@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,447 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fromRecords()` (design section 8.1, entry point 3): plain node-link records, the shape every JSON
|
|
3
|
+
* dialect parses into and what graphty-element's data sources emit. Every record is pushed into a
|
|
4
|
+
* GraphBuilder scalar by scalar -- the id, the endpoints and the weight through `addNode` / `addEdge`,
|
|
5
|
+
* every other key through `setNodeValue` / `setEdgeValue` -- so attribute columns are inferred and
|
|
6
|
+
* widened per column by the builder exactly as `addNodeRecord` / `addEdgeRecord` would (design
|
|
7
|
+
* section 5.1), and the FreezeReport carries the widenings. The reserved keys (the node id, the edge
|
|
8
|
+
* source / target and the weight) never become attribute columns: the id map and the arc array
|
|
9
|
+
* already hold them.
|
|
10
|
+
*
|
|
11
|
+
* Id coercion (design section 4.1) is applied here, before an id reaches the builder: "keep" (the
|
|
12
|
+
* default; JSON values are already typed), "canonical" (canonical integer text becomes a number,
|
|
13
|
+
* everything else stays a string), "string" and "number".
|
|
14
|
+
*/
|
|
15
|
+
import { GraphBuilder } from "../builder/graph-builder.js";
|
|
16
|
+
import { GraphFormatError } from "../errors.js";
|
|
17
|
+
import { assertOneOf } from "../util/options.js";
|
|
18
|
+
import { splitOptions } from "./from-edge-arrays.js";
|
|
19
|
+
/** The default source keys, tried in order when `edgeSource` is not given. */
|
|
20
|
+
const SOURCE_KEYS = ["source", "src", "from"];
|
|
21
|
+
/** The default target keys, tried in order when `edgeTarget` is not given. */
|
|
22
|
+
const TARGET_KEYS = ["target", "dst", "to"];
|
|
23
|
+
/** The canonical integer text of design section 4.1. */
|
|
24
|
+
const CANONICAL_INTEGER = /^-?(0|[1-9][0-9]*)$/;
|
|
25
|
+
// ============================================================ ids
|
|
26
|
+
/**
|
|
27
|
+
* Whether a record has an own property (records may come from `JSON.parse`, so prototype lookups are
|
|
28
|
+
* never consulted).
|
|
29
|
+
* @param record - the record
|
|
30
|
+
* @param key - the key
|
|
31
|
+
* @returns true when the key is an own property
|
|
32
|
+
*/
|
|
33
|
+
function hasKey(record, key) {
|
|
34
|
+
return Object.prototype.hasOwnProperty.call(record, key);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The E_INVALID_ID error for an id cell the coercion rule cannot turn into a NodeId.
|
|
38
|
+
* @param field - which cell (id / source / target)
|
|
39
|
+
* @param value - the value
|
|
40
|
+
* @param rule - the coercion rule in force
|
|
41
|
+
* @returns the error
|
|
42
|
+
*/
|
|
43
|
+
function invalidId(field, value, rule) {
|
|
44
|
+
return new GraphFormatError("E_INVALID_ID", `${field} value of type ${typeof value} is not a legal id under "${rule}"`, {
|
|
45
|
+
field,
|
|
46
|
+
found: typeof value,
|
|
47
|
+
rule,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Apply an id coercion rule to one id cell (design section 4.1). The result still goes through the
|
|
52
|
+
* builder's own id validation (E_INVALID_ID for anything that is not a finite number or a well-formed
|
|
53
|
+
* string), so this function only converts; it rejects the shapes a rule cannot convert.
|
|
54
|
+
* @param value - the cell value
|
|
55
|
+
* @param rule - the coercion rule
|
|
56
|
+
* @param field - which cell, for the error message
|
|
57
|
+
* @returns the id to hand to the builder
|
|
58
|
+
*/
|
|
59
|
+
export function coerceId(value, rule, field) {
|
|
60
|
+
switch (rule) {
|
|
61
|
+
case "keep":
|
|
62
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
throw invalidId(field, value, rule);
|
|
66
|
+
case "canonical":
|
|
67
|
+
if (typeof value === "number") {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
if (typeof value === "string") {
|
|
71
|
+
// "-0" is excluded so the rule stays injective on text (-0 and 0 are one id)
|
|
72
|
+
if (CANONICAL_INTEGER.test(value) && value !== "-0") {
|
|
73
|
+
const n = Number(value);
|
|
74
|
+
return Number.isSafeInteger(n) ? n : value;
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
throw invalidId(field, value, rule);
|
|
79
|
+
case "string":
|
|
80
|
+
if (typeof value === "string") {
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
if (typeof value === "number" ||
|
|
84
|
+
typeof value === "boolean" ||
|
|
85
|
+
typeof value === "bigint" ||
|
|
86
|
+
value === null) {
|
|
87
|
+
return String(value);
|
|
88
|
+
}
|
|
89
|
+
throw invalidId(field, value, rule);
|
|
90
|
+
case "number":
|
|
91
|
+
if (typeof value === "number") {
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
if (typeof value === "string") {
|
|
95
|
+
return Number(value);
|
|
96
|
+
}
|
|
97
|
+
throw invalidId(field, value, rule);
|
|
98
|
+
default: {
|
|
99
|
+
const name = rule;
|
|
100
|
+
throw new GraphFormatError("E_UNSUPPORTED", `unknown id coercion "${name}"`, {
|
|
101
|
+
field: "ids",
|
|
102
|
+
found: name,
|
|
103
|
+
reason: "unsupported option",
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Read an endpoint cell: the explicit key when one was given, else the first of the default keys the
|
|
110
|
+
* record has.
|
|
111
|
+
* @param record - the edge record
|
|
112
|
+
* @param explicit - the caller's key, or undefined
|
|
113
|
+
* @param defaults - the default keys in order
|
|
114
|
+
* @returns the key that was used and its value; the key is null when none is present
|
|
115
|
+
*/
|
|
116
|
+
function endpointOf(record, explicit, defaults) {
|
|
117
|
+
if (explicit !== undefined) {
|
|
118
|
+
return { key: hasKey(record, explicit) ? explicit : null, value: record[explicit] };
|
|
119
|
+
}
|
|
120
|
+
for (const key of defaults) {
|
|
121
|
+
if (hasKey(record, key)) {
|
|
122
|
+
return { key, value: record[key] };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { key: null, value: undefined };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The E_INVALID_ID error for an edge record without an endpoint.
|
|
129
|
+
* @param field - "source" or "target"
|
|
130
|
+
* @param keys - the keys that were tried
|
|
131
|
+
* @param edge - the record's position in the edge iteration
|
|
132
|
+
* @returns the error
|
|
133
|
+
*/
|
|
134
|
+
function missingEndpoint(field, keys, edge) {
|
|
135
|
+
return new GraphFormatError("E_INVALID_ID", `edge record ${edge} has no ${field} (keys tried: ${keys.join(", ")})`, {
|
|
136
|
+
field,
|
|
137
|
+
keys: [...keys],
|
|
138
|
+
edge,
|
|
139
|
+
reason: "missing endpoint",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// ============================================================ attribute policy
|
|
143
|
+
/**
|
|
144
|
+
* How non-reserved record keys become columns: the builder's inference, one json column per key, no
|
|
145
|
+
* columns at all, or only the declared columns.
|
|
146
|
+
*/
|
|
147
|
+
class AttributePolicy {
|
|
148
|
+
/**
|
|
149
|
+
* Resolve the `columns` option.
|
|
150
|
+
* @param columns - the option value; default "infer"
|
|
151
|
+
*/
|
|
152
|
+
constructor(columns) {
|
|
153
|
+
this.handles = { node: new Map(), edge: new Map() };
|
|
154
|
+
if (columns === undefined || columns === "infer") {
|
|
155
|
+
this.mode = "infer";
|
|
156
|
+
this.declared = new Map();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (columns === "json" || columns === "none") {
|
|
160
|
+
this.mode = columns;
|
|
161
|
+
this.declared = new Map();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (typeof columns === "string") {
|
|
165
|
+
// unreachable for typed callers; an unknown mode string from untyped JS lands here
|
|
166
|
+
const found = columns;
|
|
167
|
+
throw new GraphFormatError("E_UNSUPPORTED", `unsupported columns option "${found}"`, {
|
|
168
|
+
field: "columns",
|
|
169
|
+
found,
|
|
170
|
+
reason: "unsupported option",
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const declared = new Map();
|
|
174
|
+
const list = columns;
|
|
175
|
+
for (const decl of list) {
|
|
176
|
+
if (typeof decl.name !== "string" || decl.name.length === 0) {
|
|
177
|
+
throw new GraphFormatError("E_COLUMN_TYPE", "a column declaration needs a non-empty name", {
|
|
178
|
+
field: "name",
|
|
179
|
+
found: decl.name,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
if (declared.has(decl.name)) {
|
|
183
|
+
throw new GraphFormatError("E_COLUMN_EXISTS", `column "${decl.name}" is declared twice`, {
|
|
184
|
+
column: decl.name,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
declared.set(decl.name, decl);
|
|
188
|
+
}
|
|
189
|
+
this.mode = "declared";
|
|
190
|
+
this.declared = declared;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Whether any attribute key is read at all.
|
|
194
|
+
* @returns false under "none"
|
|
195
|
+
*/
|
|
196
|
+
get readsAttributes() {
|
|
197
|
+
return this.mode !== "none";
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Write one attribute cell according to the policy.
|
|
201
|
+
* @param builder - the builder
|
|
202
|
+
* @param domain - "node" or "edge"
|
|
203
|
+
* @param row - the node index or logical edge index
|
|
204
|
+
* @param key - the record key
|
|
205
|
+
* @param value - the cell value
|
|
206
|
+
*/
|
|
207
|
+
write(builder, domain, row, key, value) {
|
|
208
|
+
switch (this.mode) {
|
|
209
|
+
case "none":
|
|
210
|
+
return;
|
|
211
|
+
case "infer":
|
|
212
|
+
if (domain === "node") {
|
|
213
|
+
builder.setNodeValue(key, row, value);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
builder.setEdgeValue(key, row, value);
|
|
217
|
+
}
|
|
218
|
+
return;
|
|
219
|
+
case "json":
|
|
220
|
+
case "declared": {
|
|
221
|
+
const handle = this.handleOf(builder, domain, key);
|
|
222
|
+
if (handle === null) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (domain === "node") {
|
|
226
|
+
builder.setNodeValue(handle, row, value);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
builder.setEdgeValue(handle, row, value);
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
default: {
|
|
234
|
+
const name = this.mode;
|
|
235
|
+
throw new GraphFormatError("E_UNSUPPORTED", `unknown attribute mode ${name}`, { found: name });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* The handle of a key's column in one table, declaring it on first use: a json column under
|
|
241
|
+
* "json", the caller's declaration under "declared" (an undeclared key has no column).
|
|
242
|
+
* @param builder - the builder
|
|
243
|
+
* @param domain - "node" or "edge"
|
|
244
|
+
* @param key - the record key
|
|
245
|
+
* @returns the handle, or null when the key is not stored
|
|
246
|
+
*/
|
|
247
|
+
handleOf(builder, domain, key) {
|
|
248
|
+
const cache = this.handles[domain];
|
|
249
|
+
const cached = cache.get(key);
|
|
250
|
+
if (cached !== undefined) {
|
|
251
|
+
return cached;
|
|
252
|
+
}
|
|
253
|
+
let decl;
|
|
254
|
+
if (this.mode === "json") {
|
|
255
|
+
decl = { name: key, dtype: "json" };
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
const declared = this.declared.get(key);
|
|
259
|
+
if (declared === undefined) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
decl = declared;
|
|
263
|
+
}
|
|
264
|
+
const handle = domain === "node" ? builder.declareNodeColumn(decl) : builder.declareEdgeColumn(decl);
|
|
265
|
+
cache.set(key, handle);
|
|
266
|
+
return handle;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Resolve the keys and rules of a RecordsInput with their defaults.
|
|
271
|
+
* @param input - the input
|
|
272
|
+
* @returns the rules
|
|
273
|
+
*/
|
|
274
|
+
function rulesOf(input) {
|
|
275
|
+
return {
|
|
276
|
+
nodeId: input.nodeId === undefined ? "id" : input.nodeId,
|
|
277
|
+
edgeSource: input.edgeSource,
|
|
278
|
+
edgeTarget: input.edgeTarget,
|
|
279
|
+
edgeWeight: input.edgeWeight === undefined ? "weight" : input.edgeWeight,
|
|
280
|
+
ids: assertOneOf("ids", input.ids, ["keep", "canonical", "string", "number"]) ?? "keep",
|
|
281
|
+
attributes: new AttributePolicy(input.columns),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Resolve a positional endpoint (nodeId null: endpoints are node indices, design section 8.1): a
|
|
286
|
+
* non-negative integer below the builder's node bound, or -- under addMissingNodes -- one that
|
|
287
|
+
* extends the anonymous node range.
|
|
288
|
+
* @param builder - the builder
|
|
289
|
+
* @param value - the cell value
|
|
290
|
+
* @param field - "source" or "target"
|
|
291
|
+
* @param edge - the record's position, for the error
|
|
292
|
+
* @returns the node index
|
|
293
|
+
*/
|
|
294
|
+
function positionalEndpoint(builder, value, field, edge) {
|
|
295
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
296
|
+
throw new GraphFormatError("E_INVALID_ID", `edge record ${edge}: ${field} ${String(value)} is not a node index`, {
|
|
297
|
+
field,
|
|
298
|
+
found: value,
|
|
299
|
+
edge,
|
|
300
|
+
reason: "not an index",
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
const bound = builder.nodeBound;
|
|
304
|
+
if (value >= bound) {
|
|
305
|
+
if (!builder.options.addMissingNodes) {
|
|
306
|
+
throw new GraphFormatError("E_UNKNOWN_NODE", `edge record ${edge}: node index ${value} does not exist`, {
|
|
307
|
+
index: value,
|
|
308
|
+
field,
|
|
309
|
+
edge,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
builder.addAnonymousNodes(value - bound + 1);
|
|
313
|
+
}
|
|
314
|
+
return value;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Read the weight cell of an edge record: absent, undefined and null mean "no weight" (1 in a
|
|
318
|
+
* weighted graph, design section 3.7); anything else must be a number.
|
|
319
|
+
* @param record - the edge record
|
|
320
|
+
* @param key - the weight key
|
|
321
|
+
* @param edge - the record's position, for the error
|
|
322
|
+
* @returns the weight, or undefined when omitted
|
|
323
|
+
*/
|
|
324
|
+
function weightOf(record, key, edge) {
|
|
325
|
+
if (!hasKey(record, key)) {
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
const raw = record[key];
|
|
329
|
+
if (raw === undefined || raw === null) {
|
|
330
|
+
return undefined;
|
|
331
|
+
}
|
|
332
|
+
if (typeof raw !== "number") {
|
|
333
|
+
throw new GraphFormatError("E_INVALID_WEIGHT", `edge record ${edge}: weight "${key}" is not a number`, {
|
|
334
|
+
key,
|
|
335
|
+
found: typeof raw,
|
|
336
|
+
edge,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
return raw;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Push the node records.
|
|
343
|
+
* @param builder - the builder
|
|
344
|
+
* @param rules - the resolved rules
|
|
345
|
+
* @param nodes - the node records
|
|
346
|
+
*/
|
|
347
|
+
function pushNodes(builder, rules, nodes) {
|
|
348
|
+
const { nodeId, attributes } = rules;
|
|
349
|
+
let position = 0;
|
|
350
|
+
for (const record of nodes) {
|
|
351
|
+
let index;
|
|
352
|
+
if (nodeId === null) {
|
|
353
|
+
index = builder.addAnonymousNodes(1);
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
if (!hasKey(record, nodeId)) {
|
|
357
|
+
throw new GraphFormatError("E_INVALID_ID", `node record ${position} has no "${nodeId}" key`, {
|
|
358
|
+
field: nodeId,
|
|
359
|
+
node: position,
|
|
360
|
+
reason: "missing id",
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
index = builder.addNode(coerceId(record[nodeId], rules.ids, nodeId));
|
|
364
|
+
}
|
|
365
|
+
if (attributes.readsAttributes) {
|
|
366
|
+
for (const key of Object.keys(record)) {
|
|
367
|
+
if (key !== nodeId) {
|
|
368
|
+
attributes.write(builder, "node", index, key, record[key]);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
position++;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Push the edge records.
|
|
377
|
+
* @param builder - the builder
|
|
378
|
+
* @param rules - the resolved rules
|
|
379
|
+
* @param edges - the edge records
|
|
380
|
+
*/
|
|
381
|
+
function pushEdges(builder, rules, edges) {
|
|
382
|
+
const { nodeId, edgeWeight, attributes } = rules;
|
|
383
|
+
let position = 0;
|
|
384
|
+
for (const record of edges) {
|
|
385
|
+
const source = endpointOf(record, rules.edgeSource, SOURCE_KEYS);
|
|
386
|
+
const target = endpointOf(record, rules.edgeTarget, TARGET_KEYS);
|
|
387
|
+
if (source.key === null) {
|
|
388
|
+
throw missingEndpoint("source", rules.edgeSource === undefined ? SOURCE_KEYS : [rules.edgeSource], position);
|
|
389
|
+
}
|
|
390
|
+
if (target.key === null) {
|
|
391
|
+
throw missingEndpoint("target", rules.edgeTarget === undefined ? TARGET_KEYS : [rules.edgeTarget], position);
|
|
392
|
+
}
|
|
393
|
+
const weight = edgeWeight === null ? undefined : weightOf(record, edgeWeight, position);
|
|
394
|
+
let edge;
|
|
395
|
+
if (nodeId === null) {
|
|
396
|
+
const u = positionalEndpoint(builder, source.value, "source", position);
|
|
397
|
+
const v = positionalEndpoint(builder, target.value, "target", position);
|
|
398
|
+
edge = builder.addEdgeByIndex(u, v, weight);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
edge = builder.addEdge(coerceId(source.value, rules.ids, "source"), coerceId(target.value, rules.ids, "target"), weight);
|
|
402
|
+
}
|
|
403
|
+
if (attributes.readsAttributes) {
|
|
404
|
+
for (const key of Object.keys(record)) {
|
|
405
|
+
if (key !== source.key && key !== target.key && key !== edgeWeight) {
|
|
406
|
+
attributes.write(builder, "edge", edge, key, record[key]);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
position++;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Build a snapshot from node-link records (design section 8.1): node records (optional; every node
|
|
415
|
+
* an edge names is created under addMissingNodes, the default) and edge records, pushed into a
|
|
416
|
+
* GraphBuilder one scalar at a time and frozen. The node id comes from `nodeId` ("id" by default;
|
|
417
|
+
* null makes the node index the record position and the endpoints indices, the d3 v3 shape), the
|
|
418
|
+
* endpoints from `edgeSource` / `edgeTarget` ("source" / "target" by default, falling back to "src"
|
|
419
|
+
* / "from" and "dst" / "to"), the weight from `edgeWeight` ("weight" by default; null = unweighted).
|
|
420
|
+
* Every other key becomes an attribute column per `columns`: "infer" (default) lets the builder
|
|
421
|
+
* infer and widen per column (design section 5.1), "json" stores each key as a json column, "none"
|
|
422
|
+
* loads only the structure, and a ColumnDecl list stores only the declared keys. Ids are coerced per
|
|
423
|
+
* `ids` ("keep" by default). The staging weight precision defaults to f64 so a JSON weight such as
|
|
424
|
+
* 0.1 is never corrupted (the shadow column costs nothing when every value is f32-exact); pass
|
|
425
|
+
* `weightDtype: "f32"` to opt out.
|
|
426
|
+
* @param input - the records and keys; a record without its id or an endpoint, or with an id the
|
|
427
|
+
* coercion rule cannot convert, is E_INVALID_ID; a non-numeric weight is E_INVALID_WEIGHT; an
|
|
428
|
+
* unknown endpoint under addMissingNodes false is E_UNKNOWN_NODE
|
|
429
|
+
* @param options - builder policies and freeze options
|
|
430
|
+
* @returns the snapshot and the freeze report (its `widened` entries name the inferred columns that
|
|
431
|
+
* widened while the records were read)
|
|
432
|
+
*/
|
|
433
|
+
export function fromRecords(input, options = {}) {
|
|
434
|
+
const rules = rulesOf(input);
|
|
435
|
+
const split = splitOptions(input.directed, options);
|
|
436
|
+
const builderOptions = {
|
|
437
|
+
...split.builder,
|
|
438
|
+
weightDtype: options.weightDtype ?? "f64",
|
|
439
|
+
};
|
|
440
|
+
const builder = new GraphBuilder(builderOptions);
|
|
441
|
+
if (input.nodes !== undefined) {
|
|
442
|
+
pushNodes(builder, rules, input.nodes);
|
|
443
|
+
}
|
|
444
|
+
pushEdges(builder, rules, input.edges);
|
|
445
|
+
return builder.freezeWithReport(split.freeze);
|
|
446
|
+
}
|
|
447
|
+
//# sourceMappingURL=from-records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-records.js","sourceRoot":"","sources":["../../../src/populate/from-records.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derived graphs (design section 7.3): `toUndirected`, `transpose`, `simplified`, `withoutSelfLoops`,
|
|
3
|
+
* `filterEdges`, `inducedSubgraph`, `contract`, `relabel` and `withColumns`, each returning the
|
|
4
|
+
* `SnapshotParts` of a NEW snapshot plus the index maps back to the source (`DerivedParts`), and the
|
|
5
|
+
* `renumberPartition` helper of design section 7.5. GraphSnapshot wraps the parts with
|
|
6
|
+
* `createSnapshot()`; this module imports the class type only, so there is no runtime cycle.
|
|
7
|
+
*
|
|
8
|
+
* Every derived core is built by `buildCore()`, the two stable counting-sort passes of design section
|
|
9
|
+
* 6.3 steps 3-6 over a per-logical-edge list (src, dst, weight) in declared orientation, into a fresh
|
|
10
|
+
* 256-aligned arena (section 10.3), so every derived snapshot inherits invariants I1-I10 by
|
|
11
|
+
* construction and `flags` are computed by the one predicate set in validate.ts (I9).
|
|
12
|
+
*
|
|
13
|
+
* Index-map conventions (design section 7.3): `nodeOrigin` / `edgeOrigin` are NEW -> SOURCE,
|
|
14
|
+
* `nodeRemap` / `edgeRemap` SOURCE -> NEW with INVALID_INDEX for a dropped row and the SURVIVOR's new
|
|
15
|
+
* index for a merged edge; each map is null exactly when its index space is unchanged (same length,
|
|
16
|
+
* identity). New edges are numbered in ascending order of their survivor's source index, so relative
|
|
17
|
+
* edge order is preserved (I14). Attribute tables follow the propagation table of design section
|
|
18
|
+
* 5.11: same node space -> the SAME `AttributeTable` instance; gathered otherwise; `refersTo` values
|
|
19
|
+
* rewritten through the matching remap.
|
|
20
|
+
*/
|
|
21
|
+
import { type ArenaLayout, type ColumnInput, type ContractOptions, type EdgeListView, type EdgeMask, type F32, type GraphSnapshot, type NodeMask, type ReverseView, type SimplifyOptions, type SnapshotFlags, type ToUndirectedOptions, type TypedArrayData, type U32 } from "../types/index.js";
|
|
22
|
+
import { type SnapshotParts } from "../types/internal.js";
|
|
23
|
+
/** The report of a derived graph: how many source edges were dropped and how many merged into a survivor. */
|
|
24
|
+
interface DerivedReport {
|
|
25
|
+
/** Source edges with no counterpart in the derived graph. */
|
|
26
|
+
readonly droppedEdges: number;
|
|
27
|
+
/** Source edges collapsed into another edge (the survivor). */
|
|
28
|
+
readonly mergedEdges: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* What a derive function returns: the parts of the new snapshot (null when the operation is the
|
|
32
|
+
* identity and the caller returns the source itself) and the maps of `DerivedGraph`.
|
|
33
|
+
*/
|
|
34
|
+
export interface DerivedParts {
|
|
35
|
+
/** The parts of the new snapshot, or null for "return this". */
|
|
36
|
+
readonly parts: SnapshotParts | null;
|
|
37
|
+
/** New node index -> source node index, or null when the node space is unchanged. */
|
|
38
|
+
readonly nodeOrigin: U32 | null;
|
|
39
|
+
/** New edge index -> source edge index (survivor), or null when the edge space is unchanged. */
|
|
40
|
+
readonly edgeOrigin: U32 | null;
|
|
41
|
+
/** Source node index -> new node index or INVALID_INDEX, or null when unchanged. */
|
|
42
|
+
readonly nodeRemap: U32 | null;
|
|
43
|
+
/** Source edge index -> new edge index (survivor) or INVALID_INDEX, or null when unchanged. */
|
|
44
|
+
readonly edgeRemap: U32 | null;
|
|
45
|
+
/** contract only: source nodes per block. */
|
|
46
|
+
readonly blockSizes: U32 | null;
|
|
47
|
+
/** Dropped and merged edge counts. */
|
|
48
|
+
readonly report: DerivedReport;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The DerivedParts of an identity operation: the caller returns the source snapshot itself.
|
|
52
|
+
* @returns parts null, every map null, an empty report
|
|
53
|
+
*/
|
|
54
|
+
export declare function identityDerived(): DerivedParts;
|
|
55
|
+
/** A per-logical-edge description of a graph in declared orientation: the input of `buildCore()`. */
|
|
56
|
+
interface EdgeArrays {
|
|
57
|
+
/** Whether the graph is directed. */
|
|
58
|
+
readonly directed: boolean;
|
|
59
|
+
/** The node count. */
|
|
60
|
+
readonly nodeCount: number;
|
|
61
|
+
/** The logical edge count. */
|
|
62
|
+
readonly edgeCount: number;
|
|
63
|
+
/** Declared source of every edge. */
|
|
64
|
+
readonly src: U32;
|
|
65
|
+
/** Declared target of every edge. */
|
|
66
|
+
readonly dst: U32;
|
|
67
|
+
/** Per-edge f32 weights, or null when unweighted. */
|
|
68
|
+
readonly weights: F32 | null;
|
|
69
|
+
}
|
|
70
|
+
/** The core a `buildCore()` call produces: exactly the core fields of SnapshotParts. */
|
|
71
|
+
interface BuiltCore {
|
|
72
|
+
/** colIdx.length. */
|
|
73
|
+
readonly arcCount: number;
|
|
74
|
+
/** Logical edges with source === target. */
|
|
75
|
+
readonly selfLoopCount: number;
|
|
76
|
+
/** nodeCount + 1 row offsets. */
|
|
77
|
+
readonly rowPtr: U32;
|
|
78
|
+
/** Sorted targets. */
|
|
79
|
+
readonly colIdx: U32;
|
|
80
|
+
/** Per-arc weights, or null. */
|
|
81
|
+
readonly weights: F32 | null;
|
|
82
|
+
/** arcCount entries, or null when the permutation is the identity. */
|
|
83
|
+
readonly arcToEdge: U32 | null;
|
|
84
|
+
/** edgeCount entries, or null when the permutation is the identity. */
|
|
85
|
+
readonly edgeToArc: U32 | null;
|
|
86
|
+
/** The truthful flags (I9). */
|
|
87
|
+
readonly flags: SnapshotFlags;
|
|
88
|
+
/** The arena the arrays are views into, or null when `arena: false`. */
|
|
89
|
+
readonly arena: ArenaLayout | null;
|
|
90
|
+
}
|
|
91
|
+
/** Options of `buildCore()`. */
|
|
92
|
+
interface BuildCoreOptions {
|
|
93
|
+
/** Allocate the arrays inside one 256-aligned arena (default true) or as separate buffers. */
|
|
94
|
+
readonly arena?: boolean | undefined;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Build the core of a derived graph from a per-logical-edge list in declared orientation: the two
|
|
98
|
+
* stable counting-sort passes of design section 6.3 steps 3-6 (`sortIntoCore` of the builder module,
|
|
99
|
+
* so derived graphs and freezes share one implementation), into a fresh 256-aligned arena unless
|
|
100
|
+
* `arena: false`. Invariants I1-I10 hold by construction and the flags are computed from the stored
|
|
101
|
+
* values (I9). A NaN weight (a reducer summing +Infinity and -Infinity) is E_INVALID_WEIGHT (I8).
|
|
102
|
+
* @param edges - the per-edge arrays; only the first `edgeCount` entries are read
|
|
103
|
+
* @param options - arena or separate buffers
|
|
104
|
+
* @returns the core, the counts and the flags
|
|
105
|
+
*/
|
|
106
|
+
export declare function buildCore(edges: EdgeArrays, options?: BuildCoreOptions): BuiltCore;
|
|
107
|
+
/**
|
|
108
|
+
* `filterEdges(keep)`: the logical edges whose mask bit is set (design section 7.3).
|
|
109
|
+
* @param source - the source snapshot
|
|
110
|
+
* @param list - the source edge list
|
|
111
|
+
* @param keep - packed bitmap over logical edges; E_MASK_LENGTH when short
|
|
112
|
+
* @returns the derived parts
|
|
113
|
+
*/
|
|
114
|
+
export declare function deriveFilterEdges(source: GraphSnapshot, list: EdgeListView, keep: EdgeMask): DerivedParts;
|
|
115
|
+
/**
|
|
116
|
+
* `withoutSelfLoops()`: every edge with source !== target (design section 7.3).
|
|
117
|
+
* @param source - the source snapshot
|
|
118
|
+
* @param list - the source edge list
|
|
119
|
+
* @returns the derived parts
|
|
120
|
+
*/
|
|
121
|
+
export declare function deriveWithoutSelfLoops(source: GraphSnapshot, list: EdgeListView): DerivedParts;
|
|
122
|
+
/**
|
|
123
|
+
* `inducedSubgraph(selection)`: the subgraph on a node selection with every edge whose endpoints are
|
|
124
|
+
* both kept (design section 7.3); a compact new node space unless the selection is the identity.
|
|
125
|
+
* @param source - the source snapshot
|
|
126
|
+
* @param list - the source edge list
|
|
127
|
+
* @param selection - an index list (new index order) or a packed mask (ascending)
|
|
128
|
+
* @returns the derived parts
|
|
129
|
+
*/
|
|
130
|
+
export declare function deriveInducedSubgraph(source: GraphSnapshot, list: EdgeListView, selection: U32 | {
|
|
131
|
+
readonly mask: NodeMask;
|
|
132
|
+
}): DerivedParts;
|
|
133
|
+
/**
|
|
134
|
+
* `relabel(perm)`: the node space permuted with `perm[newIndex] = oldIndex`, edge order preserved
|
|
135
|
+
* (design section 7.3); E_INVALID_PERMUTATION unless perm is a permutation of 0..n-1.
|
|
136
|
+
* @param source - the source snapshot
|
|
137
|
+
* @param list - the source edge list
|
|
138
|
+
* @param perm - the permutation
|
|
139
|
+
* @returns the derived parts
|
|
140
|
+
*/
|
|
141
|
+
export declare function deriveRelabel(source: GraphSnapshot, list: EdgeListView, perm: U32): DerivedParts;
|
|
142
|
+
/**
|
|
143
|
+
* `toUndirected(options)` on a directed snapshot (design section 7.3): every edge becomes undirected;
|
|
144
|
+
* reciprocal pairs u -> v / v -> u (paired k-th to k-th among parallels, in edge order) collapse to
|
|
145
|
+
* one edge keeping the lower index's row and the reduced weight (default "first"); with
|
|
146
|
+
* `reciprocal: true` only paired edges survive. Self-loops are kept.
|
|
147
|
+
* @param source - a directed snapshot
|
|
148
|
+
* @param list - the source edge list
|
|
149
|
+
* @param options - reciprocal filtering and the weight reducer
|
|
150
|
+
* @returns the derived parts
|
|
151
|
+
*/
|
|
152
|
+
export declare function deriveToUndirected(source: GraphSnapshot, list: EdgeListView, options?: ToUndirectedOptions): DerivedParts;
|
|
153
|
+
/**
|
|
154
|
+
* `transpose()` on a directed snapshot (design section 7.3): the orientation of every edge swapped by
|
|
155
|
+
* adopting the reverse view's arrays as the core (zero copy, so `arena` is null); node and edge
|
|
156
|
+
* spaces unchanged, tables shared.
|
|
157
|
+
* @param source - a directed snapshot
|
|
158
|
+
* @param reverse - its reverse view
|
|
159
|
+
* @returns the derived parts
|
|
160
|
+
*/
|
|
161
|
+
export declare function deriveTranspose(source: GraphSnapshot, reverse: ReverseView): DerivedParts;
|
|
162
|
+
/**
|
|
163
|
+
* `simplified(options)` (design section 7.3): one edge per (u, v) group (parallels are adjacent by
|
|
164
|
+
* I4; undirected groups are unordered pairs), survivor = lowest index, weights per `weights`
|
|
165
|
+
* (default "first"), self-loops kept or dropped, other edge columns per `edgeReducers` (default: the
|
|
166
|
+
* survivor's row). `flags.multigraph` is false afterwards.
|
|
167
|
+
* @param source - the source snapshot
|
|
168
|
+
* @param list - the source edge list
|
|
169
|
+
* @param options - reducers and self-loop policy
|
|
170
|
+
* @returns the derived parts
|
|
171
|
+
*/
|
|
172
|
+
export declare function deriveSimplified(source: GraphSnapshot, list: EdgeListView, options?: SimplifyOptions): DerivedParts;
|
|
173
|
+
/**
|
|
174
|
+
* Renumber an arbitrary u32 labelling to dense 0..k-1 in first-seen order (design section 7.5; what
|
|
175
|
+
* `contract()` does with non-dense labels). INVALID_INDEX is not a legal label (E_PARTITION).
|
|
176
|
+
* @param labels - the labels
|
|
177
|
+
* @param out - an optional destination of the same length (may be `labels` itself)
|
|
178
|
+
* @returns the dense labels and the block count
|
|
179
|
+
*/
|
|
180
|
+
export declare function renumberPartition(labels: U32, out?: U32): {
|
|
181
|
+
readonly labels: U32;
|
|
182
|
+
readonly count: number;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* `contract(partition, options)` (design section 7.3): the nodes of each block become one node (block
|
|
186
|
+
* indices as labels, ids 0..k-1), every source edge contributes once: an inter-block edge becomes an
|
|
187
|
+
* edge block(u) -> block(v), an intra-block edge one self-loop with weight w, kept or dropped per
|
|
188
|
+
* `selfLoops`; parallels merge per `parallel` with the `weights` reducer (default "sum"; on an
|
|
189
|
+
* unweighted source "sum" materialises multiplicities). Node and edge columns are kept only through
|
|
190
|
+
* `nodeReducers` / `edgeReducers`.
|
|
191
|
+
* @param source - the source snapshot
|
|
192
|
+
* @param list - the source edge list
|
|
193
|
+
* @param partition - one label per node; E_PARTITION for a wrong length or an INVALID_INDEX label
|
|
194
|
+
* @param options - the contraction options
|
|
195
|
+
* @returns the derived parts with blockSizes
|
|
196
|
+
*/
|
|
197
|
+
export declare function deriveContract(source: GraphSnapshot, list: EdgeListView, partition: U32, options?: ContractOptions): DerivedParts;
|
|
198
|
+
/**
|
|
199
|
+
* `withColumns(nodes, edges)` (design section 7.3): the parts of a snapshot sharing the core, the id
|
|
200
|
+
* map and the SERIAL of the source with a CLONED column set plus the given columns (the graph table is
|
|
201
|
+
* cloned too; extension tables are shared).
|
|
202
|
+
* @param source - the source snapshot
|
|
203
|
+
* @param nodes - node columns to add, keyed by name
|
|
204
|
+
* @param edges - edge columns to add, keyed by name
|
|
205
|
+
* @param arcToEdge - the source's permutation arrays as the constructor holds them (null when identity)
|
|
206
|
+
* @param edgeToArc - see arcToEdge
|
|
207
|
+
* @returns the parts
|
|
208
|
+
*/
|
|
209
|
+
export declare function withColumnsParts(source: GraphSnapshot, nodes: Readonly<Record<string, TypedArrayData | ColumnInput>> | undefined, edges: Readonly<Record<string, TypedArrayData | ColumnInput>> | undefined, arcToEdge: U32 | null, edgeToArc: U32 | null): SnapshotParts;
|
|
210
|
+
export {};
|
|
211
|
+
//# sourceMappingURL=derived.d.ts.map
|