@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
package/src/errors.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The error class and the closed set of error codes of @graphty/graph-format (design section 11).
|
|
3
|
+
*
|
|
4
|
+
* Policy (design section 11.1): the builder and the constructors throw on malformed input, on the
|
|
5
|
+
* first error, with a GraphFormatError carrying a stable `code`; snapshot methods that take an index
|
|
6
|
+
* are total for in-range arguments and unchecked otherwise; only GraphFormatError instances are ever
|
|
7
|
+
* thrown by this package. Messages are plain ASCII and name the offending index, id or value when it
|
|
8
|
+
* is a number or a short string. ImportError (code E_IMPORT) is declared by @graphty/graph-io.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The closed union of error codes a GraphFormatError can carry (design section 11.2). Each code is
|
|
13
|
+
* stable across versions and is the value consumers branch on; the message is for humans.
|
|
14
|
+
*
|
|
15
|
+
* - E_INVALID_ID: NaN, a non-finite number, a bigint, an object, null, undefined or a string with a
|
|
16
|
+
* lone surrogate used as an id (details.reason "lone surrogate").
|
|
17
|
+
* - E_UNKNOWN_NODE: addEdge with addMissingNodes false, addEdgeByIndex with a dead or out-of-range
|
|
18
|
+
* index (details.index), or a requireIndex miss.
|
|
19
|
+
* - E_INDEX_RANGE: ids.idOf / table.value out of range; inducedSubgraph with a repeated or
|
|
20
|
+
* out-of-range index.
|
|
21
|
+
* - E_TOO_LARGE: nodeCount, edgeCount or arcCount would exceed MAX_COUNT.
|
|
22
|
+
* - E_INVALID_WEIGHT: a NaN weight at addEdge / setEdgeWeight / addEdges.
|
|
23
|
+
* - E_DIRECTED: mate() on a directed snapshot; setDirected() refused (locked, or a change the edge
|
|
24
|
+
* set does not allow).
|
|
25
|
+
* - E_SELF_LOOP: a self-loop under selfLoops "error".
|
|
26
|
+
* - E_DUPLICATE_EDGE: a parallel edge under duplicateEdges "error" (details source, target, edges).
|
|
27
|
+
* - E_DUPLICATE_EDGE_ID: a unique role "id" edge column violated (both edge indices in details).
|
|
28
|
+
* - E_DUPLICATE_ID: a unique node column violated; addGraph with onDuplicateNode "error"; a
|
|
29
|
+
* repeated id in the `ids` array or F64 given to fromEdgeArrays / fromCsr.
|
|
30
|
+
* - E_DUPLICATE_ROLE: two columns with the same role in one table.
|
|
31
|
+
* - E_UNKNOWN_COLUMN: require() of an absent column.
|
|
32
|
+
* - E_COLUMN_TYPE: requireTyped() dtype mismatch; a non-JSON default / fill / options / extra value
|
|
33
|
+
* (details.field); a string value with a lone surrogate.
|
|
34
|
+
* - E_COLUMN_LENGTH: set() with data.length !== rowCount * components.
|
|
35
|
+
* - E_COLUMN_ALIGNMENT: a u8 array without a constructible padded u32 view under adopt "strict".
|
|
36
|
+
* - E_COLUMN_EXISTS: declareNodeColumn / declareEdgeColumn twice with a different declaration.
|
|
37
|
+
* - E_COLUMN_IMMUTABLE: mutableData() / markDirty() / mutableValidity() / setAll() on an immutable
|
|
38
|
+
* column.
|
|
39
|
+
* - E_NO_DEFAULT: materializeDefault() on a column without a declared default.
|
|
40
|
+
* - E_PARTITION: contract() partition of the wrong length or holding INVALID_INDEX.
|
|
41
|
+
* - E_INVALID_PERMUTATION: relabel() with a perm that is not a permutation of 0..n-1.
|
|
42
|
+
* - E_MASK_LENGTH: filterEdges() / inducedSubgraph({ mask }) with a short mask.
|
|
43
|
+
* - E_GPU_INELIGIBLE: gpuView() / paddedU32View() on a string, list or json column.
|
|
44
|
+
* - E_INVALID_SNAPSHOT: validate() failure (details.invariant, row / arc / edge / column) or
|
|
45
|
+
* validate({ checksum: true }) on a snapshot without recorded checksums (details.reason
|
|
46
|
+
* "no-checksum").
|
|
47
|
+
* - E_BAD_SERIALIZATION: bad magic, endianness probe, manifest or buffer reference (details.ref).
|
|
48
|
+
* - E_UNSUPPORTED_VERSION: unknown wire major or formatVersion (details.kind "wire" | "format",
|
|
49
|
+
* details.found, details.supported).
|
|
50
|
+
* - E_DETACHED: a core accessor after a consuming transfer.
|
|
51
|
+
* - E_BUILDER_DISPOSED: any call on a disposed builder.
|
|
52
|
+
* - E_UNSUPPORTED: big-endian host (details.reason); unknown wire dtype (details.dtype) or id-map
|
|
53
|
+
* kind (details.kind).
|
|
54
|
+
* - E_IMPORT: reserved for @graphty/graph-io's ImportError.
|
|
55
|
+
*/
|
|
56
|
+
export type GraphFormatErrorCode =
|
|
57
|
+
| "E_INVALID_ID"
|
|
58
|
+
| "E_UNKNOWN_NODE"
|
|
59
|
+
| "E_INDEX_RANGE"
|
|
60
|
+
| "E_TOO_LARGE"
|
|
61
|
+
| "E_INVALID_WEIGHT"
|
|
62
|
+
| "E_DIRECTED"
|
|
63
|
+
| "E_SELF_LOOP"
|
|
64
|
+
| "E_DUPLICATE_EDGE"
|
|
65
|
+
| "E_DUPLICATE_EDGE_ID"
|
|
66
|
+
| "E_DUPLICATE_ID"
|
|
67
|
+
| "E_DUPLICATE_ROLE"
|
|
68
|
+
| "E_UNKNOWN_COLUMN"
|
|
69
|
+
| "E_COLUMN_TYPE"
|
|
70
|
+
| "E_COLUMN_LENGTH"
|
|
71
|
+
| "E_COLUMN_ALIGNMENT"
|
|
72
|
+
| "E_COLUMN_EXISTS"
|
|
73
|
+
| "E_COLUMN_IMMUTABLE"
|
|
74
|
+
| "E_NO_DEFAULT"
|
|
75
|
+
| "E_PARTITION"
|
|
76
|
+
| "E_INVALID_PERMUTATION"
|
|
77
|
+
| "E_MASK_LENGTH"
|
|
78
|
+
| "E_GPU_INELIGIBLE"
|
|
79
|
+
| "E_INVALID_SNAPSHOT"
|
|
80
|
+
| "E_BAD_SERIALIZATION"
|
|
81
|
+
| "E_UNSUPPORTED_VERSION"
|
|
82
|
+
| "E_DETACHED"
|
|
83
|
+
| "E_BUILDER_DISPOSED"
|
|
84
|
+
| "E_UNSUPPORTED"
|
|
85
|
+
| "E_IMPORT";
|
|
86
|
+
|
|
87
|
+
const EMPTY_DETAILS: Readonly<Record<string, unknown>> = Object.freeze({});
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The only error type this package throws (design section 11.2). `code` is the stable, programmatic
|
|
91
|
+
* discriminator; `details` carries the machine-readable context named per code in the
|
|
92
|
+
* GraphFormatErrorCode documentation (index, id, edge, invariant, row, found, supported, ...) as a
|
|
93
|
+
* frozen shallow copy of what the thrower supplied. `name` is "GraphFormatError" so stack traces and
|
|
94
|
+
* test matchers read naturally.
|
|
95
|
+
*/
|
|
96
|
+
export class GraphFormatError extends Error {
|
|
97
|
+
/** The stable error code (design section 11.2). */
|
|
98
|
+
readonly code: GraphFormatErrorCode;
|
|
99
|
+
|
|
100
|
+
/** Machine-readable context for the failure; an empty frozen object when none was supplied. */
|
|
101
|
+
readonly details: Readonly<Record<string, unknown>>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Create a GraphFormatError.
|
|
105
|
+
* @param code - the stable error code the caller can branch on
|
|
106
|
+
* @param message - a plain-ASCII human-readable message naming the offending index, id or value
|
|
107
|
+
* @param details - optional machine-readable context; copied shallowly and frozen
|
|
108
|
+
*/
|
|
109
|
+
constructor(code: GraphFormatErrorCode, message: string, details?: Readonly<Record<string, unknown>>) {
|
|
110
|
+
super(message);
|
|
111
|
+
this.name = "GraphFormatError";
|
|
112
|
+
this.code = code;
|
|
113
|
+
this.details = details === undefined ? EMPTY_DETAILS : Object.freeze({ ...details });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge ids are optional data, not structure (design section 4.6): an edge column with role "id"
|
|
3
|
+
* (dtype string, dict, u32 or f64 in practice; any scalar numeric dtype is read the same way) holds
|
|
4
|
+
* them, importers declare it `unique: true`, and `snapshot.edgeIndexOf(id)` resolves an id through
|
|
5
|
+
* a Map built lazily on the first call. This module owns that lazy index and the uniqueness check
|
|
6
|
+
* freeze runs over the SET rows of a unique id column (E_DUPLICATE_EDGE_ID with both edge indices).
|
|
7
|
+
* Equality is SameValueZero (a JS Map key), the same rule as node ids.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { INVALID_INDEX } from "../constants.js";
|
|
11
|
+
import { GraphFormatError } from "../errors.js";
|
|
12
|
+
import { type Column, type EdgeId } from "../types/index.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The E_COLUMN_TYPE error for a column whose dtype cannot hold edge ids.
|
|
16
|
+
* @param column - the column
|
|
17
|
+
* @returns the error
|
|
18
|
+
*/
|
|
19
|
+
function unsupportedDtype(column: Column): GraphFormatError {
|
|
20
|
+
return new GraphFormatError(
|
|
21
|
+
"E_COLUMN_TYPE",
|
|
22
|
+
`column ${JSON.stringify(column.meta.name)} of dtype ${column.dtype} cannot hold edge ids`,
|
|
23
|
+
{ column: column.meta.name, dtype: column.dtype, reason: "edge id dtype" },
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The id stored in one SET row of an edge id column: the decoded string of a string column, the
|
|
29
|
+
* dictionary value of a dict column, or the (first component of the) number of a numeric column.
|
|
30
|
+
* The caller has checked `column.isSet(row)`.
|
|
31
|
+
* @param column - the id column
|
|
32
|
+
* @param row - a set row
|
|
33
|
+
* @returns the id
|
|
34
|
+
*/
|
|
35
|
+
export function edgeIdOfRow(column: Column, row: number): EdgeId {
|
|
36
|
+
switch (column.dtype) {
|
|
37
|
+
case "string":
|
|
38
|
+
return column.valueAt(row);
|
|
39
|
+
case "dict":
|
|
40
|
+
return column.dictionary[column.codes[row]];
|
|
41
|
+
case "f32":
|
|
42
|
+
case "f64":
|
|
43
|
+
case "i32":
|
|
44
|
+
case "u32":
|
|
45
|
+
case "u8":
|
|
46
|
+
return column.data[row * column.meta.components];
|
|
47
|
+
case "bool":
|
|
48
|
+
case "list":
|
|
49
|
+
case "json":
|
|
50
|
+
throw unsupportedDtype(column);
|
|
51
|
+
default:
|
|
52
|
+
throw unsupportedDtype(column);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Whether a column's dtype can hold edge ids (string, dict or a scalar numeric dtype).
|
|
58
|
+
* @param column - the column
|
|
59
|
+
* @returns true when edgeIdOfRow can read it
|
|
60
|
+
*/
|
|
61
|
+
export function canHoldEdgeIds(column: Column): boolean {
|
|
62
|
+
switch (column.dtype) {
|
|
63
|
+
case "string":
|
|
64
|
+
case "dict":
|
|
65
|
+
case "f32":
|
|
66
|
+
case "f64":
|
|
67
|
+
case "i32":
|
|
68
|
+
case "u32":
|
|
69
|
+
case "u8":
|
|
70
|
+
return true;
|
|
71
|
+
case "bool":
|
|
72
|
+
case "list":
|
|
73
|
+
case "json":
|
|
74
|
+
return false;
|
|
75
|
+
default:
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Build the id -> edge index map of an id column over its SET rows in one pass. When an id repeats
|
|
82
|
+
* the lowest edge index wins (a unique column never repeats; `findDuplicateEdgeId` reports it).
|
|
83
|
+
* @param column - the edge id column
|
|
84
|
+
* @returns a fresh Map from id to logical edge index
|
|
85
|
+
*/
|
|
86
|
+
export function buildEdgeIdMap(column: Column): Map<EdgeId, number> {
|
|
87
|
+
if (!canHoldEdgeIds(column)) {
|
|
88
|
+
throw unsupportedDtype(column);
|
|
89
|
+
}
|
|
90
|
+
const map = new Map<EdgeId, number>();
|
|
91
|
+
const rows = column.length;
|
|
92
|
+
for (let e = 0; e < rows; e++) {
|
|
93
|
+
if (!column.isSet(e)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const id = edgeIdOfRow(column, e);
|
|
97
|
+
if (!map.has(id)) {
|
|
98
|
+
map.set(id, e);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return map;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The lazily built index behind `snapshot.edgeIndexOf(id)` (design section 4.6): a Map from id to
|
|
106
|
+
* logical edge index over the set rows of the role "id" edge column, built on the first lookup and
|
|
107
|
+
* rebuilt when a mutable column's `version` has changed since.
|
|
108
|
+
*/
|
|
109
|
+
export class EdgeIdIndex {
|
|
110
|
+
/** The edge id column. */
|
|
111
|
+
private readonly column: Column;
|
|
112
|
+
|
|
113
|
+
/** The map, or null before the first lookup. */
|
|
114
|
+
private map: Map<EdgeId, number> | null;
|
|
115
|
+
|
|
116
|
+
/** column.version when the map was built. */
|
|
117
|
+
private builtVersion: number;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Wrap an edge id column; nothing is built until the first lookup.
|
|
121
|
+
* @param column - the edge column with role "id"; E_COLUMN_TYPE when its dtype cannot hold ids
|
|
122
|
+
*/
|
|
123
|
+
constructor(column: Column) {
|
|
124
|
+
if (!canHoldEdgeIds(column)) {
|
|
125
|
+
throw unsupportedDtype(column);
|
|
126
|
+
}
|
|
127
|
+
this.column = column;
|
|
128
|
+
this.map = null;
|
|
129
|
+
this.builtVersion = -1;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Whether the map has been built (and is current).
|
|
134
|
+
* @returns true when the next lookup will not build
|
|
135
|
+
*/
|
|
136
|
+
get built(): boolean {
|
|
137
|
+
return this.map !== null && this.builtVersion === this.column.version;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Number of distinct ids over the set rows; builds the map.
|
|
142
|
+
* @returns the id count
|
|
143
|
+
*/
|
|
144
|
+
get size(): number {
|
|
145
|
+
return this.ensure().size;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The logical edge index of an id.
|
|
150
|
+
* @param id - the edge id
|
|
151
|
+
* @returns the edge index, or INVALID_INDEX on a miss
|
|
152
|
+
*/
|
|
153
|
+
indexOf(id: EdgeId): number {
|
|
154
|
+
const index = this.ensure().get(id);
|
|
155
|
+
return index === undefined ? INVALID_INDEX : index;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Whether an id is present.
|
|
160
|
+
* @param id - the edge id
|
|
161
|
+
* @returns true when some set row holds it
|
|
162
|
+
*/
|
|
163
|
+
has(id: EdgeId): boolean {
|
|
164
|
+
return this.ensure().has(id);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The map, built on first use and rebuilt after the column's version changed.
|
|
169
|
+
* @returns the id -> edge index map
|
|
170
|
+
*/
|
|
171
|
+
private ensure(): Map<EdgeId, number> {
|
|
172
|
+
const { version } = this.column;
|
|
173
|
+
if (this.map === null || this.builtVersion !== version) {
|
|
174
|
+
this.map = buildEdgeIdMap(this.column);
|
|
175
|
+
this.builtVersion = version;
|
|
176
|
+
}
|
|
177
|
+
return this.map;
|
|
178
|
+
}
|
|
179
|
+
}
|