distillate 0.5.0 → 0.7.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.
@@ -1,354 +0,0 @@
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
- const LANES = {
17
- h1lo: 0,
18
- h1hi: 0,
19
- h2lo: 0,
20
- h2hi: 0
21
- };
22
- function mul64(alo, ahi, blo, bhi) {
23
- const a0 = alo & 65535;
24
- const a1 = alo >>> 16;
25
- const a2 = ahi & 65535;
26
- const a3 = ahi >>> 16;
27
- const b0 = blo & 65535;
28
- const b1 = blo >>> 16;
29
- const b2 = bhi & 65535;
30
- const b3 = bhi >>> 16;
31
- let c0 = a0 * b0;
32
- let c1 = c0 >>> 16;
33
- c0 &= 65535;
34
- c1 += a1 * b0;
35
- let c2 = c1 >>> 16;
36
- c1 &= 65535;
37
- c1 += a0 * b1;
38
- c2 += c1 >>> 16;
39
- c1 &= 65535;
40
- c2 += a2 * b0;
41
- let c3 = c2 >>> 16;
42
- c2 &= 65535;
43
- c2 += a1 * b1;
44
- c3 += c2 >>> 16;
45
- c2 &= 65535;
46
- c2 += a0 * b2;
47
- c3 += c2 >>> 16;
48
- c2 &= 65535;
49
- c3 += a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3;
50
- c3 &= 65535;
51
- RLO = (c1 << 16 | c0) >>> 0;
52
- RHI = (c3 << 16 | c2) >>> 0;
53
- }
54
- function rotl64(lo, hi, r) {
55
- if (r < 32) {
56
- RLO = (lo << r | hi >>> 32 - r) >>> 0;
57
- RHI = (hi << r | lo >>> 32 - r) >>> 0;
58
- } else {
59
- const s = r - 32;
60
- RLO = (hi << s | lo >>> 32 - s) >>> 0;
61
- RHI = (lo << s | hi >>> 32 - s) >>> 0;
62
- }
63
- }
64
- function add64(alo, ahi, blo, bhi) {
65
- const lo = (alo >>> 0) + (blo >>> 0);
66
- RHI = ahi + bhi + (lo > 4294967295 ? 1 : 0) >>> 0;
67
- RLO = lo >>> 0;
68
- }
69
- function fmix64(lo, hi) {
70
- let l = lo;
71
- let h = hi;
72
- l = (l ^ h >>> 1) >>> 0;
73
- mul64(l, h, 3981806797, 4283543511);
74
- l = RLO;
75
- h = RHI;
76
- l = (l ^ h >>> 1) >>> 0;
77
- mul64(l, h, 444984403, 3301882366);
78
- l = RLO;
79
- h = RHI;
80
- l = (l ^ h >>> 1) >>> 0;
81
- RLO = l;
82
- RHI = h;
83
- }
84
- function murmur32(bytes, seed, len = bytes.length) {
85
- let h = seed >>> 0;
86
- const n = len & -4;
87
- for (let i = 0; i < n; i += 4) {
88
- let k = ((bytes[i] ?? 0) | (bytes[i + 1] ?? 0) << 8 | (bytes[i + 2] ?? 0) << 16 | (bytes[i + 3] ?? 0) << 24) >>> 0;
89
- k = Math.imul(k, 3432918353);
90
- k = (k << 15 | k >>> 17) >>> 0;
91
- k = Math.imul(k, 461845907);
92
- h = (h ^ k) >>> 0;
93
- h = (h << 13 | h >>> 19) >>> 0;
94
- h = Math.imul(h, 5) + 3864292196 >>> 0;
95
- }
96
- let k1 = 0;
97
- const rem = len & 3;
98
- if (rem >= 3) k1 ^= (bytes[n + 2] ?? 0) << 16;
99
- if (rem >= 2) k1 ^= (bytes[n + 1] ?? 0) << 8;
100
- if (rem >= 1) {
101
- k1 ^= bytes[n] ?? 0;
102
- k1 = Math.imul(k1 >>> 0, 3432918353);
103
- k1 = (k1 << 15 | k1 >>> 17) >>> 0;
104
- k1 = Math.imul(k1, 461845907);
105
- h = (h ^ k1) >>> 0;
106
- }
107
- h = (h ^ len) >>> 0;
108
- h ^= h >>> 16;
109
- h = Math.imul(h, 2246822507);
110
- h ^= h >>> 13;
111
- h = Math.imul(h, 3266489909);
112
- h ^= h >>> 16;
113
- return h >>> 0;
114
- }
115
- function computeLanes(bytes, seed, len) {
116
- const nblocks = len >>> 4;
117
- let h1lo = seed >>> 0;
118
- let h1hi = 0;
119
- let h2lo = seed >>> 0;
120
- let h2hi = 0;
121
- for (let i = 0; i < nblocks; i++) {
122
- const b = i * 16;
123
- let k1lo = ((bytes[b] ?? 0) | (bytes[b + 1] ?? 0) << 8 | (bytes[b + 2] ?? 0) << 16 | (bytes[b + 3] ?? 0) << 24) >>> 0;
124
- let k1hi = ((bytes[b + 4] ?? 0) | (bytes[b + 5] ?? 0) << 8 | (bytes[b + 6] ?? 0) << 16 | (bytes[b + 7] ?? 0) << 24) >>> 0;
125
- let k2lo = ((bytes[b + 8] ?? 0) | (bytes[b + 9] ?? 0) << 8 | (bytes[b + 10] ?? 0) << 16 | (bytes[b + 11] ?? 0) << 24) >>> 0;
126
- let k2hi = ((bytes[b + 12] ?? 0) | (bytes[b + 13] ?? 0) << 8 | (bytes[b + 14] ?? 0) << 16 | (bytes[b + 15] ?? 0) << 24) >>> 0;
127
- mul64(k1lo, k1hi, C1LO, C1HI);
128
- rotl64(RLO, RHI, 31);
129
- mul64(RLO, RHI, C2LO, C2HI);
130
- k1lo = RLO;
131
- k1hi = RHI;
132
- h1lo ^= k1lo;
133
- h1hi ^= k1hi;
134
- rotl64(h1lo, h1hi, 27);
135
- add64(RLO, RHI, h2lo, h2hi);
136
- mul64(RLO, RHI, 5, 0);
137
- add64(RLO, RHI, 1390208809, 0);
138
- h1lo = RLO;
139
- h1hi = RHI;
140
- mul64(k2lo, k2hi, C2LO, C2HI);
141
- rotl64(RLO, RHI, 33);
142
- mul64(RLO, RHI, C1LO, C1HI);
143
- k2lo = RLO;
144
- k2hi = RHI;
145
- h2lo ^= k2lo;
146
- h2hi ^= k2hi;
147
- rotl64(h2lo, h2hi, 31);
148
- add64(RLO, RHI, h1lo, h1hi);
149
- mul64(RLO, RHI, 5, 0);
150
- add64(RLO, RHI, 944331445, 0);
151
- h2lo = RLO;
152
- h2hi = RHI;
153
- }
154
- let k1lo = 0;
155
- let k1hi = 0;
156
- let k2lo = 0;
157
- let k2hi = 0;
158
- const tail = nblocks * 16;
159
- const rem = len & 15;
160
- if (rem >= 15) k2hi ^= (bytes[tail + 14] ?? 0) << 16;
161
- if (rem >= 14) k2hi ^= (bytes[tail + 13] ?? 0) << 8;
162
- if (rem >= 13) k2hi ^= bytes[tail + 12] ?? 0;
163
- if (rem >= 12) k2lo ^= (bytes[tail + 11] ?? 0) << 24;
164
- if (rem >= 11) k2lo ^= (bytes[tail + 10] ?? 0) << 16;
165
- if (rem >= 10) k2lo ^= (bytes[tail + 9] ?? 0) << 8;
166
- if (rem >= 9) {
167
- k2lo ^= bytes[tail + 8] ?? 0;
168
- k2lo >>>= 0;
169
- k2hi >>>= 0;
170
- mul64(k2lo, k2hi, C2LO, C2HI);
171
- rotl64(RLO, RHI, 33);
172
- mul64(RLO, RHI, C1LO, C1HI);
173
- h2lo ^= RLO;
174
- h2hi ^= RHI;
175
- }
176
- if (rem >= 8) k1hi ^= (bytes[tail + 7] ?? 0) << 24;
177
- if (rem >= 7) k1hi ^= (bytes[tail + 6] ?? 0) << 16;
178
- if (rem >= 6) k1hi ^= (bytes[tail + 5] ?? 0) << 8;
179
- if (rem >= 5) k1hi ^= bytes[tail + 4] ?? 0;
180
- if (rem >= 4) k1lo ^= (bytes[tail + 3] ?? 0) << 24;
181
- if (rem >= 3) k1lo ^= (bytes[tail + 2] ?? 0) << 16;
182
- if (rem >= 2) k1lo ^= (bytes[tail + 1] ?? 0) << 8;
183
- if (rem >= 1) {
184
- k1lo ^= bytes[tail] ?? 0;
185
- k1lo >>>= 0;
186
- k1hi >>>= 0;
187
- mul64(k1lo, k1hi, C1LO, C1HI);
188
- rotl64(RLO, RHI, 31);
189
- mul64(RLO, RHI, C2LO, C2HI);
190
- h1lo ^= RLO;
191
- h1hi ^= RHI;
192
- }
193
- h1lo = (h1lo ^ len) >>> 0;
194
- h2lo = (h2lo ^ len) >>> 0;
195
- add64(h1lo, h1hi, h2lo, h2hi);
196
- h1lo = RLO;
197
- h1hi = RHI;
198
- add64(h2lo, h2hi, h1lo, h1hi);
199
- h2lo = RLO;
200
- h2hi = RHI;
201
- fmix64(h1lo, h1hi);
202
- h1lo = RLO;
203
- h1hi = RHI;
204
- fmix64(h2lo, h2hi);
205
- h2lo = RLO;
206
- h2hi = RHI;
207
- add64(h1lo, h1hi, h2lo, h2hi);
208
- h1lo = RLO;
209
- h1hi = RHI;
210
- add64(h2lo, h2hi, h1lo, h1hi);
211
- h2lo = RLO;
212
- h2hi = RHI;
213
- LANES.h1lo = h1lo >>> 0;
214
- LANES.h1hi = h1hi >>> 0;
215
- LANES.h2lo = h2lo >>> 0;
216
- LANES.h2hi = h2hi >>> 0;
217
- }
218
- const keyEncoder = new TextEncoder();
219
- let keyBuf = /* @__PURE__ */ new Uint8Array(256);
220
- let encBytes = keyBuf;
221
- let encLen = 0;
222
- function encodeKey(key) {
223
- if (typeof key === "string") {
224
- const cap = key.length * 3;
225
- if (keyBuf.length < cap) keyBuf = new Uint8Array(cap);
226
- encLen = keyEncoder.encodeInto(key, keyBuf).written;
227
- encBytes = keyBuf;
228
- return;
229
- }
230
- encBytes = normalize(key);
231
- encLen = encBytes.length;
232
- }
233
- function keyToLanes(key, seed) {
234
- encodeKey(key);
235
- computeLanes(encBytes, seed, encLen);
236
- }
237
- function hash128KeyInto(key, seed, out) {
238
- keyToLanes(key, seed);
239
- out.h1lo = LANES.h1lo;
240
- out.h1hi = LANES.h1hi;
241
- out.h2lo = LANES.h2lo;
242
- out.h2hi = LANES.h2hi;
243
- }
244
- function reduce(x, range) {
245
- const xlo = x & 65535;
246
- const xhi = x >>> 16;
247
- const rlo = range & 65535;
248
- const rhi = range >>> 16;
249
- const lolo = xlo * rlo;
250
- const lohi = xlo * rhi;
251
- const hilo = xhi * rlo;
252
- const hihi = xhi * rhi;
253
- const carry = (lolo >>> 16) + (lohi & 65535) + (hilo & 65535);
254
- return hihi + (lohi >>> 16) + (hilo >>> 16) + (carry >>> 16) >>> 0;
255
- }
256
- /**
257
- * Derive `count` bucket indices in `[0, range)` from a key using
258
- * Kirsch-Mitzenmacher enhanced double hashing `g_i = h1 + i*h2 + i^2`
259
- * (the RocksDB `+i^2` fix), reduced into range with Lemire multiply-shift.
260
- */
261
- const SEED2 = 2654435761;
262
- function hash32x2Into(key, seed, out) {
263
- encodeKey(key);
264
- out[0] = murmur32(encBytes, seed, encLen);
265
- out[1] = murmur32(encBytes, (seed ^ SEED2) >>> 0, encLen);
266
- }
267
- function probeInto(key, count, range, seed, out) {
268
- encodeKey(key);
269
- const a = murmur32(encBytes, seed, encLen);
270
- const b = murmur32(encBytes, (seed ^ SEED2) >>> 0, encLen);
271
- for (let i = 0; i < count; i++) out[i] = reduce(a + Math.imul(i, b) + i * i >>> 0, range);
272
- }
273
- //#endregion
274
- //#region src/core/crc32.ts
275
- let table;
276
- function buildTable() {
277
- const t = /* @__PURE__ */ new Uint32Array(256);
278
- for (let n = 0; n < 256; n++) {
279
- let c = n;
280
- for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
281
- t[n] = c >>> 0;
282
- }
283
- return t;
284
- }
285
- function crc32(bytes) {
286
- table ??= buildTable();
287
- let crc = 4294967295;
288
- for (const byte of bytes) crc = (table[(crc ^ byte) & 255] ?? 0) ^ crc >>> 8;
289
- return (crc ^ 4294967295) >>> 0;
290
- }
291
- const HEADER_SIZE = 8;
292
- const TRAILER_SIZE = 4;
293
- function writeHeader(header, body) {
294
- const frame = new Uint8Array(HEADER_SIZE + body.length + TRAILER_SIZE);
295
- frame[0] = 65;
296
- frame[1] = 77;
297
- frame[2] = 81;
298
- frame[3] = 70;
299
- frame[4] = header.version;
300
- frame[5] = header.type;
301
- frame[6] = header.flags;
302
- frame[7] = 0;
303
- frame.set(body, HEADER_SIZE);
304
- const crc = crc32(frame.subarray(0, HEADER_SIZE + body.length));
305
- new DataView(frame.buffer, frame.byteOffset, frame.byteLength).setUint32(HEADER_SIZE + body.length, crc, true);
306
- return frame;
307
- }
308
- var SerializationError = class extends Error {
309
- name = "SerializationError";
310
- };
311
- var TruncatedError = class extends SerializationError {
312
- name = "TruncatedError";
313
- };
314
- var BadMagicError = class extends SerializationError {
315
- name = "BadMagicError";
316
- };
317
- var UnknownVersionError = class extends SerializationError {
318
- name = "UnknownVersionError";
319
- };
320
- var UnknownHashVariantError = class extends SerializationError {
321
- name = "UnknownHashVariantError";
322
- };
323
- var ChecksumError = class extends SerializationError {
324
- name = "ChecksumError";
325
- };
326
- /**
327
- * Asserts a frame body is long enough to hold its fixed params block, so the
328
- * params can be read without running off the end.
329
- */
330
- function assertMinBodyLength(actual, min, context) {
331
- if (actual < min) throw new TruncatedError(`${context}: body of ${String(actual)} bytes is shorter than the ${String(min)}-byte params block`);
332
- }
333
- /**
334
- * Asserts a frame body is exactly the length its declared params imply, so a
335
- * hostile or truncated frame is rejected before any backing store is allocated.
336
- */
337
- function assertBodyLength(actual, expected, context) {
338
- if (actual !== expected) throw new TruncatedError(`${context}: body of ${String(actual)} bytes does not match the declared params (expected ${String(expected)})`);
339
- }
340
- function readHeader(frame) {
341
- if (frame.length < 12) throw new TruncatedError(`frame of ${String(frame.length)} bytes is shorter than the minimum ${String(12)}`);
342
- if (frame[0] !== 65 || frame[1] !== 77 || frame[2] !== 81 || frame[3] !== 70) throw new BadMagicError("frame does not start with the AMQF magic");
343
- const version = frame[4] ?? 0;
344
- if (version !== 2) throw new UnknownVersionError(`unsupported format version ${String(version)}`);
345
- 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");
346
- return {
347
- version,
348
- type: frame[5] ?? 0,
349
- flags: frame[6] ?? 0,
350
- body: frame.subarray(HEADER_SIZE, frame.length - TRAILER_SIZE)
351
- };
352
- }
353
- //#endregion
354
- export { readHeader as a, RLO as c, hash32x2Into as d, mul64 as f, assertMinBodyLength as i, fmix64 as l, reduce as m, UnknownHashVariantError as n, writeHeader as o, probeInto as p, assertBodyLength as r, RHI as s, SerializationError as t, hash128KeyInto as u };