@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,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The enum vocabularies of the builder options (design section 12.2) shared by the constructor and
|
|
3
|
+
* the per-freeze overrides, so a value outside its set is refused the same way on every path
|
|
4
|
+
* (E_UNSUPPORTED, never a silent substitute).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { type GraphFormatError } from "../errors.js";
|
|
8
|
+
import { type DuplicatePolicy } from "../types/index.js";
|
|
9
|
+
|
|
10
|
+
/** The DuplicatePolicy members. */
|
|
11
|
+
const DUPLICATE_POLICIES: ReadonlySet<string> = new Set(["keep", "error", "first", "last", "sum", "min", "max"]);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check a duplicateEdges value.
|
|
15
|
+
* @param field - the option name for the error
|
|
16
|
+
* @param value - the value
|
|
17
|
+
* @param error - builds the error for an unsupported value
|
|
18
|
+
* @returns the value as a DuplicatePolicy
|
|
19
|
+
*/
|
|
20
|
+
export function assertDuplicatePolicy(
|
|
21
|
+
field: string,
|
|
22
|
+
value: unknown,
|
|
23
|
+
error: (field: string, found: unknown) => GraphFormatError,
|
|
24
|
+
): DuplicatePolicy {
|
|
25
|
+
if (typeof value !== "string" || !DUPLICATE_POLICIES.has(value)) {
|
|
26
|
+
throw error(field, value);
|
|
27
|
+
}
|
|
28
|
+
return value as DuplicatePolicy;
|
|
29
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one packed-bitmap layout of @graphty/graph-format (design sections 5.1, 5.3 and 7.4, decision
|
|
3
|
+
* C13): Uint32Array words, LSB-first, ceil(bits / 32) words, bit i of the bitmap at
|
|
4
|
+
* `(words[i >>> 5] >>> (i & 31)) & 1`. Validity bitmaps, bool column data, NodeMask / EdgeMask and
|
|
5
|
+
* the builder's alive / weightSet bitmaps all use these helpers, so a kernel reads every one of them
|
|
6
|
+
* with the same expression and the layout is bit-for-bit Arrow's on a little-endian host.
|
|
7
|
+
*
|
|
8
|
+
* Convention: a bitmap over `bits` bits keeps every bit at position >= bits CLEAR. Every constructor
|
|
9
|
+
* and mutator here maintains that, so word-level counts, ANDs and ORs stay exact without a length
|
|
10
|
+
* argument; callers that write words directly call bitmapClearTrailing() afterwards. Bit indices are
|
|
11
|
+
* plain numbers below 2^32 (invariant I3), so `>>> 5` and `& 31` are safe on them; word indices are
|
|
12
|
+
* multiplied, never shifted, because a word index can exceed 2^26.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { type U32 } from "../types/index.js";
|
|
16
|
+
|
|
17
|
+
/** Every bit set: the fill word of an all-true bitmap. */
|
|
18
|
+
const ALL_ONES = 0xffffffff;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The number of words a bitmap over `bits` bits needs: ceil(bits / 32). Computed with a division, not
|
|
22
|
+
* `(bits + 31) >>> 5`, because bits may be as large as MAX_COUNT and the addition would wrap.
|
|
23
|
+
* @param bits - the bit count, >= 0
|
|
24
|
+
* @returns ceil(bits / 32)
|
|
25
|
+
*/
|
|
26
|
+
export function bitmapWordCount(bits: number): number {
|
|
27
|
+
return Math.ceil(bits / 32);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The mask of the bits of the last word that lie below `bits`: all ones when bits is a multiple of
|
|
32
|
+
* 32, otherwise the low `bits % 32` bits. Computed with an unsigned shift so the result is a
|
|
33
|
+
* non-negative number even when 31 bits are kept (`(1 << 31) - 1` is not an int32).
|
|
34
|
+
* @param bits - the bit count
|
|
35
|
+
* @returns the mask as an unsigned 32-bit value
|
|
36
|
+
*/
|
|
37
|
+
function lastWordMask(bits: number): number {
|
|
38
|
+
const remainder = bits % 32;
|
|
39
|
+
return remainder === 0 ? ALL_ONES : ALL_ONES >>> (32 - remainder);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Clear every bit at a position >= bits: the tail of the last word and every word beyond. Call it
|
|
44
|
+
* after writing words directly so the bitmap keeps the trailing-bits-clear convention.
|
|
45
|
+
* @param words - the bitmap words
|
|
46
|
+
* @param bits - the bit count the bitmap covers
|
|
47
|
+
*/
|
|
48
|
+
export function bitmapClearTrailing(words: U32, bits: number): void {
|
|
49
|
+
const wordCount = bitmapWordCount(bits);
|
|
50
|
+
if (wordCount > 0 && wordCount <= words.length && bits % 32 !== 0) {
|
|
51
|
+
words[wordCount - 1] &= lastWordMask(bits);
|
|
52
|
+
}
|
|
53
|
+
if (wordCount < words.length) {
|
|
54
|
+
words.fill(0, wordCount);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Allocate a bitmap over `bits` bits: ceil(bits / 32) words, every bit clear or, with `fill`, every
|
|
60
|
+
* bit below `bits` set (trailing bits clear).
|
|
61
|
+
* @param bits - the bit count, >= 0
|
|
62
|
+
* @param fill - the initial value of every bit; defaults to false
|
|
63
|
+
* @returns the new words
|
|
64
|
+
*/
|
|
65
|
+
export function makeBitmap(bits: number, fill = false): U32 {
|
|
66
|
+
const words = new Uint32Array(bitmapWordCount(bits));
|
|
67
|
+
if (fill) {
|
|
68
|
+
words.fill(ALL_ONES);
|
|
69
|
+
bitmapClearTrailing(words, bits);
|
|
70
|
+
}
|
|
71
|
+
return words;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Read bit i.
|
|
76
|
+
* @param words - the bitmap words
|
|
77
|
+
* @param i - the bit index, below the bitmap's bit count
|
|
78
|
+
* @returns true when the bit is set
|
|
79
|
+
*/
|
|
80
|
+
export function bitmapGet(words: U32, i: number): boolean {
|
|
81
|
+
return ((words[i >>> 5] >>> (i & 31)) & 1) === 1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Set bit i.
|
|
86
|
+
* @param words - the bitmap words
|
|
87
|
+
* @param i - the bit index, below the bitmap's bit count
|
|
88
|
+
*/
|
|
89
|
+
export function bitmapSet(words: U32, i: number): void {
|
|
90
|
+
words[i >>> 5] |= 1 << (i & 31);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Clear bit i.
|
|
95
|
+
* @param words - the bitmap words
|
|
96
|
+
* @param i - the bit index, below the bitmap's bit count
|
|
97
|
+
*/
|
|
98
|
+
export function bitmapClear(words: U32, i: number): void {
|
|
99
|
+
words[i >>> 5] &= ~(1 << (i & 31));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Write bit i.
|
|
104
|
+
* @param words - the bitmap words
|
|
105
|
+
* @param i - the bit index, below the bitmap's bit count
|
|
106
|
+
* @param value - the value to write
|
|
107
|
+
*/
|
|
108
|
+
export function bitmapWrite(words: U32, i: number, value: boolean): void {
|
|
109
|
+
if (value) {
|
|
110
|
+
bitmapSet(words, i);
|
|
111
|
+
} else {
|
|
112
|
+
bitmapClear(words, i);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The number of set bits in one 32-bit word (SWAR popcount; the multiply goes through Math.imul so
|
|
118
|
+
* it never leaves 32 bits).
|
|
119
|
+
* @param word - the word, read as an unsigned 32-bit value
|
|
120
|
+
* @returns the count, 0..32
|
|
121
|
+
*/
|
|
122
|
+
export function popcount32(word: number): number {
|
|
123
|
+
let w = word - ((word >>> 1) & 0x55555555);
|
|
124
|
+
w = (w & 0x33333333) + ((w >>> 2) & 0x33333333);
|
|
125
|
+
w = (w + (w >>> 4)) & 0x0f0f0f0f;
|
|
126
|
+
return Math.imul(w, 0x01010101) >>> 24;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The number of set bits below `bits`. Bits at or above `bits` are ignored, so the count is exact
|
|
131
|
+
* even for a bitmap whose trailing bits are dirty.
|
|
132
|
+
* @param words - the bitmap words, at least ceil(bits / 32) of them
|
|
133
|
+
* @param bits - the bit count to count over
|
|
134
|
+
* @returns the number of set bits in [0, bits)
|
|
135
|
+
*/
|
|
136
|
+
export function bitmapCount(words: U32, bits: number): number {
|
|
137
|
+
const fullWords = Math.floor(bits / 32);
|
|
138
|
+
let count = 0;
|
|
139
|
+
for (let k = 0; k < fullWords; k++) {
|
|
140
|
+
count += popcount32(words[k]);
|
|
141
|
+
}
|
|
142
|
+
if (bits % 32 !== 0) {
|
|
143
|
+
count += popcount32(words[fullWords] & lastWordMask(bits));
|
|
144
|
+
}
|
|
145
|
+
return count;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The indices of the set bits below `bits`, ascending, as a fresh U32 of exactly bitmapCount()
|
|
150
|
+
* entries (the maskToIndices of design section 7.4).
|
|
151
|
+
* @param words - the bitmap words
|
|
152
|
+
* @param bits - the bit count to collect over
|
|
153
|
+
* @returns the set bit indices
|
|
154
|
+
*/
|
|
155
|
+
export function bitmapToIndices(words: U32, bits: number): U32 {
|
|
156
|
+
const out = new Uint32Array(bitmapCount(words, bits));
|
|
157
|
+
let n = 0;
|
|
158
|
+
for (let i = 0; i < bits; i++) {
|
|
159
|
+
if (((words[i >>> 5] >>> (i & 31)) & 1) === 1) {
|
|
160
|
+
out[n++] = i;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The bits [start, end) of `words` as a fresh bitmap over end - start bits starting at bit 0 (the
|
|
168
|
+
* copy behind Column.slice() for bool data and validity, design section 5.7). A word-aligned start
|
|
169
|
+
* is a plain copy; any other start shifts across word boundaries.
|
|
170
|
+
* @param words - the source words
|
|
171
|
+
* @param start - the first bit to copy
|
|
172
|
+
* @param end - one past the last bit to copy
|
|
173
|
+
* @returns the new words, trailing bits clear
|
|
174
|
+
*/
|
|
175
|
+
export function bitmapSlice(words: U32, start: number, end: number): U32 {
|
|
176
|
+
const bits = Math.max(0, end - start);
|
|
177
|
+
const out = makeBitmap(bits);
|
|
178
|
+
if (bits === 0) {
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
const firstWord = start >>> 5;
|
|
182
|
+
const shift = start & 31;
|
|
183
|
+
if (shift === 0) {
|
|
184
|
+
out.set(words.subarray(firstWord, firstWord + out.length));
|
|
185
|
+
} else {
|
|
186
|
+
const upper = 32 - shift;
|
|
187
|
+
for (let j = 0; j < out.length; j++) {
|
|
188
|
+
const k = firstWord + j;
|
|
189
|
+
const lo = k < words.length ? words[k] >>> shift : 0;
|
|
190
|
+
const hi = k + 1 < words.length ? words[k + 1] << upper : 0;
|
|
191
|
+
out[j] = lo | hi;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
bitmapClearTrailing(out, bits);
|
|
195
|
+
return out;
|
|
196
|
+
}
|