@graphty/graph-format 0.0.0 → 0.2.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.
- package/LICENSE +21 -0
- package/README.md +216 -43
- package/dist/graph-format.d.ts +1 -0
- package/dist/graph-format.d.ts.map +1 -0
- package/dist/graph-format.js +15798 -0
- package/dist/graph-format.js.map +1 -0
- package/dist/src/builder/arena.d.ts +85 -0
- package/dist/src/builder/arena.d.ts.map +1 -0
- package/dist/src/builder/arena.js +154 -0
- package/dist/src/builder/arena.js.map +1 -0
- package/dist/src/builder/compact.d.ts +515 -0
- package/dist/src/builder/compact.d.ts.map +1 -0
- package/dist/src/builder/compact.js +1553 -0
- package/dist/src/builder/compact.js.map +1 -0
- package/dist/src/builder/counting-sort.d.ts +96 -0
- package/dist/src/builder/counting-sort.d.ts.map +1 -0
- package/dist/src/builder/counting-sort.js +430 -0
- package/dist/src/builder/counting-sort.js.map +1 -0
- package/dist/src/builder/freeze.d.ts +72 -0
- package/dist/src/builder/freeze.d.ts.map +1 -0
- package/dist/src/builder/freeze.js +548 -0
- package/dist/src/builder/freeze.js.map +1 -0
- package/dist/src/builder/graph-builder.d.ts +602 -0
- package/dist/src/builder/graph-builder.d.ts.map +1 -0
- package/dist/src/builder/graph-builder.js +1940 -0
- package/dist/src/builder/graph-builder.js.map +1 -0
- package/dist/src/builder/options.d.ts +16 -0
- package/dist/src/builder/options.d.ts.map +1 -0
- package/dist/src/builder/options.js +21 -0
- package/dist/src/builder/options.js.map +1 -0
- package/dist/src/columns/bitmap.d.ts +96 -0
- package/dist/src/columns/bitmap.d.ts.map +1 -0
- package/dist/src/columns/bitmap.js +184 -0
- package/dist/src/columns/bitmap.js.map +1 -0
- package/dist/src/columns/column.d.ts +220 -0
- package/dist/src/columns/column.d.ts.map +1 -0
- package/dist/src/columns/column.js +2109 -0
- package/dist/src/columns/column.js.map +1 -0
- package/dist/src/columns/dictionary.d.ts +60 -0
- package/dist/src/columns/dictionary.d.ts.map +1 -0
- package/dist/src/columns/dictionary.js +102 -0
- package/dist/src/columns/dictionary.js.map +1 -0
- package/dist/src/columns/growable.d.ts +198 -0
- package/dist/src/columns/growable.d.ts.map +1 -0
- package/dist/src/columns/growable.js +296 -0
- package/dist/src/columns/growable.js.map +1 -0
- package/dist/src/columns/infer.d.ts +121 -0
- package/dist/src/columns/infer.d.ts.map +1 -0
- package/dist/src/columns/infer.js +268 -0
- package/dist/src/columns/infer.js.map +1 -0
- package/dist/src/columns/remap.d.ts +143 -0
- package/dist/src/columns/remap.d.ts.map +1 -0
- package/dist/src/columns/remap.js +588 -0
- package/dist/src/columns/remap.js.map +1 -0
- package/dist/src/columns/table.d.ts +184 -0
- package/dist/src/columns/table.d.ts.map +1 -0
- package/dist/src/columns/table.js +485 -0
- package/dist/src/columns/table.js.map +1 -0
- package/dist/src/constants.d.ts +34 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +79 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/errors.d.ts +76 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +32 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/ids/edge-id-index.d.ts +77 -0
- package/dist/src/ids/edge-id-index.d.ts.map +1 -0
- package/dist/src/ids/edge-id-index.js +155 -0
- package/dist/src/ids/edge-id-index.js.map +1 -0
- package/dist/src/ids/node-id-map.d.ts +280 -0
- package/dist/src/ids/node-id-map.d.ts.map +1 -0
- package/dist/src/ids/node-id-map.js +1139 -0
- package/dist/src/ids/node-id-map.js.map +1 -0
- package/dist/src/ids/string-store.d.ts +219 -0
- package/dist/src/ids/string-store.d.ts.map +1 -0
- package/dist/src/ids/string-store.js +526 -0
- package/dist/src/ids/string-store.js.map +1 -0
- package/dist/src/index.d.ts +30 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +29 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/populate/from-csr.d.ts +61 -0
- package/dist/src/populate/from-csr.d.ts.map +1 -0
- package/dist/src/populate/from-csr.js +706 -0
- package/dist/src/populate/from-csr.js.map +1 -0
- package/dist/src/populate/from-edge-arrays.d.ts +51 -0
- package/dist/src/populate/from-edge-arrays.d.ts.map +1 -0
- package/dist/src/populate/from-edge-arrays.js +217 -0
- package/dist/src/populate/from-edge-arrays.js.map +1 -0
- package/dist/src/populate/from-records.d.ts +51 -0
- package/dist/src/populate/from-records.d.ts.map +1 -0
- package/dist/src/populate/from-records.js +447 -0
- package/dist/src/populate/from-records.js.map +1 -0
- package/dist/src/snapshot/derived.d.ts +211 -0
- package/dist/src/snapshot/derived.d.ts.map +1 -0
- package/dist/src/snapshot/derived.js +1254 -0
- package/dist/src/snapshot/derived.js.map +1 -0
- package/dist/src/snapshot/graph-meta.d.ts +23 -0
- package/dist/src/snapshot/graph-meta.d.ts.map +1 -0
- package/dist/src/snapshot/graph-meta.js +159 -0
- package/dist/src/snapshot/graph-meta.js.map +1 -0
- package/dist/src/snapshot/graph-snapshot.d.ts +509 -0
- package/dist/src/snapshot/graph-snapshot.d.ts.map +1 -0
- package/dist/src/snapshot/graph-snapshot.js +1247 -0
- package/dist/src/snapshot/graph-snapshot.js.map +1 -0
- package/dist/src/snapshot/hash.d.ts +90 -0
- package/dist/src/snapshot/hash.d.ts.map +1 -0
- package/dist/src/snapshot/hash.js +228 -0
- package/dist/src/snapshot/hash.js.map +1 -0
- package/dist/src/snapshot/queries.d.ts +74 -0
- package/dist/src/snapshot/queries.d.ts.map +1 -0
- package/dist/src/snapshot/queries.js +131 -0
- package/dist/src/snapshot/queries.js.map +1 -0
- package/dist/src/snapshot/validate.d.ts +192 -0
- package/dist/src/snapshot/validate.d.ts.map +1 -0
- package/dist/src/snapshot/validate.js +990 -0
- package/dist/src/snapshot/validate.js.map +1 -0
- package/dist/src/snapshot/views.d.ts +274 -0
- package/dist/src/snapshot/views.d.ts.map +1 -0
- package/dist/src/snapshot/views.js +856 -0
- package/dist/src/snapshot/views.js.map +1 -0
- package/dist/src/types/builder.d.ts +456 -0
- package/dist/src/types/builder.d.ts.map +1 -0
- package/dist/src/types/builder.js +11 -0
- package/dist/src/types/builder.js.map +1 -0
- package/dist/src/types/columns.d.ts +615 -0
- package/dist/src/types/columns.d.ts.map +1 -0
- package/dist/src/types/columns.js +14 -0
- package/dist/src/types/columns.js.map +1 -0
- package/dist/src/types/index.d.ts +14 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +11 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/internal.d.ts +172 -0
- package/dist/src/types/internal.d.ts.map +1 -0
- package/dist/src/types/internal.js +13 -0
- package/dist/src/types/internal.js.map +1 -0
- package/dist/src/types/snapshot.d.ts +801 -0
- package/dist/src/types/snapshot.d.ts.map +1 -0
- package/dist/src/types/snapshot.js +14 -0
- package/dist/src/types/snapshot.js.map +1 -0
- package/dist/src/types/wire.d.ts +196 -0
- package/dist/src/types/wire.d.ts.map +1 -0
- package/dist/src/types/wire.js +8 -0
- package/dist/src/types/wire.js.map +1 -0
- package/dist/src/util/mask.d.ts +55 -0
- package/dist/src/util/mask.d.ts.map +1 -0
- package/dist/src/util/mask.js +71 -0
- package/dist/src/util/mask.js.map +1 -0
- package/dist/src/util/options.d.ts +22 -0
- package/dist/src/util/options.d.ts.map +1 -0
- package/dist/src/util/options.js +49 -0
- package/dist/src/util/options.js.map +1 -0
- package/dist/src/util/shared-buffers.d.ts +42 -0
- package/dist/src/util/shared-buffers.d.ts.map +1 -0
- package/dist/src/util/shared-buffers.js +52 -0
- package/dist/src/util/shared-buffers.js.map +1 -0
- package/dist/src/util/typed-array.d.ts +205 -0
- package/dist/src/util/typed-array.d.ts.map +1 -0
- package/dist/src/util/typed-array.js +289 -0
- package/dist/src/util/typed-array.js.map +1 -0
- package/dist/src/wire/bytes.d.ts +69 -0
- package/dist/src/wire/bytes.d.ts.map +1 -0
- package/dist/src/wire/bytes.js +361 -0
- package/dist/src/wire/bytes.js.map +1 -0
- package/dist/src/wire/carried-views.d.ts +111 -0
- package/dist/src/wire/carried-views.d.ts.map +1 -0
- package/dist/src/wire/carried-views.js +286 -0
- package/dist/src/wire/carried-views.js.map +1 -0
- package/dist/src/wire/from-wire.d.ts +144 -0
- package/dist/src/wire/from-wire.d.ts.map +1 -0
- package/dist/src/wire/from-wire.js +1425 -0
- package/dist/src/wire/from-wire.js.map +1 -0
- package/dist/src/wire/to-wire.d.ts +171 -0
- package/dist/src/wire/to-wire.d.ts.map +1 -0
- package/dist/src/wire/to-wire.js +652 -0
- package/dist/src/wire/to-wire.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +72 -7
- package/src/builder/arena.ts +192 -0
- package/src/builder/compact.ts +1811 -0
- package/src/builder/counting-sort.ts +506 -0
- package/src/builder/freeze.ts +689 -0
- package/src/builder/graph-builder.ts +2264 -0
- package/src/builder/options.ts +29 -0
- package/src/columns/bitmap.ts +196 -0
- package/src/columns/column.ts +2574 -0
- package/src/columns/dictionary.ts +114 -0
- package/src/columns/growable.ts +350 -0
- package/src/columns/infer.ts +285 -0
- package/src/columns/remap.ts +663 -0
- package/src/columns/table.ts +568 -0
- package/src/constants.ts +89 -0
- package/src/errors.ts +115 -0
- package/src/ids/edge-id-index.ts +179 -0
- package/src/ids/node-id-map.ts +1340 -0
- package/src/ids/string-store.ts +589 -0
- package/src/index.ts +139 -0
- package/src/lib-resizable-array-buffer.d.ts +34 -0
- package/src/populate/from-csr.ts +802 -0
- package/src/populate/from-edge-arrays.ts +257 -0
- package/src/populate/from-records.ts +536 -0
- package/src/snapshot/derived.ts +1486 -0
- package/src/snapshot/graph-meta.ts +167 -0
- package/src/snapshot/graph-snapshot.ts +1503 -0
- package/src/snapshot/hash.ts +241 -0
- package/src/snapshot/queries.ts +136 -0
- package/src/snapshot/validate.ts +1108 -0
- package/src/snapshot/views.ts +943 -0
- package/src/types/builder.ts +480 -0
- package/src/types/columns.ts +727 -0
- package/src/types/index.ts +14 -0
- package/src/types/internal.ts +195 -0
- package/src/types/snapshot.ts +886 -0
- package/src/types/wire.ts +207 -0
- package/src/util/mask.ts +89 -0
- package/src/util/options.ts +57 -0
- package/src/util/shared-buffers.ts +56 -0
- package/src/util/typed-array.ts +371 -0
- package/src/wire/bytes.ts +440 -0
- package/src/wire/carried-views.ts +327 -0
- package/src/wire/from-wire.ts +1690 -0
- package/src/wire/to-wire.ts +755 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fromEdgeArrays()` (design section 8.1, entry point 1): COO typed arrays with dense node indices,
|
|
3
|
+
* the 20 ms path. The input goes through the builder's index-space fast path -- `addAnonymousNodes`
|
|
4
|
+
* (no id Map unless `ids` is given) plus one `addEdges` call -- and then the freeze pipeline of design
|
|
5
|
+
* section 6.3, so every builder policy (duplicate edges, self-loops, weight precision) and every
|
|
6
|
+
* freeze option (label, prepare, arena, checksum) applies exactly as it does to a hand-built
|
|
7
|
+
* builder. Attribute columns are staged in the builder too, so a merging duplicate policy or a
|
|
8
|
+
* dropped self-loop gathers them through the same remaps as any other column (design section 5.11).
|
|
9
|
+
*
|
|
10
|
+
* The options object is the intersection of BuilderOptionsPatch and FreezeOptions; `splitOptions`
|
|
11
|
+
* routes each field to the builder or to the freeze and is shared with `fromRecords`.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { GraphBuilder } from "../builder/graph-builder.js";
|
|
15
|
+
import { columnFromValues, metaToDecl } from "../columns/column.js";
|
|
16
|
+
import { GraphFormatError } from "../errors.js";
|
|
17
|
+
import { type GraphSnapshot } from "../snapshot/graph-snapshot.js";
|
|
18
|
+
import {
|
|
19
|
+
type BuilderOptionsPatch,
|
|
20
|
+
type ColumnDecl,
|
|
21
|
+
type ColumnInput,
|
|
22
|
+
type EdgeArraysInput,
|
|
23
|
+
type FreezeOptions,
|
|
24
|
+
type GraphBuilderOptions,
|
|
25
|
+
type NodeId,
|
|
26
|
+
type TypedArrayData,
|
|
27
|
+
} from "../types/index.js";
|
|
28
|
+
|
|
29
|
+
// ============================================================ options
|
|
30
|
+
|
|
31
|
+
/** The builder half and the freeze half of a `BuilderOptionsPatch & FreezeOptions` object. */
|
|
32
|
+
interface SplitOptions {
|
|
33
|
+
/** The builder options; `directed` is the caller's input value. */
|
|
34
|
+
readonly builder: GraphBuilderOptions;
|
|
35
|
+
/** The freeze options. */
|
|
36
|
+
readonly freeze: FreezeOptions;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Route the fields of a factory options object to the builder constructor and to `freeze()`.
|
|
41
|
+
* `duplicateEdges` (a field of both) becomes the builder's default policy, which the freeze then
|
|
42
|
+
* applies; an `options.directed` must agree with the input's own `directed` (E_DIRECTED otherwise; the input is
|
|
43
|
+
* authoritative). Undefined fields are left to the builder's and the freeze's own defaults.
|
|
44
|
+
* @param directed - the input's direction
|
|
45
|
+
* @param options - the combined options
|
|
46
|
+
* @returns the two halves
|
|
47
|
+
*/
|
|
48
|
+
export function splitOptions(directed: boolean, options: BuilderOptionsPatch & FreezeOptions): SplitOptions {
|
|
49
|
+
if (options.directed !== undefined && options.directed !== directed) {
|
|
50
|
+
throw new GraphFormatError(
|
|
51
|
+
"E_DIRECTED",
|
|
52
|
+
`options.directed (${String(options.directed)}) disagrees with the input's directed (${String(directed)})`,
|
|
53
|
+
{ reason: "direction mismatch", directed, found: options.directed },
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
builder: {
|
|
58
|
+
directed,
|
|
59
|
+
weighted: options.weighted,
|
|
60
|
+
weightDtype: options.weightDtype,
|
|
61
|
+
duplicateEdges: options.duplicateEdges,
|
|
62
|
+
selfLoops: options.selfLoops,
|
|
63
|
+
addMissingNodes: options.addMissingNodes,
|
|
64
|
+
expectedNodes: options.expectedNodes,
|
|
65
|
+
expectedEdges: options.expectedEdges,
|
|
66
|
+
},
|
|
67
|
+
freeze: {
|
|
68
|
+
label: options.label,
|
|
69
|
+
prepare: options.prepare,
|
|
70
|
+
arena: options.arena,
|
|
71
|
+
release: options.release,
|
|
72
|
+
profile: options.profile,
|
|
73
|
+
checksum: options.checksum,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ============================================================ columns
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Whether a column value is a typed array (as opposed to a ColumnInput).
|
|
82
|
+
* @param value - the column value
|
|
83
|
+
* @returns true for a typed array
|
|
84
|
+
*/
|
|
85
|
+
function isTypedArrayData(value: TypedArrayData | ColumnInput): value is TypedArrayData {
|
|
86
|
+
return ArrayBuffer.isView(value);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Stage one caller-supplied column in the builder (design section 8.1). A typed array (bare or
|
|
91
|
+
* inside a ColumnInput) is bulk-set with its declaration; a JS array of values is resolved with the
|
|
92
|
+
* same inference `AttributeTable.set()` applies (design section 5.1 widening, list detection) and
|
|
93
|
+
* written row by row into a declared column, so a string / list / json column reaches the snapshot
|
|
94
|
+
* through the same freeze step as every other column.
|
|
95
|
+
* @param builder - the builder
|
|
96
|
+
* @param domain - "node" or "edge"
|
|
97
|
+
* @param rows - the table's row count (nodeCount or edge count); a JS array must have this many entries
|
|
98
|
+
* @param name - the column name (the record key; a `decl.name` is ignored)
|
|
99
|
+
* @param value - the typed array or ColumnInput
|
|
100
|
+
*/
|
|
101
|
+
function stageColumn(
|
|
102
|
+
builder: GraphBuilder,
|
|
103
|
+
domain: "node" | "edge",
|
|
104
|
+
rows: number,
|
|
105
|
+
name: string,
|
|
106
|
+
value: TypedArrayData | ColumnInput,
|
|
107
|
+
): void {
|
|
108
|
+
const data = isTypedArrayData(value) ? value : value.data;
|
|
109
|
+
const decl = isTypedArrayData(value) ? {} : value.decl;
|
|
110
|
+
if (ArrayBuffer.isView(data)) {
|
|
111
|
+
if (domain === "node") {
|
|
112
|
+
builder.setNodeColumn(name, data, decl);
|
|
113
|
+
} else {
|
|
114
|
+
builder.setEdgeColumn(name, data, decl);
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const column = columnFromValues(domain, rows, name, data, decl);
|
|
119
|
+
const declaration: ColumnDecl = { ...metaToDecl(column.meta), name, dtype: column.dtype };
|
|
120
|
+
const handle = domain === "node" ? builder.declareNodeColumn(declaration) : builder.declareEdgeColumn(declaration);
|
|
121
|
+
for (let row = 0; row < rows; row++) {
|
|
122
|
+
if (!column.isSet(row)) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const cell = column.value(row);
|
|
126
|
+
if (domain === "node") {
|
|
127
|
+
builder.setNodeValue(handle, row, cell);
|
|
128
|
+
} else {
|
|
129
|
+
builder.setEdgeValue(handle, row, cell);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ============================================================ the entry point
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The E_COLUMN_LENGTH error for two input arrays whose lengths disagree.
|
|
138
|
+
* @param field - the array that is wrong
|
|
139
|
+
* @param expected - the length it should have
|
|
140
|
+
* @param found - the length it has
|
|
141
|
+
* @returns the error
|
|
142
|
+
*/
|
|
143
|
+
function lengthError(field: string, expected: number, found: number): GraphFormatError {
|
|
144
|
+
return new GraphFormatError("E_COLUMN_LENGTH", `${field} has ${found} entries, expected ${expected}`, {
|
|
145
|
+
field,
|
|
146
|
+
expected,
|
|
147
|
+
found,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Resolve the node count of an EdgeArraysInput: `ids.length` when ids are given (and `nodeCount`,
|
|
153
|
+
* when also given, must agree), else `nodeCount`, which is then required.
|
|
154
|
+
* @param input - the input
|
|
155
|
+
* @returns the node count
|
|
156
|
+
*/
|
|
157
|
+
function resolveNodeCount(input: EdgeArraysInput): number {
|
|
158
|
+
const { nodeCount, ids } = input;
|
|
159
|
+
if (nodeCount !== undefined && (!Number.isInteger(nodeCount) || nodeCount < 0)) {
|
|
160
|
+
throw new GraphFormatError("E_INDEX_RANGE", `nodeCount ${nodeCount} is not a non-negative integer`, {
|
|
161
|
+
field: "nodeCount",
|
|
162
|
+
found: nodeCount,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (ids !== undefined) {
|
|
166
|
+
if (nodeCount !== undefined && nodeCount !== ids.length) {
|
|
167
|
+
throw lengthError("ids", nodeCount, ids.length);
|
|
168
|
+
}
|
|
169
|
+
return ids.length;
|
|
170
|
+
}
|
|
171
|
+
if (nodeCount === undefined) {
|
|
172
|
+
throw new GraphFormatError("E_INDEX_RANGE", "nodeCount is required when no ids are given", {
|
|
173
|
+
field: "nodeCount",
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return nodeCount;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Add the caller's ids to the builder in index order; every id must be distinct so that index i holds
|
|
181
|
+
* ids[i] (E_DUPLICATE_ID otherwise, naming the id and both positions).
|
|
182
|
+
* @param builder - the builder
|
|
183
|
+
* @param ids - the ids in index order
|
|
184
|
+
*/
|
|
185
|
+
function addIds(builder: GraphBuilder, ids: readonly NodeId[] | Float64Array): void {
|
|
186
|
+
const indices = builder.addNodes(ids);
|
|
187
|
+
for (let i = 0; i < indices.length; i++) {
|
|
188
|
+
if (indices[i] !== i) {
|
|
189
|
+
const id = ids[i];
|
|
190
|
+
throw new GraphFormatError("E_DUPLICATE_ID", `ids[${i}] repeats the id of index ${indices[i]}`, {
|
|
191
|
+
id,
|
|
192
|
+
index: indices[i],
|
|
193
|
+
position: i,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Build a snapshot from COO typed arrays with dense node indices (design section 8.1): the builder's
|
|
201
|
+
* index-space fast path (`addAnonymousNodes` + `addEdges`, no id Map unless `ids` is given) followed
|
|
202
|
+
* by the freeze pipeline, so the result is exactly what a builder fed the same nodes, edges, columns
|
|
203
|
+
* and meta would freeze to. Without `ids` the id map is `identity` with offset 0 and no storage;
|
|
204
|
+
* with `ids` the kind is detected at freeze (design section 4.2). Float64 weights select the f64
|
|
205
|
+
* staging precision unless `options.weightDtype` says otherwise, so the values are downcast to f32 in
|
|
206
|
+
* the arc array and an f64 shadow column is kept only when some value is not f32-exact (design
|
|
207
|
+
* section 3.7).
|
|
208
|
+
* @param input - the arrays; `nodeCount` is required unless `ids` is given (E_INDEX_RANGE); `src`,
|
|
209
|
+
* `dst` and `weights` must have one entry per edge (E_COLUMN_LENGTH); every index must be below the
|
|
210
|
+
* node count (E_UNKNOWN_NODE); no weight may be NaN (E_INVALID_WEIGHT); ids must be distinct legal
|
|
211
|
+
* ids (E_DUPLICATE_ID / E_INVALID_ID); columns must have the table's row count (E_COLUMN_LENGTH)
|
|
212
|
+
* @param options - builder policies and freeze options; `duplicateEdges` and `selfLoops` apply at the
|
|
213
|
+
* freeze (E_DUPLICATE_EDGE / E_SELF_LOOP under the "error" policies)
|
|
214
|
+
* @returns the frozen snapshot
|
|
215
|
+
*/
|
|
216
|
+
export function fromEdgeArrays(
|
|
217
|
+
input: EdgeArraysInput,
|
|
218
|
+
options: BuilderOptionsPatch & FreezeOptions = {},
|
|
219
|
+
): GraphSnapshot {
|
|
220
|
+
const { src, dst, weights } = input;
|
|
221
|
+
if (dst.length !== src.length) {
|
|
222
|
+
throw lengthError("dst", src.length, dst.length);
|
|
223
|
+
}
|
|
224
|
+
if (weights !== undefined && weights.length !== src.length) {
|
|
225
|
+
throw lengthError("weights", src.length, weights.length);
|
|
226
|
+
}
|
|
227
|
+
const nodeCount = resolveNodeCount(input);
|
|
228
|
+
const edgeCount = src.length;
|
|
229
|
+
const split = splitOptions(input.directed, options);
|
|
230
|
+
const builderOptions: GraphBuilderOptions = {
|
|
231
|
+
...split.builder,
|
|
232
|
+
weightDtype: options.weightDtype ?? (weights instanceof Float64Array ? "f64" : undefined),
|
|
233
|
+
expectedNodes: options.expectedNodes ?? nodeCount,
|
|
234
|
+
expectedEdges: options.expectedEdges ?? edgeCount,
|
|
235
|
+
};
|
|
236
|
+
const builder = new GraphBuilder(builderOptions);
|
|
237
|
+
if (input.ids === undefined) {
|
|
238
|
+
builder.addAnonymousNodes(nodeCount);
|
|
239
|
+
} else {
|
|
240
|
+
addIds(builder, input.ids);
|
|
241
|
+
}
|
|
242
|
+
builder.addEdges(src, dst, weights);
|
|
243
|
+
if (input.nodeColumns !== undefined) {
|
|
244
|
+
for (const name of Object.keys(input.nodeColumns)) {
|
|
245
|
+
stageColumn(builder, "node", nodeCount, name, input.nodeColumns[name]);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (input.edgeColumns !== undefined) {
|
|
249
|
+
for (const name of Object.keys(input.edgeColumns)) {
|
|
250
|
+
stageColumn(builder, "edge", edgeCount, name, input.edgeColumns[name]);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (input.meta !== undefined) {
|
|
254
|
+
builder.setMeta(input.meta);
|
|
255
|
+
}
|
|
256
|
+
return builder.freeze(split.freeze);
|
|
257
|
+
}
|