@graphty/algorithms 1.7.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/algorithms.d.ts +2 -37
  2. package/dist/algorithms.js +736 -223
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/algorithms.standalone.js +24524 -0
  5. package/dist/algorithms.standalone.js.map +1 -0
  6. package/dist/src/algorithms/centrality/betweenness.d.ts +16 -11
  7. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  8. package/dist/src/algorithms/centrality/betweenness.js +17 -0
  9. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  10. package/dist/src/core/graph.d.ts +10 -0
  11. package/dist/src/core/graph.d.ts.map +1 -1
  12. package/dist/src/core/graph.js +31 -2
  13. package/dist/src/core/graph.js.map +1 -1
  14. package/dist/src/index.d.ts +10 -0
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/index.js +7 -0
  17. package/dist/src/index.js.map +1 -1
  18. package/dist/src/indexed/accelerator.d.ts +161 -0
  19. package/dist/src/indexed/accelerator.d.ts.map +1 -0
  20. package/dist/src/indexed/accelerator.js +60 -0
  21. package/dist/src/indexed/accelerator.js.map +1 -0
  22. package/dist/src/indexed/bfs.d.ts +28 -0
  23. package/dist/src/indexed/bfs.d.ts.map +1 -0
  24. package/dist/src/indexed/bfs.js +39 -0
  25. package/dist/src/indexed/bfs.js.map +1 -0
  26. package/dist/src/indexed/common-neighbors.d.ts +17 -0
  27. package/dist/src/indexed/common-neighbors.d.ts.map +1 -0
  28. package/dist/src/indexed/common-neighbors.js +41 -0
  29. package/dist/src/indexed/common-neighbors.js.map +1 -0
  30. package/dist/src/indexed/components.d.ts +28 -0
  31. package/dist/src/indexed/components.d.ts.map +1 -0
  32. package/dist/src/indexed/components.js +58 -0
  33. package/dist/src/indexed/components.js.map +1 -0
  34. package/dist/src/indexed/dijkstra.d.ts +63 -0
  35. package/dist/src/indexed/dijkstra.d.ts.map +1 -0
  36. package/dist/src/indexed/dijkstra.js +98 -0
  37. package/dist/src/indexed/dijkstra.js.map +1 -0
  38. package/dist/src/indexed/index.d.ts +22 -0
  39. package/dist/src/indexed/index.d.ts.map +1 -0
  40. package/dist/src/indexed/index.js +22 -0
  41. package/dist/src/indexed/index.js.map +1 -0
  42. package/dist/src/indexed/mst.d.ts +26 -0
  43. package/dist/src/indexed/mst.d.ts.map +1 -0
  44. package/dist/src/indexed/mst.js +48 -0
  45. package/dist/src/indexed/mst.js.map +1 -0
  46. package/dist/src/indexed/pagerank.d.ts +30 -0
  47. package/dist/src/indexed/pagerank.d.ts.map +1 -0
  48. package/dist/src/indexed/pagerank.js +50 -0
  49. package/dist/src/indexed/pagerank.js.map +1 -0
  50. package/dist/src/indexed/structures/arc-source.d.ts +13 -0
  51. package/dist/src/indexed/structures/arc-source.d.ts.map +1 -0
  52. package/dist/src/indexed/structures/arc-source.js +25 -0
  53. package/dist/src/indexed/structures/arc-source.js.map +1 -0
  54. package/dist/src/indexed/structures/index.d.ts +9 -0
  55. package/dist/src/indexed/structures/index.d.ts.map +1 -0
  56. package/dist/src/indexed/structures/index.js +9 -0
  57. package/dist/src/indexed/structures/index.js.map +1 -0
  58. package/dist/src/indexed/structures/min-heap.d.ts +44 -0
  59. package/dist/src/indexed/structures/min-heap.d.ts.map +1 -0
  60. package/dist/src/indexed/structures/min-heap.js +112 -0
  61. package/dist/src/indexed/structures/min-heap.js.map +1 -0
  62. package/dist/src/indexed/structures/union-find.d.ts +39 -0
  63. package/dist/src/indexed/structures/union-find.d.ts.map +1 -0
  64. package/dist/src/indexed/structures/union-find.js +70 -0
  65. package/dist/src/indexed/structures/union-find.js.map +1 -0
  66. package/dist/src/indexed/to-snapshot.d.ts +38 -0
  67. package/dist/src/indexed/to-snapshot.d.ts.map +1 -0
  68. package/dist/src/indexed/to-snapshot.js +58 -0
  69. package/dist/src/indexed/to-snapshot.js.map +1 -0
  70. package/dist/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +7 -3
  72. package/src/algorithms/centrality/betweenness.ts +36 -11
  73. package/src/core/graph.ts +35 -2
  74. package/src/index.ts +46 -0
  75. package/src/indexed/accelerator.ts +225 -0
  76. package/src/indexed/bfs.ts +57 -0
  77. package/src/indexed/common-neighbors.ts +46 -0
  78. package/src/indexed/components.ts +78 -0
  79. package/src/indexed/dijkstra.ts +134 -0
  80. package/src/indexed/index.ts +28 -0
  81. package/src/indexed/mst.ts +62 -0
  82. package/src/indexed/pagerank.ts +73 -0
  83. package/src/indexed/structures/arc-source.ts +25 -0
  84. package/src/indexed/structures/index.ts +9 -0
  85. package/src/indexed/structures/min-heap.ts +122 -0
  86. package/src/indexed/structures/union-find.ts +74 -0
  87. package/src/indexed/to-snapshot.ts +78 -0
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The source node of an arc, by binary search on `rowPtr`. `GraphSnapshot` exposes `arcSource(a)`
3
+ * (`graph-format/src/snapshot/graph-snapshot.ts:544`), but an `AdjacencyView` -- which is what the
4
+ * Port 1 and Port 2 signatures take, so that `reverse()` works as an input for free -- does not,
5
+ * so the predecessor walk carries its own.
6
+ * @param rowPtr - The view's nodeCount + 1 row offsets
7
+ * @param arc - An arc index in `[0, arcCount)`
8
+ * @returns The node index whose row contains the arc
9
+ * @public
10
+ */
11
+ export function arcSourceIn(rowPtr, arc) {
12
+ let lo = 0;
13
+ let hi = rowPtr.length - 1; // nodeCount
14
+ while (lo < hi) {
15
+ const mid = (lo + hi) >> 1;
16
+ if (rowPtr[mid + 1] <= arc) {
17
+ lo = mid + 1;
18
+ }
19
+ else {
20
+ hi = mid;
21
+ }
22
+ }
23
+ return lo;
24
+ }
25
+ //# sourceMappingURL=arc-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arc-source.js","sourceRoot":"","sources":["../../../../src/indexed/structures/arc-source.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,MAAW,EAAE,GAAW;IAChD,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY;IACxC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;YACzB,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACJ,EAAE,GAAG,GAAG,CAAC;QACb,CAAC;IACL,CAAC;IACD,OAAO,EAAE,CAAC;AACd,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Scratch structures for the index-based ports (graph-format design 14.2, section 14.6's
3
+ * helper-ownership sentence at `graph-format-design.md:4270`).
4
+ * @module
5
+ */
6
+ export { arcSourceIn } from "./arc-source.js";
7
+ export { IndexedMinHeap } from "./min-heap.js";
8
+ export { IntUnionFind } from "./union-find.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/indexed/structures/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Scratch structures for the index-based ports (graph-format design 14.2, section 14.6's
3
+ * helper-ownership sentence at `graph-format-design.md:4270`).
4
+ * @module
5
+ */
6
+ export { arcSourceIn } from "./arc-source.js";
7
+ export { IndexedMinHeap } from "./min-heap.js";
8
+ export { IntUnionFind } from "./union-find.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/indexed/structures/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * A binary min-heap over node indices with O(log n) decrease-key, keyed by `Float64Array` values
3
+ * (graph-format design 14.2, `graph-format-design.md:3771`). `pushOrDecrease` is the only operation
4
+ * Dijkstra's inner loop needs: it inserts an absent node and decreases a present one, so the heap
5
+ * never holds a stale duplicate and `pop()` needs no "is this entry current" check.
6
+ * @public
7
+ */
8
+ export declare class IndexedMinHeap {
9
+ private readonly heap;
10
+ private readonly slot;
11
+ private readonly key;
12
+ private size;
13
+ /**
14
+ * Create an empty heap over node indices in `[0, capacity)`.
15
+ * @param capacity - The number of distinct node indices the heap may hold
16
+ */
17
+ constructor(capacity: number);
18
+ /**
19
+ * Whether the heap holds no entries.
20
+ * @returns True when the heap holds no entries
21
+ */
22
+ isEmpty(): boolean;
23
+ /**
24
+ * Insert a node that is not in the heap.
25
+ * @param node - The node index
26
+ * @param key - Its key
27
+ */
28
+ push(node: number, key: number): void;
29
+ /**
30
+ * Insert the node, or lower its key if it is already present and the new key is smaller.
31
+ * @param node - The node index
32
+ * @param key - Its candidate key
33
+ */
34
+ pushOrDecrease(node: number, key: number): void;
35
+ /**
36
+ * Remove and return the node with the smallest key. Undefined behaviour on an empty heap;
37
+ * callers guard with `isEmpty()`.
38
+ * @returns The node index
39
+ */
40
+ pop(): number;
41
+ private siftUp;
42
+ private siftDown;
43
+ }
44
+ //# sourceMappingURL=min-heap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"min-heap.d.ts","sourceRoot":"","sources":["../../../../src/indexed/structures/min-heap.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,IAAI,CAAK;IAEjB;;;OAGG;gBACS,QAAQ,EAAE,MAAM;IAM5B;;;OAGG;IACH,OAAO,IAAI,OAAO;IAIlB;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAQrC;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAY/C;;;;OAIG;IACH,GAAG,IAAI,MAAM;IAab,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,QAAQ;CAsBnB"}
@@ -0,0 +1,112 @@
1
+ import { INVALID_INDEX } from "@graphty/graph-format";
2
+ /**
3
+ * A binary min-heap over node indices with O(log n) decrease-key, keyed by `Float64Array` values
4
+ * (graph-format design 14.2, `graph-format-design.md:3771`). `pushOrDecrease` is the only operation
5
+ * Dijkstra's inner loop needs: it inserts an absent node and decreases a present one, so the heap
6
+ * never holds a stale duplicate and `pop()` needs no "is this entry current" check.
7
+ * @public
8
+ */
9
+ export class IndexedMinHeap {
10
+ /**
11
+ * Create an empty heap over node indices in `[0, capacity)`.
12
+ * @param capacity - The number of distinct node indices the heap may hold
13
+ */
14
+ constructor(capacity) {
15
+ this.size = 0;
16
+ this.heap = new Uint32Array(capacity);
17
+ this.slot = new Uint32Array(capacity).fill(INVALID_INDEX);
18
+ this.key = new Float64Array(capacity);
19
+ }
20
+ /**
21
+ * Whether the heap holds no entries.
22
+ * @returns True when the heap holds no entries
23
+ */
24
+ isEmpty() {
25
+ return this.size === 0;
26
+ }
27
+ /**
28
+ * Insert a node that is not in the heap.
29
+ * @param node - The node index
30
+ * @param key - Its key
31
+ */
32
+ push(node, key) {
33
+ this.key[node] = key;
34
+ this.heap[this.size] = node;
35
+ this.slot[node] = this.size;
36
+ this.size++;
37
+ this.siftUp(this.size - 1);
38
+ }
39
+ /**
40
+ * Insert the node, or lower its key if it is already present and the new key is smaller.
41
+ * @param node - The node index
42
+ * @param key - Its candidate key
43
+ */
44
+ pushOrDecrease(node, key) {
45
+ const at = this.slot[node];
46
+ if (at === INVALID_INDEX) {
47
+ this.push(node, key);
48
+ return;
49
+ }
50
+ if (key < this.key[node]) {
51
+ this.key[node] = key;
52
+ this.siftUp(at);
53
+ }
54
+ }
55
+ /**
56
+ * Remove and return the node with the smallest key. Undefined behaviour on an empty heap;
57
+ * callers guard with `isEmpty()`.
58
+ * @returns The node index
59
+ */
60
+ pop() {
61
+ const top = this.heap[0];
62
+ this.slot[top] = INVALID_INDEX;
63
+ this.size--;
64
+ if (this.size > 0) {
65
+ const moved = this.heap[this.size];
66
+ this.heap[0] = moved;
67
+ this.slot[moved] = 0;
68
+ this.siftDown(0);
69
+ }
70
+ return top;
71
+ }
72
+ siftUp(from) {
73
+ let at = from;
74
+ const node = this.heap[at];
75
+ const key = this.key[node];
76
+ while (at > 0) {
77
+ const parent = (at - 1) >> 1;
78
+ const parentNode = this.heap[parent];
79
+ if (this.key[parentNode] <= key) {
80
+ break;
81
+ }
82
+ this.heap[at] = parentNode;
83
+ this.slot[parentNode] = at;
84
+ at = parent;
85
+ }
86
+ this.heap[at] = node;
87
+ this.slot[node] = at;
88
+ }
89
+ siftDown(from) {
90
+ let at = from;
91
+ const node = this.heap[at];
92
+ const key = this.key[node];
93
+ for (;;) {
94
+ const left = 2 * at + 1;
95
+ if (left >= this.size) {
96
+ break;
97
+ }
98
+ const right = left + 1;
99
+ const child = right < this.size && this.key[this.heap[right]] < this.key[this.heap[left]] ? right : left;
100
+ const childNode = this.heap[child];
101
+ if (key <= this.key[childNode]) {
102
+ break;
103
+ }
104
+ this.heap[at] = childNode;
105
+ this.slot[childNode] = at;
106
+ at = child;
107
+ }
108
+ this.heap[at] = node;
109
+ this.slot[node] = at;
110
+ }
111
+ }
112
+ //# sourceMappingURL=min-heap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"min-heap.js","sourceRoot":"","sources":["../../../../src/indexed/structures/min-heap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type U32 } from "@graphty/graph-format";
2
+ /**
3
+ * Index-keyed union-find over `[0, size)` with union by rank and path halving. The legacy
4
+ * `UnionFind` (`src/data-structures/union-find.ts`) is NodeId-keyed and stays where it is.
5
+ * @public
6
+ */
7
+ export declare class IntUnionFind {
8
+ private readonly parent;
9
+ private readonly rank;
10
+ /**
11
+ * Create a union-find whose every element is a singleton set.
12
+ * @param size - The number of elements, each initially its own singleton set
13
+ */
14
+ constructor(size: number);
15
+ /**
16
+ * Find the representative of an element's set, halving the path on the way up.
17
+ * @param x - An element index
18
+ * @returns The representative of x's set
19
+ */
20
+ find(x: number): number;
21
+ /**
22
+ * Merge the sets of two elements, attaching the shallower tree under the deeper one.
23
+ * @param a - An element index
24
+ * @param b - An element index
25
+ * @returns True when the two sets were distinct and have now been merged
26
+ */
27
+ union(a: number, b: number): boolean;
28
+ /**
29
+ * Dense labels in FIRST-SEEN order, which is what makes `groups()` identical to the legacy
30
+ * iteration order and identical to the GPU's after its own `renumberPartition` readback
31
+ * (design 9.7's connectedComponents row).
32
+ * @returns The labels and the number of distinct sets
33
+ */
34
+ toLabels(): {
35
+ readonly labels: U32;
36
+ readonly count: number;
37
+ };
38
+ }
39
+ //# sourceMappingURL=union-find.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"union-find.d.ts","sourceRoot":"","sources":["../../../../src/indexed/structures/union-find.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAEpE;;;;GAIG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAM;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;IAE3B;;;OAGG;gBACS,IAAI,EAAE,MAAM;IAQxB;;;;OAIG;IACH,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IASvB;;;;;OAKG;IACH,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;IAiBpC;;;;;OAKG;IACH,QAAQ,IAAI;QAAE,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAO/D"}
@@ -0,0 +1,70 @@
1
+ import { renumberPartition } from "@graphty/graph-format";
2
+ /**
3
+ * Index-keyed union-find over `[0, size)` with union by rank and path halving. The legacy
4
+ * `UnionFind` (`src/data-structures/union-find.ts`) is NodeId-keyed and stays where it is.
5
+ * @public
6
+ */
7
+ export class IntUnionFind {
8
+ /**
9
+ * Create a union-find whose every element is a singleton set.
10
+ * @param size - The number of elements, each initially its own singleton set
11
+ */
12
+ constructor(size) {
13
+ this.parent = new Uint32Array(size);
14
+ this.rank = new Uint32Array(size);
15
+ for (let i = 0; i < size; i++) {
16
+ this.parent[i] = i;
17
+ }
18
+ }
19
+ /**
20
+ * Find the representative of an element's set, halving the path on the way up.
21
+ * @param x - An element index
22
+ * @returns The representative of x's set
23
+ */
24
+ find(x) {
25
+ let node = x;
26
+ while (this.parent[node] !== node) {
27
+ this.parent[node] = this.parent[this.parent[node]]; // path halving
28
+ node = this.parent[node];
29
+ }
30
+ return node;
31
+ }
32
+ /**
33
+ * Merge the sets of two elements, attaching the shallower tree under the deeper one.
34
+ * @param a - An element index
35
+ * @param b - An element index
36
+ * @returns True when the two sets were distinct and have now been merged
37
+ */
38
+ union(a, b) {
39
+ const ra = this.find(a);
40
+ const rb = this.find(b);
41
+ if (ra === rb) {
42
+ return false;
43
+ }
44
+ if (this.rank[ra] < this.rank[rb]) {
45
+ this.parent[ra] = rb;
46
+ }
47
+ else if (this.rank[ra] > this.rank[rb]) {
48
+ this.parent[rb] = ra;
49
+ }
50
+ else {
51
+ this.parent[rb] = ra;
52
+ this.rank[ra]++;
53
+ }
54
+ return true;
55
+ }
56
+ /**
57
+ * Dense labels in FIRST-SEEN order, which is what makes `groups()` identical to the legacy
58
+ * iteration order and identical to the GPU's after its own `renumberPartition` readback
59
+ * (design 9.7's connectedComponents row).
60
+ * @returns The labels and the number of distinct sets
61
+ */
62
+ toLabels() {
63
+ const roots = new Uint32Array(this.parent.length);
64
+ for (let i = 0; i < roots.length; i++) {
65
+ roots[i] = this.find(i);
66
+ }
67
+ return renumberPartition(roots);
68
+ }
69
+ }
70
+ //# sourceMappingURL=union-find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"union-find.js","sourceRoot":"","sources":["../../../../src/indexed/structures/union-find.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAY,MAAM,uBAAuB,CAAC;AAEpE;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAIrB;;;OAGG;IACH,YAAY,IAAY;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,CAAS;QACV,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe;YACnE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,CAAS,EAAE,CAAS;QACtB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QACzB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QACzB,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QACJ,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;CACJ"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Conversion from the legacy `Graph` class to a frozen graph-format snapshot
3
+ * (graph-format design 14.1 rule 4, 14.6 row A1). This is the ONLY bridge between the legacy
4
+ * Map-of-Maps surface and `indexed.*`; nothing under `src/indexed/` other than this file imports
5
+ * `../core/graph.js`.
6
+ * @module
7
+ */
8
+ import { type GraphSnapshot } from "@graphty/graph-format";
9
+ import type { Graph } from "../core/graph.js";
10
+ /** Options of {@link toSnapshot}. @public */
11
+ export interface ToSnapshotOptions {
12
+ /**
13
+ * Record FNV-1a checksums at freeze so a caller can assert `snapshot.validate({ checksum: true })`
14
+ * (graph-format design 14.2's first port rule: views are shared, so a port that writes into one
15
+ * has to fail a test rather than corrupt the next call). Default false; the test suites set it.
16
+ */
17
+ readonly checksum?: boolean | undefined;
18
+ }
19
+ /**
20
+ * Freeze a legacy `Graph` into a `GraphSnapshot`, memoised on the graph's `mutationCount`.
21
+ *
22
+ * The builder is created with `weightDtype: "f64"` so a legacy graph's double weights survive
23
+ * exactly: at freeze, graph-format keeps the original values in an f64 edge column with role
24
+ * `weight` (the "shadow") whenever at least one of them is not f32-exact, and costs nothing when
25
+ * they all are (graph-format design section 3.7, `graph-format/src/builder/freeze.ts:332-360`).
26
+ * A weighted `indexed.*` port reproduces legacy f64 results by passing
27
+ * `expandEdges(s, shadow.data)` as its per-arc `weights` override.
28
+ *
29
+ * Every legacy edge carries a weight (`Graph.addEdge` defaults it to 1), so the builder's
30
+ * `weighted: "auto"` always allocates the arc weight array -- 4 bytes per arc. That is truthful
31
+ * rather than wasteful: the legacy graph really does store the value.
32
+ * @param graph - The legacy graph to convert
33
+ * @param options - Conversion options
34
+ * @returns A frozen snapshot of the graph's current topology and weights
35
+ * @public
36
+ */
37
+ export declare function toSnapshot(graph: Graph, options?: ToSnapshotOptions): GraphSnapshot;
38
+ //# sourceMappingURL=to-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-snapshot.d.ts","sourceRoot":"","sources":["../../../src/indexed/to-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3C;AAeD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,iBAAsB,GAAG,aAAa,CAwBvF"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Conversion from the legacy `Graph` class to a frozen graph-format snapshot
3
+ * (graph-format design 14.1 rule 4, 14.6 row A1). This is the ONLY bridge between the legacy
4
+ * Map-of-Maps surface and `indexed.*`; nothing under `src/indexed/` other than this file imports
5
+ * `../core/graph.js`.
6
+ * @module
7
+ */
8
+ import { GraphBuilder } from "@graphty/graph-format";
9
+ /**
10
+ * One entry per graph, REPLACED rather than appended to on a mutation. The entry holds the
11
+ * mutationCount it was built at, which is what makes a stale hit impossible -- the bug the old
12
+ * `WeakMap<Graph, CSRGraph>` cache had (graph-format design 14.1 rule 4).
13
+ */
14
+ const SNAPSHOT_CACHE = new WeakMap();
15
+ /**
16
+ * Freeze a legacy `Graph` into a `GraphSnapshot`, memoised on the graph's `mutationCount`.
17
+ *
18
+ * The builder is created with `weightDtype: "f64"` so a legacy graph's double weights survive
19
+ * exactly: at freeze, graph-format keeps the original values in an f64 edge column with role
20
+ * `weight` (the "shadow") whenever at least one of them is not f32-exact, and costs nothing when
21
+ * they all are (graph-format design section 3.7, `graph-format/src/builder/freeze.ts:332-360`).
22
+ * A weighted `indexed.*` port reproduces legacy f64 results by passing
23
+ * `expandEdges(s, shadow.data)` as its per-arc `weights` override.
24
+ *
25
+ * Every legacy edge carries a weight (`Graph.addEdge` defaults it to 1), so the builder's
26
+ * `weighted: "auto"` always allocates the arc weight array -- 4 bytes per arc. That is truthful
27
+ * rather than wasteful: the legacy graph really does store the value.
28
+ * @param graph - The legacy graph to convert
29
+ * @param options - Conversion options
30
+ * @returns A frozen snapshot of the graph's current topology and weights
31
+ * @public
32
+ */
33
+ export function toSnapshot(graph, options = {}) {
34
+ const checksum = options.checksum === true;
35
+ const cached = SNAPSHOT_CACHE.get(graph);
36
+ // A checksummed snapshot answers a plain request; a plain one cannot answer a checksummed
37
+ // request -- validate({ checksum: true }) throws E_INVALID_SNAPSHOT ("no-checksum") when none
38
+ // were recorded (graph-format/src/types/snapshot.ts:401-405).
39
+ if (cached !== undefined && cached.mutationCount === graph.mutationCount && (cached.checksum || !checksum)) {
40
+ return cached.snapshot;
41
+ }
42
+ const builder = new GraphBuilder({
43
+ directed: graph.isDirected,
44
+ weightDtype: "f64",
45
+ expectedNodes: graph.nodeCount,
46
+ expectedEdges: graph.totalEdgeCount,
47
+ });
48
+ for (const node of graph.nodes()) {
49
+ builder.addNode(node.id);
50
+ }
51
+ for (const edge of graph.edges()) {
52
+ builder.addEdge(edge.source, edge.target, edge.weight);
53
+ }
54
+ const snapshot = builder.freeze({ label: "algorithms.toSnapshot", checksum });
55
+ SNAPSHOT_CACHE.set(graph, { mutationCount: graph.mutationCount, checksum, snapshot });
56
+ return snapshot;
57
+ }
58
+ //# sourceMappingURL=to-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-snapshot.js","sourceRoot":"","sources":["../../../src/indexed/to-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAsB,MAAM,uBAAuB,CAAC;AAoBzE;;;;GAIG;AACH,MAAM,cAAc,GAAG,IAAI,OAAO,EAAqB,CAAC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAY,EAAE,UAA6B,EAAE;IACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC;IAC3C,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzC,0FAA0F;IAC1F,8FAA8F;IAC9F,8DAA8D;IAC9D,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzG,OAAO,MAAM,CAAC,QAAQ,CAAC;IAC3B,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAC7B,QAAQ,EAAE,KAAK,CAAC,UAAU;QAC1B,WAAW,EAAE,KAAK;QAClB,aAAa,EAAE,KAAK,CAAC,SAAS;QAC9B,aAAa,EAAE,KAAK,CAAC,cAAc;KACtC,CAAC,CAAC;IACH,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9E,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtF,OAAO,QAAQ,CAAC;AACpB,CAAC"}