distillate 0.1.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 +105 -0
- package/dist/blocked/index.cjs +116 -0
- package/dist/blocked/index.d.cts +29 -0
- package/dist/blocked/index.d.ts +29 -0
- package/dist/blocked/index.js +114 -0
- package/dist/bloom/index.cjs +132 -0
- package/dist/bloom/index.d.cts +24 -0
- package/dist/bloom/index.d.ts +24 -0
- package/dist/bloom/index.js +130 -0
- package/dist/bytes-DCuYtUVS.d.cts +4 -0
- package/dist/bytes-DCuYtUVS.d.ts +4 -0
- package/dist/fuse/index.cjs +298 -0
- package/dist/fuse/index.d.cts +35 -0
- package/dist/fuse/index.d.ts +35 -0
- package/dist/fuse/index.js +295 -0
- package/dist/index.cjs +5 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/serialize-C5rwVPvv.cjs +312 -0
- package/dist/serialize-E_4WyueA.js +271 -0
- package/package.json +114 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { i as hash128, n as readHeader, r as writeHeader, s as normalize, t as SerializationError } from "../serialize-E_4WyueA.js";
|
|
2
|
+
//#region src/fuse/fuse.ts
|
|
3
|
+
const ARITY = 3;
|
|
4
|
+
const TYPE_FUSE8 = 3;
|
|
5
|
+
const TYPE_FUSE16 = 4;
|
|
6
|
+
var BinaryFuseBuildError = class extends Error {
|
|
7
|
+
name = "BinaryFuseBuildError";
|
|
8
|
+
};
|
|
9
|
+
let RLO = 0;
|
|
10
|
+
let RHI = 0;
|
|
11
|
+
function mul64(alo, ahi, blo, bhi) {
|
|
12
|
+
const a0 = alo & 65535;
|
|
13
|
+
const a1 = alo >>> 16;
|
|
14
|
+
const a2 = ahi & 65535;
|
|
15
|
+
const a3 = ahi >>> 16;
|
|
16
|
+
const b0 = blo & 65535;
|
|
17
|
+
const b1 = blo >>> 16;
|
|
18
|
+
const b2 = bhi & 65535;
|
|
19
|
+
const b3 = bhi >>> 16;
|
|
20
|
+
let c0 = a0 * b0;
|
|
21
|
+
let c1 = c0 >>> 16;
|
|
22
|
+
c0 &= 65535;
|
|
23
|
+
c1 += a1 * b0;
|
|
24
|
+
let c2 = c1 >>> 16;
|
|
25
|
+
c1 &= 65535;
|
|
26
|
+
c1 += a0 * b1;
|
|
27
|
+
c2 += c1 >>> 16;
|
|
28
|
+
c1 &= 65535;
|
|
29
|
+
c2 += a2 * b0;
|
|
30
|
+
let c3 = c2 >>> 16;
|
|
31
|
+
c2 &= 65535;
|
|
32
|
+
c2 += a1 * b1;
|
|
33
|
+
c3 += c2 >>> 16;
|
|
34
|
+
c2 &= 65535;
|
|
35
|
+
c2 += a0 * b2;
|
|
36
|
+
c3 += c2 >>> 16;
|
|
37
|
+
c2 &= 65535;
|
|
38
|
+
c3 += a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3;
|
|
39
|
+
c3 &= 65535;
|
|
40
|
+
RLO = (c1 << 16 | c0) >>> 0;
|
|
41
|
+
RHI = (c3 << 16 | c2) >>> 0;
|
|
42
|
+
}
|
|
43
|
+
function fmix64(lo, hi) {
|
|
44
|
+
let l = (lo ^ hi >>> 1) >>> 0;
|
|
45
|
+
let h = hi;
|
|
46
|
+
mul64(l, h, 3981806797, 4283543511);
|
|
47
|
+
l = RLO;
|
|
48
|
+
h = RHI;
|
|
49
|
+
l = (l ^ h >>> 1) >>> 0;
|
|
50
|
+
mul64(l, h, 444984403, 3301882366);
|
|
51
|
+
l = RLO;
|
|
52
|
+
h = RHI;
|
|
53
|
+
l = (l ^ h >>> 1) >>> 0;
|
|
54
|
+
RLO = l;
|
|
55
|
+
RHI = h;
|
|
56
|
+
}
|
|
57
|
+
function mixSeed(lo, hi, seed) {
|
|
58
|
+
const l = (lo >>> 0) + (seed >>> 0);
|
|
59
|
+
const carry = l > 4294967295 ? 1 : 0;
|
|
60
|
+
fmix64(l >>> 0, hi + carry >>> 0);
|
|
61
|
+
}
|
|
62
|
+
function mulhi64(lo, hi, n) {
|
|
63
|
+
mul64(hi, 0, n, 0);
|
|
64
|
+
const aLo = RLO;
|
|
65
|
+
const aHi = RHI;
|
|
66
|
+
mul64(lo, 0, n, 0);
|
|
67
|
+
const bHi = RHI;
|
|
68
|
+
return aHi + ((aLo >>> 0) + (bHi >>> 0) > 4294967295 ? 1 : 0) >>> 0;
|
|
69
|
+
}
|
|
70
|
+
function positionsInto(mlo, mhi, seg, segMask, segCountLen, out) {
|
|
71
|
+
const h0 = mulhi64(mlo, mhi, segCountLen);
|
|
72
|
+
let h1 = h0 + seg >>> 0;
|
|
73
|
+
let h2 = h1 + seg >>> 0;
|
|
74
|
+
h1 = (h1 ^ (mlo >>> 18 | mhi << 14) & segMask) >>> 0;
|
|
75
|
+
h2 = (h2 ^ mlo & segMask) >>> 0;
|
|
76
|
+
out[0] = h0;
|
|
77
|
+
out[1] = h1;
|
|
78
|
+
out[2] = h2;
|
|
79
|
+
}
|
|
80
|
+
function fpMask(fp) {
|
|
81
|
+
return (1 << 8 * fp.BYTES_PER_ELEMENT) - 1 >>> 0;
|
|
82
|
+
}
|
|
83
|
+
function computeParams(size) {
|
|
84
|
+
const seg = Math.min(1 << Math.floor(Math.log(size) / Math.log(3.33) + 2.25), 1 << 18);
|
|
85
|
+
const segMask = seg - 1;
|
|
86
|
+
const sizeFactor = Math.max(1.125, .875 + .25 * Math.log(1e6) / Math.log(Math.max(size, 2)));
|
|
87
|
+
const capacity = Math.round(size * sizeFactor);
|
|
88
|
+
let segCount = Math.floor((capacity + seg - 1) / seg) - (ARITY - 1);
|
|
89
|
+
if (segCount <= 0) segCount = 1;
|
|
90
|
+
let arrayLength = (segCount + ARITY - 1) * seg;
|
|
91
|
+
segCount = Math.floor((arrayLength + seg - 1) / seg) - (ARITY - 1);
|
|
92
|
+
if (segCount <= 0) segCount = 1;
|
|
93
|
+
arrayLength = (segCount + ARITY - 1) * seg;
|
|
94
|
+
return {
|
|
95
|
+
seg,
|
|
96
|
+
segMask,
|
|
97
|
+
segCountLen: segCount * seg,
|
|
98
|
+
arrayLength
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Peel the 3-hypergraph and assign fingerprints so every key's XOR of its 3
|
|
103
|
+
* lanes equals its fingerprint. Retries with a bumped seed on a stall; returns
|
|
104
|
+
* the seed that succeeded.
|
|
105
|
+
*/
|
|
106
|
+
function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
|
|
107
|
+
const size = hashes.length / 2;
|
|
108
|
+
const { seg, segMask, segCountLen, arrayLength } = params;
|
|
109
|
+
const mask = fpMask(fp);
|
|
110
|
+
const counts = new Uint32Array(arrayLength);
|
|
111
|
+
const xorLo = new Uint32Array(arrayLength);
|
|
112
|
+
const xorHi = new Uint32Array(arrayLength);
|
|
113
|
+
const orderLo = new Uint32Array(size);
|
|
114
|
+
const orderHi = new Uint32Array(size);
|
|
115
|
+
const orderIdx = new Uint32Array(size);
|
|
116
|
+
const pos = /* @__PURE__ */ new Uint32Array(3);
|
|
117
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
118
|
+
const seed = attempt;
|
|
119
|
+
counts.fill(0);
|
|
120
|
+
xorLo.fill(0);
|
|
121
|
+
xorHi.fill(0);
|
|
122
|
+
for (let i = 0; i < size; i++) {
|
|
123
|
+
mixSeed(hashes[2 * i] ?? 0, hashes[2 * i + 1] ?? 0, seed);
|
|
124
|
+
const mlo = RLO;
|
|
125
|
+
const mhi = RHI;
|
|
126
|
+
positionsInto(mlo, mhi, seg, segMask, segCountLen, pos);
|
|
127
|
+
for (let j = 0; j < 3; j++) {
|
|
128
|
+
const p = pos[j] ?? 0;
|
|
129
|
+
counts[p] = (counts[p] ?? 0) + 1;
|
|
130
|
+
xorLo[p] = (xorLo[p] ?? 0) ^ mlo;
|
|
131
|
+
xorHi[p] = (xorHi[p] ?? 0) ^ mhi;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const queue = [];
|
|
135
|
+
for (let idx = 0; idx < arrayLength; idx++) if ((counts[idx] ?? 0) === 1) queue.push(idx);
|
|
136
|
+
let processed = 0;
|
|
137
|
+
while (queue.length > 0) {
|
|
138
|
+
const idx = queue.pop();
|
|
139
|
+
if (idx === void 0) break;
|
|
140
|
+
if ((counts[idx] ?? 0) !== 1) continue;
|
|
141
|
+
const mlo = xorLo[idx] ?? 0;
|
|
142
|
+
const mhi = xorHi[idx] ?? 0;
|
|
143
|
+
orderLo[processed] = mlo;
|
|
144
|
+
orderHi[processed] = mhi;
|
|
145
|
+
orderIdx[processed] = idx;
|
|
146
|
+
processed++;
|
|
147
|
+
positionsInto(mlo, mhi, seg, segMask, segCountLen, pos);
|
|
148
|
+
for (let j = 0; j < 3; j++) {
|
|
149
|
+
const p = pos[j] ?? 0;
|
|
150
|
+
counts[p] = (counts[p] ?? 0) - 1;
|
|
151
|
+
xorLo[p] = (xorLo[p] ?? 0) ^ mlo;
|
|
152
|
+
xorHi[p] = (xorHi[p] ?? 0) ^ mhi;
|
|
153
|
+
if ((counts[p] ?? 0) === 1) queue.push(p);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (processed === size) {
|
|
157
|
+
fp.fill(0);
|
|
158
|
+
for (let i = processed - 1; i >= 0; i--) {
|
|
159
|
+
const mlo = orderLo[i] ?? 0;
|
|
160
|
+
const mhi = orderHi[i] ?? 0;
|
|
161
|
+
const idx = orderIdx[i] ?? 0;
|
|
162
|
+
positionsInto(mlo, mhi, seg, segMask, segCountLen, pos);
|
|
163
|
+
const p0 = pos[0] ?? 0;
|
|
164
|
+
const p1 = pos[1] ?? 0;
|
|
165
|
+
const p2 = pos[2] ?? 0;
|
|
166
|
+
fp[idx] = ((mlo ^ mhi) & mask ^ (fp[p0] ?? 0) ^ (fp[p1] ?? 0) ^ (fp[p2] ?? 0)) & mask;
|
|
167
|
+
}
|
|
168
|
+
return seed;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
throw new BinaryFuseBuildError("binary fuse construction failed");
|
|
172
|
+
}
|
|
173
|
+
function buildState(keys, alloc) {
|
|
174
|
+
const hashList = [];
|
|
175
|
+
const seen = /* @__PURE__ */ new Set();
|
|
176
|
+
for (const key of keys) {
|
|
177
|
+
const { h1lo, h1hi } = hash128(normalize(key), 0);
|
|
178
|
+
const lo = h1lo >>> 0;
|
|
179
|
+
const hi = h1hi >>> 0;
|
|
180
|
+
const id = `${String(lo)},${String(hi)}`;
|
|
181
|
+
if (seen.has(id)) continue;
|
|
182
|
+
seen.add(id);
|
|
183
|
+
hashList.push(lo, hi);
|
|
184
|
+
}
|
|
185
|
+
const size = hashList.length / 2;
|
|
186
|
+
const params = computeParams(size);
|
|
187
|
+
if (size === 0) return {
|
|
188
|
+
fp: alloc(0),
|
|
189
|
+
seed: 0,
|
|
190
|
+
params,
|
|
191
|
+
size: 0
|
|
192
|
+
};
|
|
193
|
+
const hashes = Uint32Array.from(hashList);
|
|
194
|
+
const fp = alloc(params.arrayLength);
|
|
195
|
+
return {
|
|
196
|
+
fp,
|
|
197
|
+
seed: buildFingerprints(fp, hashes, params),
|
|
198
|
+
params,
|
|
199
|
+
size
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function fuseStateFromBytes(bytes, expectedType) {
|
|
203
|
+
const { type, body } = readHeader(bytes);
|
|
204
|
+
if (type !== expectedType) throw new SerializationError(`expected AMQF type ${String(expectedType)}, got ${String(type)}`);
|
|
205
|
+
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
206
|
+
const seed = dv.getUint32(0, true);
|
|
207
|
+
const seg = dv.getUint32(4, true);
|
|
208
|
+
const segCountLen = dv.getUint32(8, true);
|
|
209
|
+
const size = dv.getUint32(12, true);
|
|
210
|
+
const laneBytes = body.subarray(16);
|
|
211
|
+
const bpe = expectedType === TYPE_FUSE8 ? 1 : 2;
|
|
212
|
+
const arrayLength = laneBytes.length / bpe;
|
|
213
|
+
const fp = bpe === 1 ? new Uint8Array(arrayLength) : new Uint16Array(arrayLength);
|
|
214
|
+
new Uint8Array(fp.buffer).set(laneBytes);
|
|
215
|
+
return {
|
|
216
|
+
fp,
|
|
217
|
+
seed,
|
|
218
|
+
params: {
|
|
219
|
+
seg,
|
|
220
|
+
segMask: seg - 1,
|
|
221
|
+
segCountLen,
|
|
222
|
+
arrayLength
|
|
223
|
+
},
|
|
224
|
+
size
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
var BinaryFuse = class {
|
|
228
|
+
#fp;
|
|
229
|
+
#seed;
|
|
230
|
+
#seg;
|
|
231
|
+
#segMask;
|
|
232
|
+
#segCountLen;
|
|
233
|
+
#size;
|
|
234
|
+
#pos = /* @__PURE__ */ new Uint32Array(3);
|
|
235
|
+
constructor(state) {
|
|
236
|
+
this.#fp = state.fp;
|
|
237
|
+
this.#seed = state.seed;
|
|
238
|
+
this.#seg = state.params.seg;
|
|
239
|
+
this.#segMask = state.params.segMask;
|
|
240
|
+
this.#segCountLen = state.params.segCountLen;
|
|
241
|
+
this.#size = state.size;
|
|
242
|
+
}
|
|
243
|
+
get size() {
|
|
244
|
+
return this.#size;
|
|
245
|
+
}
|
|
246
|
+
get bitsPerKey() {
|
|
247
|
+
return this.#size === 0 ? 0 : this.#fp.byteLength * 8 / this.#size;
|
|
248
|
+
}
|
|
249
|
+
toBytes() {
|
|
250
|
+
const laneBytes = new Uint8Array(this.#fp.buffer, this.#fp.byteOffset, this.#fp.byteLength);
|
|
251
|
+
const body = new Uint8Array(16 + laneBytes.length);
|
|
252
|
+
const dv = new DataView(body.buffer);
|
|
253
|
+
dv.setUint32(0, this.#seed, true);
|
|
254
|
+
dv.setUint32(4, this.#seg, true);
|
|
255
|
+
dv.setUint32(8, this.#segCountLen, true);
|
|
256
|
+
dv.setUint32(12, this.#size, true);
|
|
257
|
+
body.set(laneBytes, 16);
|
|
258
|
+
return writeHeader({
|
|
259
|
+
version: 1,
|
|
260
|
+
type: this.#fp.BYTES_PER_ELEMENT === 1 ? TYPE_FUSE8 : TYPE_FUSE16,
|
|
261
|
+
flags: 0
|
|
262
|
+
}, body);
|
|
263
|
+
}
|
|
264
|
+
has(key) {
|
|
265
|
+
if (this.#fp.length === 0) return false;
|
|
266
|
+
const { h1lo, h1hi } = hash128(normalize(key), 0);
|
|
267
|
+
mixSeed(h1lo >>> 0, h1hi >>> 0, this.#seed);
|
|
268
|
+
const mlo = RLO;
|
|
269
|
+
const mhi = RHI;
|
|
270
|
+
positionsInto(mlo, mhi, this.#seg, this.#segMask, this.#segCountLen, this.#pos);
|
|
271
|
+
const mask = fpMask(this.#fp);
|
|
272
|
+
const p0 = this.#pos[0] ?? 0;
|
|
273
|
+
const p1 = this.#pos[1] ?? 0;
|
|
274
|
+
const p2 = this.#pos[2] ?? 0;
|
|
275
|
+
return ((mlo ^ mhi) & mask) === (((this.#fp[p0] ?? 0) ^ (this.#fp[p1] ?? 0) ^ (this.#fp[p2] ?? 0)) & mask);
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var BinaryFuse8 = class BinaryFuse8 extends BinaryFuse {
|
|
279
|
+
static from(keys) {
|
|
280
|
+
return new BinaryFuse8(buildState(keys, (n) => new Uint8Array(n)));
|
|
281
|
+
}
|
|
282
|
+
static fromBytes(bytes) {
|
|
283
|
+
return new BinaryFuse8(fuseStateFromBytes(bytes, TYPE_FUSE8));
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
var BinaryFuse16 = class BinaryFuse16 extends BinaryFuse {
|
|
287
|
+
static from(keys) {
|
|
288
|
+
return new BinaryFuse16(buildState(keys, (n) => new Uint16Array(n)));
|
|
289
|
+
}
|
|
290
|
+
static fromBytes(bytes) {
|
|
291
|
+
return new BinaryFuse16(fuseStateFromBytes(bytes, TYPE_FUSE16));
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
//#endregion
|
|
295
|
+
export { BinaryFuse16, BinaryFuse8, BinaryFuseBuildError };
|
package/dist/index.cjs
ADDED
package/dist/index.d.cts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
//#region src/core/bytes.ts
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
function normalize(input) {
|
|
4
|
+
if (typeof input === "string") return encoder.encode(input);
|
|
5
|
+
if (input instanceof Uint8Array) return input;
|
|
6
|
+
return new Uint8Array(input);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/core/hasher.ts
|
|
10
|
+
const C1LO = 289559509;
|
|
11
|
+
const C1HI = 2277735313;
|
|
12
|
+
const C2LO = 658871167;
|
|
13
|
+
const C2HI = 1291169091;
|
|
14
|
+
let RLO = 0;
|
|
15
|
+
let RHI = 0;
|
|
16
|
+
function mul64(alo, ahi, blo, bhi) {
|
|
17
|
+
const a0 = alo & 65535;
|
|
18
|
+
const a1 = alo >>> 16;
|
|
19
|
+
const a2 = ahi & 65535;
|
|
20
|
+
const a3 = ahi >>> 16;
|
|
21
|
+
const b0 = blo & 65535;
|
|
22
|
+
const b1 = blo >>> 16;
|
|
23
|
+
const b2 = bhi & 65535;
|
|
24
|
+
const b3 = bhi >>> 16;
|
|
25
|
+
let c0 = a0 * b0;
|
|
26
|
+
let c1 = c0 >>> 16;
|
|
27
|
+
c0 &= 65535;
|
|
28
|
+
c1 += a1 * b0;
|
|
29
|
+
let c2 = c1 >>> 16;
|
|
30
|
+
c1 &= 65535;
|
|
31
|
+
c1 += a0 * b1;
|
|
32
|
+
c2 += c1 >>> 16;
|
|
33
|
+
c1 &= 65535;
|
|
34
|
+
c2 += a2 * b0;
|
|
35
|
+
let c3 = c2 >>> 16;
|
|
36
|
+
c2 &= 65535;
|
|
37
|
+
c2 += a1 * b1;
|
|
38
|
+
c3 += c2 >>> 16;
|
|
39
|
+
c2 &= 65535;
|
|
40
|
+
c2 += a0 * b2;
|
|
41
|
+
c3 += c2 >>> 16;
|
|
42
|
+
c2 &= 65535;
|
|
43
|
+
c3 += a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3;
|
|
44
|
+
c3 &= 65535;
|
|
45
|
+
RLO = (c1 << 16 | c0) >>> 0;
|
|
46
|
+
RHI = (c3 << 16 | c2) >>> 0;
|
|
47
|
+
}
|
|
48
|
+
function rotl64(lo, hi, r) {
|
|
49
|
+
if (r < 32) {
|
|
50
|
+
RLO = (lo << r | hi >>> 32 - r) >>> 0;
|
|
51
|
+
RHI = (hi << r | lo >>> 32 - r) >>> 0;
|
|
52
|
+
} else {
|
|
53
|
+
const s = r - 32;
|
|
54
|
+
RLO = (hi << s | lo >>> 32 - s) >>> 0;
|
|
55
|
+
RHI = (lo << s | hi >>> 32 - s) >>> 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function add64(alo, ahi, blo, bhi) {
|
|
59
|
+
const lo = (alo >>> 0) + (blo >>> 0);
|
|
60
|
+
RHI = ahi + bhi + (lo > 4294967295 ? 1 : 0) >>> 0;
|
|
61
|
+
RLO = lo >>> 0;
|
|
62
|
+
}
|
|
63
|
+
function fmix64(lo, hi) {
|
|
64
|
+
let l = lo;
|
|
65
|
+
let h = hi;
|
|
66
|
+
l = (l ^ h >>> 1) >>> 0;
|
|
67
|
+
mul64(l, h, 3981806797, 4283543511);
|
|
68
|
+
l = RLO;
|
|
69
|
+
h = RHI;
|
|
70
|
+
l = (l ^ h >>> 1) >>> 0;
|
|
71
|
+
mul64(l, h, 444984403, 3301882366);
|
|
72
|
+
l = RLO;
|
|
73
|
+
h = RHI;
|
|
74
|
+
l = (l ^ h >>> 1) >>> 0;
|
|
75
|
+
RLO = l;
|
|
76
|
+
RHI = h;
|
|
77
|
+
}
|
|
78
|
+
function hash128(bytes, seed = 0) {
|
|
79
|
+
const len = bytes.length;
|
|
80
|
+
const nblocks = len >>> 4;
|
|
81
|
+
let h1lo = seed >>> 0;
|
|
82
|
+
let h1hi = 0;
|
|
83
|
+
let h2lo = seed >>> 0;
|
|
84
|
+
let h2hi = 0;
|
|
85
|
+
for (let i = 0; i < nblocks; i++) {
|
|
86
|
+
const b = i * 16;
|
|
87
|
+
let k1lo = ((bytes[b] ?? 0) | (bytes[b + 1] ?? 0) << 8 | (bytes[b + 2] ?? 0) << 16 | (bytes[b + 3] ?? 0) << 24) >>> 0;
|
|
88
|
+
let k1hi = ((bytes[b + 4] ?? 0) | (bytes[b + 5] ?? 0) << 8 | (bytes[b + 6] ?? 0) << 16 | (bytes[b + 7] ?? 0) << 24) >>> 0;
|
|
89
|
+
let k2lo = ((bytes[b + 8] ?? 0) | (bytes[b + 9] ?? 0) << 8 | (bytes[b + 10] ?? 0) << 16 | (bytes[b + 11] ?? 0) << 24) >>> 0;
|
|
90
|
+
let k2hi = ((bytes[b + 12] ?? 0) | (bytes[b + 13] ?? 0) << 8 | (bytes[b + 14] ?? 0) << 16 | (bytes[b + 15] ?? 0) << 24) >>> 0;
|
|
91
|
+
mul64(k1lo, k1hi, C1LO, C1HI);
|
|
92
|
+
rotl64(RLO, RHI, 31);
|
|
93
|
+
mul64(RLO, RHI, C2LO, C2HI);
|
|
94
|
+
k1lo = RLO;
|
|
95
|
+
k1hi = RHI;
|
|
96
|
+
h1lo ^= k1lo;
|
|
97
|
+
h1hi ^= k1hi;
|
|
98
|
+
rotl64(h1lo, h1hi, 27);
|
|
99
|
+
add64(RLO, RHI, h2lo, h2hi);
|
|
100
|
+
mul64(RLO, RHI, 5, 0);
|
|
101
|
+
add64(RLO, RHI, 1390208809, 0);
|
|
102
|
+
h1lo = RLO;
|
|
103
|
+
h1hi = RHI;
|
|
104
|
+
mul64(k2lo, k2hi, C2LO, C2HI);
|
|
105
|
+
rotl64(RLO, RHI, 33);
|
|
106
|
+
mul64(RLO, RHI, C1LO, C1HI);
|
|
107
|
+
k2lo = RLO;
|
|
108
|
+
k2hi = RHI;
|
|
109
|
+
h2lo ^= k2lo;
|
|
110
|
+
h2hi ^= k2hi;
|
|
111
|
+
rotl64(h2lo, h2hi, 31);
|
|
112
|
+
add64(RLO, RHI, h1lo, h1hi);
|
|
113
|
+
mul64(RLO, RHI, 5, 0);
|
|
114
|
+
add64(RLO, RHI, 944331445, 0);
|
|
115
|
+
h2lo = RLO;
|
|
116
|
+
h2hi = RHI;
|
|
117
|
+
}
|
|
118
|
+
let k1lo = 0;
|
|
119
|
+
let k1hi = 0;
|
|
120
|
+
let k2lo = 0;
|
|
121
|
+
let k2hi = 0;
|
|
122
|
+
const tail = nblocks * 16;
|
|
123
|
+
const rem = len & 15;
|
|
124
|
+
if (rem >= 15) k2hi ^= (bytes[tail + 14] ?? 0) << 16;
|
|
125
|
+
if (rem >= 14) k2hi ^= (bytes[tail + 13] ?? 0) << 8;
|
|
126
|
+
if (rem >= 13) k2hi ^= bytes[tail + 12] ?? 0;
|
|
127
|
+
if (rem >= 12) k2lo ^= (bytes[tail + 11] ?? 0) << 24;
|
|
128
|
+
if (rem >= 11) k2lo ^= (bytes[tail + 10] ?? 0) << 16;
|
|
129
|
+
if (rem >= 10) k2lo ^= (bytes[tail + 9] ?? 0) << 8;
|
|
130
|
+
if (rem >= 9) {
|
|
131
|
+
k2lo ^= bytes[tail + 8] ?? 0;
|
|
132
|
+
k2lo >>>= 0;
|
|
133
|
+
k2hi >>>= 0;
|
|
134
|
+
mul64(k2lo, k2hi, C2LO, C2HI);
|
|
135
|
+
rotl64(RLO, RHI, 33);
|
|
136
|
+
mul64(RLO, RHI, C1LO, C1HI);
|
|
137
|
+
h2lo ^= RLO;
|
|
138
|
+
h2hi ^= RHI;
|
|
139
|
+
}
|
|
140
|
+
if (rem >= 8) k1hi ^= (bytes[tail + 7] ?? 0) << 24;
|
|
141
|
+
if (rem >= 7) k1hi ^= (bytes[tail + 6] ?? 0) << 16;
|
|
142
|
+
if (rem >= 6) k1hi ^= (bytes[tail + 5] ?? 0) << 8;
|
|
143
|
+
if (rem >= 5) k1hi ^= bytes[tail + 4] ?? 0;
|
|
144
|
+
if (rem >= 4) k1lo ^= (bytes[tail + 3] ?? 0) << 24;
|
|
145
|
+
if (rem >= 3) k1lo ^= (bytes[tail + 2] ?? 0) << 16;
|
|
146
|
+
if (rem >= 2) k1lo ^= (bytes[tail + 1] ?? 0) << 8;
|
|
147
|
+
if (rem >= 1) {
|
|
148
|
+
k1lo ^= bytes[tail] ?? 0;
|
|
149
|
+
k1lo >>>= 0;
|
|
150
|
+
k1hi >>>= 0;
|
|
151
|
+
mul64(k1lo, k1hi, C1LO, C1HI);
|
|
152
|
+
rotl64(RLO, RHI, 31);
|
|
153
|
+
mul64(RLO, RHI, C2LO, C2HI);
|
|
154
|
+
h1lo ^= RLO;
|
|
155
|
+
h1hi ^= RHI;
|
|
156
|
+
}
|
|
157
|
+
h1lo = (h1lo ^ len) >>> 0;
|
|
158
|
+
h2lo = (h2lo ^ len) >>> 0;
|
|
159
|
+
add64(h1lo, h1hi, h2lo, h2hi);
|
|
160
|
+
h1lo = RLO;
|
|
161
|
+
h1hi = RHI;
|
|
162
|
+
add64(h2lo, h2hi, h1lo, h1hi);
|
|
163
|
+
h2lo = RLO;
|
|
164
|
+
h2hi = RHI;
|
|
165
|
+
fmix64(h1lo, h1hi);
|
|
166
|
+
h1lo = RLO;
|
|
167
|
+
h1hi = RHI;
|
|
168
|
+
fmix64(h2lo, h2hi);
|
|
169
|
+
h2lo = RLO;
|
|
170
|
+
h2hi = RHI;
|
|
171
|
+
add64(h1lo, h1hi, h2lo, h2hi);
|
|
172
|
+
h1lo = RLO;
|
|
173
|
+
h1hi = RHI;
|
|
174
|
+
add64(h2lo, h2hi, h1lo, h1hi);
|
|
175
|
+
h2lo = RLO;
|
|
176
|
+
h2hi = RHI;
|
|
177
|
+
return {
|
|
178
|
+
h1lo: h1lo >>> 0,
|
|
179
|
+
h1hi: h1hi >>> 0,
|
|
180
|
+
h2lo: h2lo >>> 0,
|
|
181
|
+
h2hi: h2hi >>> 0
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function reduce(x, range) {
|
|
185
|
+
const xlo = x & 65535;
|
|
186
|
+
const xhi = x >>> 16;
|
|
187
|
+
const rlo = range & 65535;
|
|
188
|
+
const rhi = range >>> 16;
|
|
189
|
+
const lolo = xlo * rlo;
|
|
190
|
+
const lohi = xlo * rhi;
|
|
191
|
+
const hilo = xhi * rlo;
|
|
192
|
+
const hihi = xhi * rhi;
|
|
193
|
+
const carry = (lolo >>> 16) + (lohi & 65535) + (hilo & 65535);
|
|
194
|
+
return hihi + (lohi >>> 16) + (hilo >>> 16) + (carry >>> 16) >>> 0;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Derive `count` bucket indices in `[0, range)` from a key using
|
|
198
|
+
* Kirsch-Mitzenmacher enhanced double hashing `g_i = h1 + i*h2 + i^2`
|
|
199
|
+
* (the RocksDB `+i^2` fix), reduced into range with Lemire multiply-shift.
|
|
200
|
+
*/
|
|
201
|
+
function probeInto(key, count, range, seed, out) {
|
|
202
|
+
const { h1lo, h1hi, h2lo, h2hi } = hash128(normalize(key), seed);
|
|
203
|
+
const a = (h1lo ^ h1hi) >>> 0;
|
|
204
|
+
const b = (h2lo ^ h2hi) >>> 0;
|
|
205
|
+
for (let i = 0; i < count; i++) out[i] = reduce(a + Math.imul(i, b) + i * i >>> 0, range);
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/core/crc32.ts
|
|
209
|
+
let table;
|
|
210
|
+
function buildTable() {
|
|
211
|
+
const t = /* @__PURE__ */ new Uint32Array(256);
|
|
212
|
+
for (let n = 0; n < 256; n++) {
|
|
213
|
+
let c = n;
|
|
214
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
215
|
+
t[n] = c >>> 0;
|
|
216
|
+
}
|
|
217
|
+
return t;
|
|
218
|
+
}
|
|
219
|
+
function crc32(bytes) {
|
|
220
|
+
table ??= buildTable();
|
|
221
|
+
let crc = 4294967295;
|
|
222
|
+
for (const byte of bytes) crc = (table[(crc ^ byte) & 255] ?? 0) ^ crc >>> 8;
|
|
223
|
+
return (crc ^ 4294967295) >>> 0;
|
|
224
|
+
}
|
|
225
|
+
const HEADER_SIZE = 8;
|
|
226
|
+
const TRAILER_SIZE = 4;
|
|
227
|
+
function writeHeader(header, body) {
|
|
228
|
+
const frame = new Uint8Array(HEADER_SIZE + body.length + TRAILER_SIZE);
|
|
229
|
+
frame[0] = 65;
|
|
230
|
+
frame[1] = 77;
|
|
231
|
+
frame[2] = 81;
|
|
232
|
+
frame[3] = 70;
|
|
233
|
+
frame[4] = header.version;
|
|
234
|
+
frame[5] = header.type;
|
|
235
|
+
frame[6] = header.flags;
|
|
236
|
+
frame[7] = 0;
|
|
237
|
+
frame.set(body, HEADER_SIZE);
|
|
238
|
+
const crc = crc32(frame.subarray(0, HEADER_SIZE + body.length));
|
|
239
|
+
new DataView(frame.buffer, frame.byteOffset, frame.byteLength).setUint32(HEADER_SIZE + body.length, crc, true);
|
|
240
|
+
return frame;
|
|
241
|
+
}
|
|
242
|
+
var SerializationError = class extends Error {
|
|
243
|
+
name = "SerializationError";
|
|
244
|
+
};
|
|
245
|
+
var TruncatedError = class extends SerializationError {
|
|
246
|
+
name = "TruncatedError";
|
|
247
|
+
};
|
|
248
|
+
var BadMagicError = class extends SerializationError {
|
|
249
|
+
name = "BadMagicError";
|
|
250
|
+
};
|
|
251
|
+
var UnknownVersionError = class extends SerializationError {
|
|
252
|
+
name = "UnknownVersionError";
|
|
253
|
+
};
|
|
254
|
+
var ChecksumError = class extends SerializationError {
|
|
255
|
+
name = "ChecksumError";
|
|
256
|
+
};
|
|
257
|
+
function readHeader(frame) {
|
|
258
|
+
if (frame.length < 12) throw new TruncatedError(`frame of ${String(frame.length)} bytes is shorter than the minimum ${String(12)}`);
|
|
259
|
+
if (frame[0] !== 65 || frame[1] !== 77 || frame[2] !== 81 || frame[3] !== 70) throw new BadMagicError("frame does not start with the AMQF magic");
|
|
260
|
+
const version = frame[4] ?? 0;
|
|
261
|
+
if (version !== 1) throw new UnknownVersionError(`unsupported format version ${String(version)}`);
|
|
262
|
+
if (new DataView(frame.buffer, frame.byteOffset, frame.byteLength).getUint32(frame.length - TRAILER_SIZE, true) !== crc32(frame.subarray(0, frame.length - TRAILER_SIZE))) throw new ChecksumError("frame CRC32 does not match its contents");
|
|
263
|
+
return {
|
|
264
|
+
version,
|
|
265
|
+
type: frame[5] ?? 0,
|
|
266
|
+
flags: frame[6] ?? 0,
|
|
267
|
+
body: frame.subarray(HEADER_SIZE, frame.length - TRAILER_SIZE)
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//#endregion
|
|
271
|
+
Object.defineProperty(exports, "SerializationError", {
|
|
272
|
+
enumerable: true,
|
|
273
|
+
get: function() {
|
|
274
|
+
return SerializationError;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
Object.defineProperty(exports, "hash128", {
|
|
278
|
+
enumerable: true,
|
|
279
|
+
get: function() {
|
|
280
|
+
return hash128;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
Object.defineProperty(exports, "normalize", {
|
|
284
|
+
enumerable: true,
|
|
285
|
+
get: function() {
|
|
286
|
+
return normalize;
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
Object.defineProperty(exports, "probeInto", {
|
|
290
|
+
enumerable: true,
|
|
291
|
+
get: function() {
|
|
292
|
+
return probeInto;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
Object.defineProperty(exports, "readHeader", {
|
|
296
|
+
enumerable: true,
|
|
297
|
+
get: function() {
|
|
298
|
+
return readHeader;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
Object.defineProperty(exports, "reduce", {
|
|
302
|
+
enumerable: true,
|
|
303
|
+
get: function() {
|
|
304
|
+
return reduce;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
Object.defineProperty(exports, "writeHeader", {
|
|
308
|
+
enumerable: true,
|
|
309
|
+
get: function() {
|
|
310
|
+
return writeHeader;
|
|
311
|
+
}
|
|
312
|
+
});
|