@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,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level typed-array helpers shared by every module of @graphty/graph-format (design sections 5.7,
|
|
3
|
+
* 6.2, 9.5, 10.2 and 10.3): rounding and alignment arithmetic, arena segment layout, the 4-byte
|
|
4
|
+
* padding rules of I10, the u8 adoption predicate, the wire buffer-range check, per-dtype
|
|
5
|
+
* typed-array constructors, and the growth primitive of the builder staging (doubling into a
|
|
6
|
+
* resizable ArrayBuffer when the engine has one, allocate-and-copy doubling otherwise).
|
|
7
|
+
*
|
|
8
|
+
* Nothing here knows about graphs; everything is arithmetic over byte lengths and typed arrays.
|
|
9
|
+
*/
|
|
10
|
+
import { type Dtype, type TypedArrayData, type U8, type U32 } from "../types/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Whether resizable ArrayBuffer is available, detected once at module load (design section 6.2). The
|
|
13
|
+
* growth helpers take it as their default; tests pass an explicit value to exercise both paths.
|
|
14
|
+
*/
|
|
15
|
+
export declare const HAS_RESIZABLE_ARRAY_BUFFER: boolean;
|
|
16
|
+
/** Staging capacities are rounded up to this many elements (design section 6.2). */
|
|
17
|
+
export declare const STAGING_ELEMENT_GRANULE = 16;
|
|
18
|
+
/** Staging backing buffers are a multiple of this many bytes (design section 6.2). */
|
|
19
|
+
export declare const STAGING_BYTE_GRANULE = 64;
|
|
20
|
+
/**
|
|
21
|
+
* Virtual address space reserved (`maxByteLength`) for a fresh resizable staging buffer: 256 MiB, so
|
|
22
|
+
* a staging array grows in place without copying up to 64M u32 elements. Reservations are
|
|
23
|
+
* address-space only (pages are committed as the buffer grows), and a buffer that outgrows its
|
|
24
|
+
* reservation is reallocated with a doubled one, so the constant bounds the number of copies rather
|
|
25
|
+
* than the size of anything.
|
|
26
|
+
*/
|
|
27
|
+
export declare const STAGING_RESERVE_BYTES: number;
|
|
28
|
+
/**
|
|
29
|
+
* Round `value` up to the next multiple of `multiple`. Written with `%`, not bit masks, because arc
|
|
30
|
+
* counts and byte lengths exceed 2^31 (invariant I3, design section 10.6).
|
|
31
|
+
* @param value - a non-negative integer
|
|
32
|
+
* @param multiple - a positive integer
|
|
33
|
+
* @returns the smallest multiple of `multiple` that is >= value
|
|
34
|
+
*/
|
|
35
|
+
export declare function roundUp(value: number, multiple: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Pad a byte length to the next multiple of 4: the size of the padded u32 view of a u8 column and
|
|
38
|
+
* the rule every GPU-bound array satisfies (design sections 5.7 and 10.2).
|
|
39
|
+
* @param byteLength - a non-negative byte count
|
|
40
|
+
* @returns roundUp(byteLength, 4)
|
|
41
|
+
*/
|
|
42
|
+
export declare function padTo4(byteLength: number): number;
|
|
43
|
+
/**
|
|
44
|
+
* The number of u32 words that span a byte range: ceil(byteLength / 4) (design section 10.2).
|
|
45
|
+
* @param byteLength - a non-negative byte count
|
|
46
|
+
* @returns the word count of the padded u32 view
|
|
47
|
+
*/
|
|
48
|
+
export declare function paddedWordCount(byteLength: number): number;
|
|
49
|
+
/**
|
|
50
|
+
* Align a byte offset up to the next arena segment boundary (design section 10.3; 256 bytes, the
|
|
51
|
+
* WebGPU minStorageBufferOffsetAlignment default).
|
|
52
|
+
* @param byteOffset - a non-negative byte offset
|
|
53
|
+
* @param alignment - the alignment in bytes; defaults to ALIGNMENT (256)
|
|
54
|
+
* @returns roundUp(byteOffset, alignment)
|
|
55
|
+
*/
|
|
56
|
+
export declare function alignUp(byteOffset: number, alignment?: number): number;
|
|
57
|
+
/**
|
|
58
|
+
* The result of laying out consecutive segments at aligned offsets (design section 10.3).
|
|
59
|
+
*/
|
|
60
|
+
interface SegmentLayout {
|
|
61
|
+
/**
|
|
62
|
+
* One entry per input length: the segment's byte offset relative to the start of the arena, or null for
|
|
63
|
+
* a zero-length segment, which occupies nothing.
|
|
64
|
+
*/
|
|
65
|
+
readonly offsets: readonly (number | null)[];
|
|
66
|
+
/** One entry per input length: offset + length, or null for a zero-length segment. */
|
|
67
|
+
readonly ends: readonly (number | null)[];
|
|
68
|
+
/** The end of the last non-empty segment; 0 when every segment is empty. No trailing padding is added. */
|
|
69
|
+
readonly byteLength: number;
|
|
70
|
+
/** The bytes spent on inter-segment padding. */
|
|
71
|
+
readonly padding: number;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Lay out segments back to back, each non-empty one starting at a multiple of `alignment`, in the
|
|
75
|
+
* given order (design section 10.3: hot to cold). Zero-length segments get a null offset and occupy
|
|
76
|
+
* nothing, which is how an absent `weights`, a zero-arc `colIdx` and an identity permutation stay out
|
|
77
|
+
* of the arena. For the worked example of section 10.3 (400,004 / 8,000,000 / 8,000,000 / 8,000,000 /
|
|
78
|
+
* 4,000,000) the offsets are 0 / 400,128 / 8,400,128 / 16,400,128 / 24,400,128 and the total is
|
|
79
|
+
* 28,400,128 with 124 bytes of padding.
|
|
80
|
+
* @param byteLengths - the unpadded byte length of every segment in arena order (0 = absent)
|
|
81
|
+
* @param alignment - the segment alignment in bytes; defaults to ALIGNMENT (256)
|
|
82
|
+
* @returns the offsets, ends, total byte length and padding of the layout
|
|
83
|
+
*/
|
|
84
|
+
export declare function layoutSegments(byteLengths: readonly number[], alignment?: number): SegmentLayout;
|
|
85
|
+
/**
|
|
86
|
+
* The I10 predicate for a GPU-bound array: a view whose byteOffset and byteLength are both multiples
|
|
87
|
+
* of 4 (design section 10.2).
|
|
88
|
+
* @param view - any ArrayBufferView
|
|
89
|
+
* @returns true when both byteOffset and byteLength are multiples of 4
|
|
90
|
+
*/
|
|
91
|
+
export declare function isFourByteAligned(view: ArrayBufferView): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* The "plain ArrayBuffer" half of invariant I10 (decision D-SAB, design section 9.4): the view's
|
|
94
|
+
* buffer is an `ArrayBuffer` that is neither a `SharedArrayBuffer` nor resizable, so its bytes are a
|
|
95
|
+
* `BufferSource` for `GPUQueue.writeBuffer`, transferable, and of fixed length for the life of the
|
|
96
|
+
* snapshot (invariant I17).
|
|
97
|
+
* @param view - any ArrayBufferView
|
|
98
|
+
* @returns true when the buffer is a plain, fixed-length ArrayBuffer
|
|
99
|
+
*/
|
|
100
|
+
export declare function isOverPlainBuffer(view: ArrayBufferView): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* The u8 adoption predicate of design section 5.7: "a zero-copy padded Uint32Array view is
|
|
103
|
+
* constructible", i.e. `byteOffset % 4 === 0 && byteOffset + roundUp(byteLength, 4) <=
|
|
104
|
+
* buffer.byteLength`.
|
|
105
|
+
* @param data - the u8 array a column would adopt
|
|
106
|
+
* @returns true when paddedU32View(data) can be built without copying
|
|
107
|
+
*/
|
|
108
|
+
export declare function canViewAsPaddedU32(data: U8): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* The zero-copy Uint32Array of ceil(byteLength / 4) words over a u8 array's own byte range (design
|
|
111
|
+
* sections 5.7 and 10.2); the trailing lanes of the last word are whatever the buffer holds there.
|
|
112
|
+
* @param data - a u8 array satisfying canViewAsPaddedU32()
|
|
113
|
+
* @returns the padded u32 view; E_COLUMN_ALIGNMENT when the view is not constructible
|
|
114
|
+
*/
|
|
115
|
+
export declare function paddedU32View(data: U8): U32;
|
|
116
|
+
/**
|
|
117
|
+
* Copy a u8 array into a fresh store over which the padded u32 view is constructible: a new
|
|
118
|
+
* ArrayBuffer of roundUp(length, 4) bytes viewed at offset 0 with the original length (design section
|
|
119
|
+
* 5.7, the `adopt: "copy"` path). The padding bytes are zero.
|
|
120
|
+
* @param data - the u8 array to copy
|
|
121
|
+
* @returns a new U8 of the same length whose store satisfies canViewAsPaddedU32()
|
|
122
|
+
*/
|
|
123
|
+
export declare function copyToPaddedStore(data: U8): U8;
|
|
124
|
+
/**
|
|
125
|
+
* The dtypes whose storage is one flat typed array: the five numeric dtypes plus bool (packed u32
|
|
126
|
+
* words) and dict (u32 codes). string, list and json have offsets, children or JS values instead.
|
|
127
|
+
*/
|
|
128
|
+
export type TypedDtype = Exclude<Dtype, "string" | "list" | "json">;
|
|
129
|
+
/**
|
|
130
|
+
* A typed-array class as the helpers use it: BYTES_PER_ELEMENT plus the (buffer, byteOffset, length)
|
|
131
|
+
* constructor. Every concrete typed-array constructor satisfies it with T fixed to its
|
|
132
|
+
* ArrayBuffer-parameterised instance type.
|
|
133
|
+
*/
|
|
134
|
+
export interface TypedArrayCtor<T extends TypedArrayData> {
|
|
135
|
+
/** Bytes per element. */
|
|
136
|
+
readonly BYTES_PER_ELEMENT: number;
|
|
137
|
+
/**
|
|
138
|
+
* Construct a view of `length` elements over `buffer` starting at `byteOffset`.
|
|
139
|
+
* @param buffer - the backing buffer
|
|
140
|
+
* @param byteOffset - the start of the view in bytes
|
|
141
|
+
* @param length - the element count of the view
|
|
142
|
+
*/
|
|
143
|
+
new (buffer: ArrayBuffer, byteOffset: number, length: number): T;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Throw E_UNSUPPORTED for a dtype value outside the union; the `default` branch of every dtype switch
|
|
147
|
+
* (design section 13.4) calls this so an unknown dtype coming from untrusted data fails loudly. Always
|
|
148
|
+
* throws.
|
|
149
|
+
* @param dtype - the value that reached the default branch
|
|
150
|
+
*/
|
|
151
|
+
export declare function unsupportedDtype(dtype: never): never;
|
|
152
|
+
/**
|
|
153
|
+
* The typed-array class that stores a flat dtype (design section 5.1): Float32Array for f32,
|
|
154
|
+
* Float64Array for f64, Int32Array for i32, Uint8Array for u8, and Uint32Array for u32, for the packed
|
|
155
|
+
* words of bool and for the codes of dict.
|
|
156
|
+
* @param dtype - a flat dtype
|
|
157
|
+
* @returns the constructor; E_UNSUPPORTED for an unknown dtype
|
|
158
|
+
*/
|
|
159
|
+
export declare function typedArrayCtorOf(dtype: TypedDtype): TypedArrayCtor<TypedArrayData>;
|
|
160
|
+
/**
|
|
161
|
+
* The next staging capacity, in elements, that holds at least `needed`: doubling from `current`,
|
|
162
|
+
* rounded up to STAGING_ELEMENT_GRANULE (design section 6.2). A capacity of 0 grows to the granule.
|
|
163
|
+
* @param current - the present capacity in elements
|
|
164
|
+
* @param needed - the minimum capacity required
|
|
165
|
+
* @returns the new capacity, >= needed, >= 2 * current, a multiple of 16
|
|
166
|
+
*/
|
|
167
|
+
export declare function growCapacity(current: number, needed: number): number;
|
|
168
|
+
/**
|
|
169
|
+
* The byte length of a staging backing buffer for `capacity` elements of `bytesPerElement` bytes each:
|
|
170
|
+
* rounded up to STAGING_BYTE_GRANULE (design section 6.2). Because every element size divides 64 the
|
|
171
|
+
* result is always a whole number of elements.
|
|
172
|
+
* @param capacity - the capacity in elements
|
|
173
|
+
* @param bytesPerElement - the element size in bytes (1, 4 or 8)
|
|
174
|
+
* @returns the buffer byte length, a multiple of 64
|
|
175
|
+
*/
|
|
176
|
+
export declare function stagingByteLength(capacity: number, bytesPerElement: number): number;
|
|
177
|
+
/**
|
|
178
|
+
* Allocate a staging buffer of `byteLength` bytes. With `resizable` true the buffer is created with a
|
|
179
|
+
* `maxByteLength` of at least `reserveBytes` (and at least `byteLength`) so it can later grow in place;
|
|
180
|
+
* should the engine refuse that reservation with a RangeError (an address-space limit, not a missing
|
|
181
|
+
* capability) the buffer is created resizable with `maxByteLength === byteLength`, which simply means
|
|
182
|
+
* its next growth reallocates. With `resizable` false a plain fixed-length buffer is returned.
|
|
183
|
+
* @param byteLength - the initial byte length
|
|
184
|
+
* @param resizable - whether to create a resizable buffer; defaults to HAS_RESIZABLE_ARRAY_BUFFER
|
|
185
|
+
* @param reserveBytes - the address space to reserve for in-place growth; defaults to STAGING_RESERVE_BYTES
|
|
186
|
+
* @returns the new buffer
|
|
187
|
+
*/
|
|
188
|
+
export declare function allocateStagingBuffer(byteLength: number, resizable?: boolean, reserveBytes?: number): ArrayBuffer;
|
|
189
|
+
/**
|
|
190
|
+
* Grow a staging array so it holds at least `minLength` elements, preserving its contents (design
|
|
191
|
+
* section 6.2). When the array is the leading view of a resizable buffer with room left, the buffer is
|
|
192
|
+
* resized in place and no bytes move; otherwise a new buffer is allocated (resizable per `resizable`,
|
|
193
|
+
* with a reservation of at least twice the old one so repeated overflow stays amortised) and the
|
|
194
|
+
* contents copied. Either way the returned array is a fresh view object of exactly the new capacity;
|
|
195
|
+
* the caller replaces its reference. Elements beyond the old length are zero on the copy path and on a
|
|
196
|
+
* freshly resized region.
|
|
197
|
+
* @param array - the current staging array, viewed from byteOffset 0 of its buffer
|
|
198
|
+
* @param ctor - the array's constructor
|
|
199
|
+
* @param minLength - the minimum element count required
|
|
200
|
+
* @param resizable - whether new buffers are resizable; defaults to HAS_RESIZABLE_ARRAY_BUFFER
|
|
201
|
+
* @returns a view of growCapacity(array.length, minLength) elements holding the old contents
|
|
202
|
+
*/
|
|
203
|
+
export declare function growTypedArray<T extends TypedArrayData>(array: T, ctor: TypedArrayCtor<T>, minLength: number, resizable?: boolean): T;
|
|
204
|
+
export {};
|
|
205
|
+
//# sourceMappingURL=typed-array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-array.d.ts","sourceRoot":"","sources":["../../../src/util/typed-array.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level typed-array helpers shared by every module of @graphty/graph-format (design sections 5.7,
|
|
3
|
+
* 6.2, 9.5, 10.2 and 10.3): rounding and alignment arithmetic, arena segment layout, the 4-byte
|
|
4
|
+
* padding rules of I10, the u8 adoption predicate, the wire buffer-range check, per-dtype
|
|
5
|
+
* typed-array constructors, and the growth primitive of the builder staging (doubling into a
|
|
6
|
+
* resizable ArrayBuffer when the engine has one, allocate-and-copy doubling otherwise).
|
|
7
|
+
*
|
|
8
|
+
* Nothing here knows about graphs; everything is arithmetic over byte lengths and typed arrays.
|
|
9
|
+
*/
|
|
10
|
+
import { ALIGNMENT } from "../constants.js";
|
|
11
|
+
import { GraphFormatError } from "../errors.js";
|
|
12
|
+
// ============================================================ resizable ArrayBuffer detection
|
|
13
|
+
/**
|
|
14
|
+
* Probe once whether this engine supports resizable ArrayBuffer (ES2024: Node 20+, Chrome 111+,
|
|
15
|
+
* Safari 16.4+, Firefox 128+). The probe constructs a tiny resizable buffer and grows it; any throw or
|
|
16
|
+
* missing member means "not supported", in which case staging grows by allocate-and-copy (design
|
|
17
|
+
* section 6.2).
|
|
18
|
+
* @returns true when `new ArrayBuffer(n, { maxByteLength })` and `resize()` work
|
|
19
|
+
*/
|
|
20
|
+
function detectResizableArrayBuffer() {
|
|
21
|
+
try {
|
|
22
|
+
const probe = new ArrayBuffer(0, { maxByteLength: 64 });
|
|
23
|
+
if (!probe.resizable || typeof probe.resize !== "function") {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
probe.resize(64);
|
|
27
|
+
return probe.byteLength === 64 && probe.maxByteLength === 64;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Whether resizable ArrayBuffer is available, detected once at module load (design section 6.2). The
|
|
35
|
+
* growth helpers take it as their default; tests pass an explicit value to exercise both paths.
|
|
36
|
+
*/
|
|
37
|
+
export const HAS_RESIZABLE_ARRAY_BUFFER = detectResizableArrayBuffer();
|
|
38
|
+
// ============================================================ staging growth constants
|
|
39
|
+
/** Staging capacities are rounded up to this many elements (design section 6.2). */
|
|
40
|
+
export const STAGING_ELEMENT_GRANULE = 16;
|
|
41
|
+
/** Staging backing buffers are a multiple of this many bytes (design section 6.2). */
|
|
42
|
+
export const STAGING_BYTE_GRANULE = 64;
|
|
43
|
+
/**
|
|
44
|
+
* Virtual address space reserved (`maxByteLength`) for a fresh resizable staging buffer: 256 MiB, so
|
|
45
|
+
* a staging array grows in place without copying up to 64M u32 elements. Reservations are
|
|
46
|
+
* address-space only (pages are committed as the buffer grows), and a buffer that outgrows its
|
|
47
|
+
* reservation is reallocated with a doubled one, so the constant bounds the number of copies rather
|
|
48
|
+
* than the size of anything.
|
|
49
|
+
*/
|
|
50
|
+
export const STAGING_RESERVE_BYTES = 256 * 1024 * 1024;
|
|
51
|
+
// ============================================================ rounding and alignment
|
|
52
|
+
/**
|
|
53
|
+
* Round `value` up to the next multiple of `multiple`. Written with `%`, not bit masks, because arc
|
|
54
|
+
* counts and byte lengths exceed 2^31 (invariant I3, design section 10.6).
|
|
55
|
+
* @param value - a non-negative integer
|
|
56
|
+
* @param multiple - a positive integer
|
|
57
|
+
* @returns the smallest multiple of `multiple` that is >= value
|
|
58
|
+
*/
|
|
59
|
+
export function roundUp(value, multiple) {
|
|
60
|
+
const remainder = value % multiple;
|
|
61
|
+
return remainder === 0 ? value : value + multiple - remainder;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Pad a byte length to the next multiple of 4: the size of the padded u32 view of a u8 column and
|
|
65
|
+
* the rule every GPU-bound array satisfies (design sections 5.7 and 10.2).
|
|
66
|
+
* @param byteLength - a non-negative byte count
|
|
67
|
+
* @returns roundUp(byteLength, 4)
|
|
68
|
+
*/
|
|
69
|
+
export function padTo4(byteLength) {
|
|
70
|
+
return roundUp(byteLength, 4);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The number of u32 words that span a byte range: ceil(byteLength / 4) (design section 10.2).
|
|
74
|
+
* @param byteLength - a non-negative byte count
|
|
75
|
+
* @returns the word count of the padded u32 view
|
|
76
|
+
*/
|
|
77
|
+
export function paddedWordCount(byteLength) {
|
|
78
|
+
return Math.ceil(byteLength / 4);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Align a byte offset up to the next arena segment boundary (design section 10.3; 256 bytes, the
|
|
82
|
+
* WebGPU minStorageBufferOffsetAlignment default).
|
|
83
|
+
* @param byteOffset - a non-negative byte offset
|
|
84
|
+
* @param alignment - the alignment in bytes; defaults to ALIGNMENT (256)
|
|
85
|
+
* @returns roundUp(byteOffset, alignment)
|
|
86
|
+
*/
|
|
87
|
+
export function alignUp(byteOffset, alignment = ALIGNMENT) {
|
|
88
|
+
return roundUp(byteOffset, alignment);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Lay out segments back to back, each non-empty one starting at a multiple of `alignment`, in the
|
|
92
|
+
* given order (design section 10.3: hot to cold). Zero-length segments get a null offset and occupy
|
|
93
|
+
* nothing, which is how an absent `weights`, a zero-arc `colIdx` and an identity permutation stay out
|
|
94
|
+
* of the arena. For the worked example of section 10.3 (400,004 / 8,000,000 / 8,000,000 / 8,000,000 /
|
|
95
|
+
* 4,000,000) the offsets are 0 / 400,128 / 8,400,128 / 16,400,128 / 24,400,128 and the total is
|
|
96
|
+
* 28,400,128 with 124 bytes of padding.
|
|
97
|
+
* @param byteLengths - the unpadded byte length of every segment in arena order (0 = absent)
|
|
98
|
+
* @param alignment - the segment alignment in bytes; defaults to ALIGNMENT (256)
|
|
99
|
+
* @returns the offsets, ends, total byte length and padding of the layout
|
|
100
|
+
*/
|
|
101
|
+
export function layoutSegments(byteLengths, alignment = ALIGNMENT) {
|
|
102
|
+
const offsets = [];
|
|
103
|
+
const ends = [];
|
|
104
|
+
let cursor = 0;
|
|
105
|
+
let padding = 0;
|
|
106
|
+
for (const byteLength of byteLengths) {
|
|
107
|
+
if (byteLength === 0) {
|
|
108
|
+
offsets.push(null);
|
|
109
|
+
ends.push(null);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const offset = alignUp(cursor, alignment);
|
|
113
|
+
padding += offset - cursor;
|
|
114
|
+
offsets.push(offset);
|
|
115
|
+
cursor = offset + byteLength;
|
|
116
|
+
ends.push(cursor);
|
|
117
|
+
}
|
|
118
|
+
return { offsets, ends, byteLength: cursor, padding };
|
|
119
|
+
}
|
|
120
|
+
// ============================================================ 4-byte rules and adoption (I10, 5.7)
|
|
121
|
+
/**
|
|
122
|
+
* The I10 predicate for a GPU-bound array: a view whose byteOffset and byteLength are both multiples
|
|
123
|
+
* of 4 (design section 10.2).
|
|
124
|
+
* @param view - any ArrayBufferView
|
|
125
|
+
* @returns true when both byteOffset and byteLength are multiples of 4
|
|
126
|
+
*/
|
|
127
|
+
export function isFourByteAligned(view) {
|
|
128
|
+
return view.byteOffset % 4 === 0 && view.byteLength % 4 === 0;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The "plain ArrayBuffer" half of invariant I10 (decision D-SAB, design section 9.4): the view's
|
|
132
|
+
* buffer is an `ArrayBuffer` that is neither a `SharedArrayBuffer` nor resizable, so its bytes are a
|
|
133
|
+
* `BufferSource` for `GPUQueue.writeBuffer`, transferable, and of fixed length for the life of the
|
|
134
|
+
* snapshot (invariant I17).
|
|
135
|
+
* @param view - any ArrayBufferView
|
|
136
|
+
* @returns true when the buffer is a plain, fixed-length ArrayBuffer
|
|
137
|
+
*/
|
|
138
|
+
export function isOverPlainBuffer(view) {
|
|
139
|
+
const { buffer } = view;
|
|
140
|
+
return buffer instanceof ArrayBuffer && !buffer.resizable;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The u8 adoption predicate of design section 5.7: "a zero-copy padded Uint32Array view is
|
|
144
|
+
* constructible", i.e. `byteOffset % 4 === 0 && byteOffset + roundUp(byteLength, 4) <=
|
|
145
|
+
* buffer.byteLength`.
|
|
146
|
+
* @param data - the u8 array a column would adopt
|
|
147
|
+
* @returns true when paddedU32View(data) can be built without copying
|
|
148
|
+
*/
|
|
149
|
+
export function canViewAsPaddedU32(data) {
|
|
150
|
+
return data.byteOffset % 4 === 0 && data.byteOffset + padTo4(data.byteLength) <= data.buffer.byteLength;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The zero-copy Uint32Array of ceil(byteLength / 4) words over a u8 array's own byte range (design
|
|
154
|
+
* sections 5.7 and 10.2); the trailing lanes of the last word are whatever the buffer holds there.
|
|
155
|
+
* @param data - a u8 array satisfying canViewAsPaddedU32()
|
|
156
|
+
* @returns the padded u32 view; E_COLUMN_ALIGNMENT when the view is not constructible
|
|
157
|
+
*/
|
|
158
|
+
export function paddedU32View(data) {
|
|
159
|
+
if (!canViewAsPaddedU32(data)) {
|
|
160
|
+
throw new GraphFormatError("E_COLUMN_ALIGNMENT", `u8 array at byteOffset ${data.byteOffset} with byteLength ${data.byteLength} has no zero-copy padded u32 view`, { byteOffset: data.byteOffset, byteLength: data.byteLength, bufferByteLength: data.buffer.byteLength });
|
|
161
|
+
}
|
|
162
|
+
return new Uint32Array(data.buffer, data.byteOffset, paddedWordCount(data.byteLength));
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Copy a u8 array into a fresh store over which the padded u32 view is constructible: a new
|
|
166
|
+
* ArrayBuffer of roundUp(length, 4) bytes viewed at offset 0 with the original length (design section
|
|
167
|
+
* 5.7, the `adopt: "copy"` path). The padding bytes are zero.
|
|
168
|
+
* @param data - the u8 array to copy
|
|
169
|
+
* @returns a new U8 of the same length whose store satisfies canViewAsPaddedU32()
|
|
170
|
+
*/
|
|
171
|
+
export function copyToPaddedStore(data) {
|
|
172
|
+
const store = new Uint8Array(new ArrayBuffer(padTo4(data.byteLength)), 0, data.byteLength);
|
|
173
|
+
store.set(data);
|
|
174
|
+
return store;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Throw E_UNSUPPORTED for a dtype value outside the union; the `default` branch of every dtype switch
|
|
178
|
+
* (design section 13.4) calls this so an unknown dtype coming from untrusted data fails loudly. Always
|
|
179
|
+
* throws.
|
|
180
|
+
* @param dtype - the value that reached the default branch
|
|
181
|
+
*/
|
|
182
|
+
export function unsupportedDtype(dtype) {
|
|
183
|
+
throw new GraphFormatError("E_UNSUPPORTED", `unsupported dtype ${String(dtype)}`, { dtype });
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The typed-array class that stores a flat dtype (design section 5.1): Float32Array for f32,
|
|
187
|
+
* Float64Array for f64, Int32Array for i32, Uint8Array for u8, and Uint32Array for u32, for the packed
|
|
188
|
+
* words of bool and for the codes of dict.
|
|
189
|
+
* @param dtype - a flat dtype
|
|
190
|
+
* @returns the constructor; E_UNSUPPORTED for an unknown dtype
|
|
191
|
+
*/
|
|
192
|
+
export function typedArrayCtorOf(dtype) {
|
|
193
|
+
switch (dtype) {
|
|
194
|
+
case "f32":
|
|
195
|
+
return Float32Array;
|
|
196
|
+
case "f64":
|
|
197
|
+
return Float64Array;
|
|
198
|
+
case "i32":
|
|
199
|
+
return Int32Array;
|
|
200
|
+
case "u8":
|
|
201
|
+
return Uint8Array;
|
|
202
|
+
case "u32":
|
|
203
|
+
case "bool":
|
|
204
|
+
case "dict":
|
|
205
|
+
return Uint32Array;
|
|
206
|
+
default:
|
|
207
|
+
return unsupportedDtype(dtype);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// ============================================================ staging growth
|
|
211
|
+
/**
|
|
212
|
+
* The next staging capacity, in elements, that holds at least `needed`: doubling from `current`,
|
|
213
|
+
* rounded up to STAGING_ELEMENT_GRANULE (design section 6.2). A capacity of 0 grows to the granule.
|
|
214
|
+
* @param current - the present capacity in elements
|
|
215
|
+
* @param needed - the minimum capacity required
|
|
216
|
+
* @returns the new capacity, >= needed, >= 2 * current, a multiple of 16
|
|
217
|
+
*/
|
|
218
|
+
export function growCapacity(current, needed) {
|
|
219
|
+
return roundUp(Math.max(needed, current * 2, STAGING_ELEMENT_GRANULE), STAGING_ELEMENT_GRANULE);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* The byte length of a staging backing buffer for `capacity` elements of `bytesPerElement` bytes each:
|
|
223
|
+
* rounded up to STAGING_BYTE_GRANULE (design section 6.2). Because every element size divides 64 the
|
|
224
|
+
* result is always a whole number of elements.
|
|
225
|
+
* @param capacity - the capacity in elements
|
|
226
|
+
* @param bytesPerElement - the element size in bytes (1, 4 or 8)
|
|
227
|
+
* @returns the buffer byte length, a multiple of 64
|
|
228
|
+
*/
|
|
229
|
+
export function stagingByteLength(capacity, bytesPerElement) {
|
|
230
|
+
return roundUp(capacity * bytesPerElement, STAGING_BYTE_GRANULE);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Allocate a staging buffer of `byteLength` bytes. With `resizable` true the buffer is created with a
|
|
234
|
+
* `maxByteLength` of at least `reserveBytes` (and at least `byteLength`) so it can later grow in place;
|
|
235
|
+
* should the engine refuse that reservation with a RangeError (an address-space limit, not a missing
|
|
236
|
+
* capability) the buffer is created resizable with `maxByteLength === byteLength`, which simply means
|
|
237
|
+
* its next growth reallocates. With `resizable` false a plain fixed-length buffer is returned.
|
|
238
|
+
* @param byteLength - the initial byte length
|
|
239
|
+
* @param resizable - whether to create a resizable buffer; defaults to HAS_RESIZABLE_ARRAY_BUFFER
|
|
240
|
+
* @param reserveBytes - the address space to reserve for in-place growth; defaults to STAGING_RESERVE_BYTES
|
|
241
|
+
* @returns the new buffer
|
|
242
|
+
*/
|
|
243
|
+
export function allocateStagingBuffer(byteLength, resizable = HAS_RESIZABLE_ARRAY_BUFFER, reserveBytes = STAGING_RESERVE_BYTES) {
|
|
244
|
+
if (!resizable) {
|
|
245
|
+
return new ArrayBuffer(byteLength);
|
|
246
|
+
}
|
|
247
|
+
const maxByteLength = Math.max(byteLength, reserveBytes);
|
|
248
|
+
try {
|
|
249
|
+
return new ArrayBuffer(byteLength, { maxByteLength });
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
if (err instanceof RangeError && maxByteLength > byteLength) {
|
|
253
|
+
return new ArrayBuffer(byteLength, { maxByteLength: byteLength });
|
|
254
|
+
}
|
|
255
|
+
throw err;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Grow a staging array so it holds at least `minLength` elements, preserving its contents (design
|
|
260
|
+
* section 6.2). When the array is the leading view of a resizable buffer with room left, the buffer is
|
|
261
|
+
* resized in place and no bytes move; otherwise a new buffer is allocated (resizable per `resizable`,
|
|
262
|
+
* with a reservation of at least twice the old one so repeated overflow stays amortised) and the
|
|
263
|
+
* contents copied. Either way the returned array is a fresh view object of exactly the new capacity;
|
|
264
|
+
* the caller replaces its reference. Elements beyond the old length are zero on the copy path and on a
|
|
265
|
+
* freshly resized region.
|
|
266
|
+
* @param array - the current staging array, viewed from byteOffset 0 of its buffer
|
|
267
|
+
* @param ctor - the array's constructor
|
|
268
|
+
* @param minLength - the minimum element count required
|
|
269
|
+
* @param resizable - whether new buffers are resizable; defaults to HAS_RESIZABLE_ARRAY_BUFFER
|
|
270
|
+
* @returns a view of growCapacity(array.length, minLength) elements holding the old contents
|
|
271
|
+
*/
|
|
272
|
+
export function growTypedArray(array, ctor, minLength, resizable = HAS_RESIZABLE_ARRAY_BUFFER) {
|
|
273
|
+
if (minLength <= array.length) {
|
|
274
|
+
return array;
|
|
275
|
+
}
|
|
276
|
+
const bytesPerElement = ctor.BYTES_PER_ELEMENT;
|
|
277
|
+
const byteLength = stagingByteLength(growCapacity(array.length, minLength), bytesPerElement);
|
|
278
|
+
const capacity = byteLength / bytesPerElement;
|
|
279
|
+
const { buffer } = array;
|
|
280
|
+
if (buffer.resizable && array.byteOffset === 0 && byteLength <= buffer.maxByteLength) {
|
|
281
|
+
buffer.resize(byteLength);
|
|
282
|
+
return new ctor(buffer, 0, capacity);
|
|
283
|
+
}
|
|
284
|
+
const reserve = Math.max(buffer.maxByteLength * 2, STAGING_RESERVE_BYTES);
|
|
285
|
+
const next = new ctor(allocateStagingBuffer(byteLength, resizable, reserve), 0, capacity);
|
|
286
|
+
next.set(array);
|
|
287
|
+
return next;
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=typed-array.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-array.js","sourceRoot":"","sources":["../../../src/util/typed-array.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GSNP byte container (design section 9.2): `toBytes()` writes one contiguous buffer,
|
|
3
|
+
* `toByteChunks()` the same bytes as a sequence (header + manifest, then every 256-padded segment
|
|
4
|
+
* in manifest order), `fromBytes()` adopts a container's buffer region as the arena and
|
|
5
|
+
* `fromByteChunks()` adopts each chunk's buffer per segment. The snapshot's `toBytes` /
|
|
6
|
+
* `toByteChunks` methods call the functions of this module directly.
|
|
7
|
+
*
|
|
8
|
+
* Layout, all integers little-endian:
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* offset size field
|
|
12
|
+
* 0 4 magic "GSNP"
|
|
13
|
+
* 4 2 wire major (u16)
|
|
14
|
+
* 6 2 wire minor (u16)
|
|
15
|
+
* 8 4 endianness probe: 0x01020304 written through a host-order Uint32Array
|
|
16
|
+
* 12 4 manifest byte length L (u32)
|
|
17
|
+
* 16 L manifest: UTF-8 JSON of the WireManifest, every reference into buffer 0 with a
|
|
18
|
+
* region-relative byteOffset
|
|
19
|
+
* 16+L pad zero padding to the next multiple of 256
|
|
20
|
+
* B ... buffer region: each array at a 256-aligned offset in manifest order, core arrays
|
|
21
|
+
* first so the region's prefix is the arena; every segment padded to 256 bytes
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* The reader refuses a bad magic, an unexpected probe, a truncated header or manifest, a manifest
|
|
25
|
+
* whose versions disagree with the header (E_BAD_SERIALIZATION), an unknown wire major
|
|
26
|
+
* (E_UNSUPPORTED_VERSION) and everything the manifest reader of from-wire.ts refuses.
|
|
27
|
+
*/
|
|
28
|
+
import { type GraphSnapshot } from "../snapshot/graph-snapshot.js";
|
|
29
|
+
import { type FromWireOptions, type ToBytesOptions, type U8 } from "../types/index.js";
|
|
30
|
+
/** Bytes before the manifest: magic, major, minor, probe and manifest length. */
|
|
31
|
+
export declare const CONTAINER_HEADER_BYTES = 16;
|
|
32
|
+
/**
|
|
33
|
+
* The GSNP container of a snapshot as one contiguous buffer (design section 9.2).
|
|
34
|
+
* @param snapshot - the snapshot
|
|
35
|
+
* @param options - the cached views to carry
|
|
36
|
+
* @returns the container bytes at offset 0 of a fresh ArrayBuffer; E_UNSUPPORTED on a big-endian host
|
|
37
|
+
*/
|
|
38
|
+
export declare function toBytes(snapshot: GraphSnapshot, options?: ToBytesOptions): U8;
|
|
39
|
+
/**
|
|
40
|
+
* The GSNP container as a sequence of chunks whose concatenation equals `toBytes()` (design section
|
|
41
|
+
* 9.2): the header + manifest padded to 256, then each non-empty segment padded to 256, in manifest
|
|
42
|
+
* order. The layout is computed when this function is called; the chunk copies are made lazily.
|
|
43
|
+
* @param snapshot - the snapshot
|
|
44
|
+
* @param options - the cached views to carry
|
|
45
|
+
* @returns the chunks; E_UNSUPPORTED on a big-endian host
|
|
46
|
+
*/
|
|
47
|
+
export declare function toByteChunks(snapshot: GraphSnapshot, options?: ToBytesOptions): Iterable<U8>;
|
|
48
|
+
/**
|
|
49
|
+
* Rebuild a snapshot from a GSNP container (design section 9.2). Defaults: `validate: "full"` and
|
|
50
|
+
* `copy: false`. The buffer region is adopted as the arena when the container is a plain
|
|
51
|
+
* ArrayBuffer viewed at a byteOffset that is a multiple of 8 (so f64 segments align); a
|
|
52
|
+
* SharedArrayBuffer, an odd offset or `copy: true` take the copy path into a fresh 256-aligned
|
|
53
|
+
* buffer.
|
|
54
|
+
* @param bytes - the container: a Uint8Array, an ArrayBuffer or a SharedArrayBuffer
|
|
55
|
+
* @param options - validation level, copy and unknown-column policy
|
|
56
|
+
* @returns the snapshot; E_BAD_SERIALIZATION / E_UNSUPPORTED_VERSION / E_UNSUPPORTED / E_INVALID_SNAPSHOT on bad input
|
|
57
|
+
*/
|
|
58
|
+
export declare function fromBytes(bytes: Uint8Array | ArrayBufferLike, options?: FromWireOptions): GraphSnapshot;
|
|
59
|
+
/**
|
|
60
|
+
* Rebuild a snapshot from the chunks `toByteChunks()` produced (or any split of a container's
|
|
61
|
+
* bytes): each segment is adopted as a view into the chunk that holds it (a segment spanning two
|
|
62
|
+
* chunks, or one in a SharedArrayBuffer, is copied) and the snapshot has `arena === null` (design
|
|
63
|
+
* section 9.2). Defaults: `validate: "full"`, `copy: false`.
|
|
64
|
+
* @param chunks - the chunks in order
|
|
65
|
+
* @param options - validation level, copy and unknown-column policy
|
|
66
|
+
* @returns the snapshot
|
|
67
|
+
*/
|
|
68
|
+
export declare function fromByteChunks(chunks: Iterable<Uint8Array>, options?: FromWireOptions): GraphSnapshot;
|
|
69
|
+
//# sourceMappingURL=bytes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../../src/wire/bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAuB,KAAK,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAiB5G,iFAAiF;AACjF,eAAO,MAAM,sBAAsB,KAAK,CAAC;AA2DzC;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,GAAE,cAAmB,GAAG,EAAE,CASjF;AAuBD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,GAAE,cAAmB,GAAG,QAAQ,CAAC,EAAE,CAAC,CAEhG;AAuGD;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,aAAa,CAsBvG;AA6HD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,aAAa,CAcrG"}
|