distillate 0.14.0 → 0.14.2
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/dist/blocked/index.cjs +1 -1
- package/dist/blocked/index.js +1 -1
- package/dist/bloom/index.cjs +6 -4
- package/dist/bloom/index.js +6 -4
- package/dist/bytes-DWGupBUE.cjs +45 -0
- package/dist/bytes-oOWlu7N5.js +34 -0
- package/dist/countmin/index.cjs +1 -1
- package/dist/countmin/index.js +1 -1
- package/dist/cuckoo/index.cjs +20 -9
- package/dist/cuckoo/index.js +20 -9
- package/dist/distinct-BhxDB8mW.js +61 -0
- package/dist/distinct-Ck5PKuCS.cjs +66 -0
- package/dist/fuse/index.cjs +6 -11
- package/dist/fuse/index.js +6 -11
- package/dist/{hasher-DOdmZ-LI.js → hasher-BQxNrCQC.js} +3 -18
- package/dist/{hasher-DPXmP7SH.cjs → hasher-CKLP9Oqe.cjs} +3 -18
- package/dist/hll/index.cjs +1 -1
- package/dist/hll/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/scalable/index.cjs +1 -1
- package/dist/scalable/index.js +1 -1
- package/dist/topk/index.cjs +19 -20
- package/dist/topk/index.js +19 -20
- package/package.json +7 -7
- package/dist/bytes-Be7tq1F7.js +0 -9
- package/dist/bytes-D2duG1jq.cjs +0 -14
package/dist/blocked/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_hasher = require("../hasher-
|
|
2
|
+
const require_hasher = require("../hasher-CKLP9Oqe.cjs");
|
|
3
3
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
4
4
|
const require_params = require("../params-UTZbJ22c.cjs");
|
|
5
5
|
//#region src/blocked/blocked.ts
|
package/dist/blocked/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as hash32x2Into, u as reduce } from "../hasher-
|
|
1
|
+
import { a as hash32x2Into, u as reduce } from "../hasher-BQxNrCQC.js";
|
|
2
2
|
import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
|
|
3
3
|
import { i as assertProbability, n as assertPositiveFinite, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
|
|
4
4
|
//#region src/blocked/blocked.ts
|
package/dist/bloom/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_sizing = require("../sizing-Ch0SDdza.cjs");
|
|
3
|
-
const require_hasher = require("../hasher-
|
|
3
|
+
const require_hasher = require("../hasher-CKLP9Oqe.cjs");
|
|
4
4
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
5
5
|
const require_params = require("../params-UTZbJ22c.cjs");
|
|
6
6
|
//#region src/bloom/bloom.ts
|
|
@@ -67,7 +67,7 @@ var BloomFilter = class BloomFilter {
|
|
|
67
67
|
this.#m = m;
|
|
68
68
|
this.#k = k;
|
|
69
69
|
this.#seed = seed;
|
|
70
|
-
this.#scratch = new Uint32Array(k);
|
|
70
|
+
this.#scratch = new Uint32Array(Math.max(k, 2));
|
|
71
71
|
this.#n = n ?? Math.max(1, Math.round(m * Math.LN2 / k));
|
|
72
72
|
}
|
|
73
73
|
get m() {
|
|
@@ -131,8 +131,10 @@ var BloomFilter = class BloomFilter {
|
|
|
131
131
|
for (let i = 0; i < this.#k; i++) this.#bits.set(this.#scratch[i] ?? 0);
|
|
132
132
|
}
|
|
133
133
|
has(key) {
|
|
134
|
-
require_hasher.
|
|
135
|
-
|
|
134
|
+
require_hasher.hash32x2Into(key, this.#seed, this.#scratch);
|
|
135
|
+
const a = this.#scratch[0] ?? 0;
|
|
136
|
+
const b = this.#scratch[1] ?? 0;
|
|
137
|
+
for (let i = 0; i < this.#k; i++) if (!this.#bits.get(require_hasher.probeAt(a, b, i, this.#m))) return false;
|
|
136
138
|
return true;
|
|
137
139
|
}
|
|
138
140
|
};
|
package/dist/bloom/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as BitSet, t as bloomSizing } from "../sizing-zxCBlyhO.js";
|
|
2
|
-
import { c as probeInto } from "../hasher-
|
|
2
|
+
import { a as hash32x2Into, c as probeInto, s as probeAt } from "../hasher-BQxNrCQC.js";
|
|
3
3
|
import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
|
|
4
4
|
import { a as assertUint16, i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
|
|
5
5
|
//#region src/bloom/bloom.ts
|
|
@@ -66,7 +66,7 @@ var BloomFilter = class BloomFilter {
|
|
|
66
66
|
this.#m = m;
|
|
67
67
|
this.#k = k;
|
|
68
68
|
this.#seed = seed;
|
|
69
|
-
this.#scratch = new Uint32Array(k);
|
|
69
|
+
this.#scratch = new Uint32Array(Math.max(k, 2));
|
|
70
70
|
this.#n = n ?? Math.max(1, Math.round(m * Math.LN2 / k));
|
|
71
71
|
}
|
|
72
72
|
get m() {
|
|
@@ -130,8 +130,10 @@ var BloomFilter = class BloomFilter {
|
|
|
130
130
|
for (let i = 0; i < this.#k; i++) this.#bits.set(this.#scratch[i] ?? 0);
|
|
131
131
|
}
|
|
132
132
|
has(key) {
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
hash32x2Into(key, this.#seed, this.#scratch);
|
|
134
|
+
const a = this.#scratch[0] ?? 0;
|
|
135
|
+
const b = this.#scratch[1] ?? 0;
|
|
136
|
+
for (let i = 0; i < this.#k; i++) if (!this.#bits.get(probeAt(a, b, i, this.#m))) return false;
|
|
135
137
|
return true;
|
|
136
138
|
}
|
|
137
139
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
const ASCII_FAST_MAX = 12;
|
|
9
|
+
let keyBuf = new Uint8Array(256);
|
|
10
|
+
let keyBytes = keyBuf;
|
|
11
|
+
function encodedBytes() {
|
|
12
|
+
return keyBytes;
|
|
13
|
+
}
|
|
14
|
+
function encodeKey(key) {
|
|
15
|
+
if (typeof key === "string") {
|
|
16
|
+
const n = key.length;
|
|
17
|
+
if (keyBuf.length < n * 3) keyBuf = new Uint8Array(n * 3);
|
|
18
|
+
keyBytes = keyBuf;
|
|
19
|
+
if (n <= ASCII_FAST_MAX) {
|
|
20
|
+
let i = 0;
|
|
21
|
+
for (; i < n; i++) {
|
|
22
|
+
const c = key.charCodeAt(i);
|
|
23
|
+
if (c > 127) break;
|
|
24
|
+
keyBuf[i] = c;
|
|
25
|
+
}
|
|
26
|
+
if (i === n) return n;
|
|
27
|
+
}
|
|
28
|
+
return encoder.encodeInto(key, keyBuf).written;
|
|
29
|
+
}
|
|
30
|
+
keyBytes = normalize(key);
|
|
31
|
+
return keyBytes.length;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
Object.defineProperty(exports, "encodeKey", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function() {
|
|
37
|
+
return encodeKey;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(exports, "encodedBytes", {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
get: function() {
|
|
43
|
+
return encodedBytes;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
const ASCII_FAST_MAX = 12;
|
|
9
|
+
let keyBuf = new Uint8Array(256);
|
|
10
|
+
let keyBytes = keyBuf;
|
|
11
|
+
function encodedBytes() {
|
|
12
|
+
return keyBytes;
|
|
13
|
+
}
|
|
14
|
+
function encodeKey(key) {
|
|
15
|
+
if (typeof key === "string") {
|
|
16
|
+
const n = key.length;
|
|
17
|
+
if (keyBuf.length < n * 3) keyBuf = new Uint8Array(n * 3);
|
|
18
|
+
keyBytes = keyBuf;
|
|
19
|
+
if (n <= ASCII_FAST_MAX) {
|
|
20
|
+
let i = 0;
|
|
21
|
+
for (; i < n; i++) {
|
|
22
|
+
const c = key.charCodeAt(i);
|
|
23
|
+
if (c > 127) break;
|
|
24
|
+
keyBuf[i] = c;
|
|
25
|
+
}
|
|
26
|
+
if (i === n) return n;
|
|
27
|
+
}
|
|
28
|
+
return encoder.encodeInto(key, keyBuf).written;
|
|
29
|
+
}
|
|
30
|
+
keyBytes = normalize(key);
|
|
31
|
+
return keyBytes.length;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { encodedBytes as n, encodeKey as t };
|
package/dist/countmin/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_hasher = require("../hasher-
|
|
2
|
+
const require_hasher = require("../hasher-CKLP9Oqe.cjs");
|
|
3
3
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
4
4
|
const require_params = require("../params-UTZbJ22c.cjs");
|
|
5
5
|
//#region src/countmin/sizing.ts
|
package/dist/countmin/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as hash32x2Into, s as probeAt } from "../hasher-
|
|
1
|
+
import { a as hash32x2Into, s as probeAt } from "../hasher-BQxNrCQC.js";
|
|
2
2
|
import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
|
|
3
3
|
import { i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
|
|
4
4
|
//#region src/countmin/sizing.ts
|
package/dist/cuckoo/index.cjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_hasher = require("../hasher-
|
|
2
|
+
const require_hasher = require("../hasher-CKLP9Oqe.cjs");
|
|
3
3
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
4
4
|
const require_params = require("../params-UTZbJ22c.cjs");
|
|
5
|
+
const require_distinct = require("../distinct-Ck5PKuCS.cjs");
|
|
5
6
|
function cuckooSizing(n, epsilon) {
|
|
6
7
|
require_params.assertProbability(epsilon, "epsilon");
|
|
7
8
|
const f = Math.max(4, Math.ceil(Math.log2(8 / epsilon)));
|
|
@@ -54,17 +55,21 @@ var CuckooFilter = class CuckooFilter {
|
|
|
54
55
|
});
|
|
55
56
|
}
|
|
56
57
|
static from(keys, epsilon, options = {}) {
|
|
57
|
-
const
|
|
58
|
-
const distinct = [];
|
|
58
|
+
const distinct = new require_distinct.DistinctHashes(4);
|
|
59
59
|
for (const key of keys) {
|
|
60
60
|
require_hasher.hash128KeyInto(key, options.seed ?? 0, HASH);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
distinct.add(HASH);
|
|
62
|
+
}
|
|
63
|
+
const f = CuckooFilter.create(Math.max(1, distinct.size), epsilon, options);
|
|
64
|
+
const words = distinct.words;
|
|
65
|
+
for (let at = 0; at < words.length; at += 4) {
|
|
66
|
+
HASH.w0 = words[at] ?? 0;
|
|
67
|
+
HASH.w1 = words[at + 1] ?? 0;
|
|
68
|
+
HASH.w2 = words[at + 2] ?? 0;
|
|
69
|
+
HASH.w3 = words[at + 3] ?? 0;
|
|
70
|
+
f.#derive();
|
|
71
|
+
f.#insert();
|
|
65
72
|
}
|
|
66
|
-
const f = CuckooFilter.create(Math.max(1, distinct.length), epsilon, options);
|
|
67
|
-
for (const k of distinct) f.add(k);
|
|
68
73
|
return f;
|
|
69
74
|
}
|
|
70
75
|
static fromBytes(bytes) {
|
|
@@ -134,6 +139,9 @@ var CuckooFilter = class CuckooFilter {
|
|
|
134
139
|
}
|
|
135
140
|
add(key) {
|
|
136
141
|
this.#hash(key);
|
|
142
|
+
this.#insert();
|
|
143
|
+
}
|
|
144
|
+
#insert() {
|
|
137
145
|
if (this.#replace(this.#i1, 0, this.#fp) || this.#replace(this.#i2, 0, this.#fp)) {
|
|
138
146
|
this.#count++;
|
|
139
147
|
return;
|
|
@@ -202,6 +210,9 @@ var CuckooFilter = class CuckooFilter {
|
|
|
202
210
|
}
|
|
203
211
|
#hash(key) {
|
|
204
212
|
require_hasher.hash128KeyInto(key, this.#seed, HASH);
|
|
213
|
+
this.#derive();
|
|
214
|
+
}
|
|
215
|
+
#derive() {
|
|
205
216
|
this.#fp = HASH.w1 >>> 32 - this.#f || 1;
|
|
206
217
|
this.#i1 = require_hasher.reduce(HASH.w0, this.#buckets);
|
|
207
218
|
this.#i2 = this.#alt(this.#i1, this.#fp);
|
package/dist/cuckoo/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { i as hash128KeyInto, u as reduce } from "../hasher-
|
|
1
|
+
import { i as hash128KeyInto, u as reduce } from "../hasher-BQxNrCQC.js";
|
|
2
2
|
import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
|
|
3
3
|
import { i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
|
|
4
|
+
import { t as DistinctHashes } from "../distinct-BhxDB8mW.js";
|
|
4
5
|
function cuckooSizing(n, epsilon) {
|
|
5
6
|
assertProbability(epsilon, "epsilon");
|
|
6
7
|
const f = Math.max(4, Math.ceil(Math.log2(8 / epsilon)));
|
|
@@ -53,17 +54,21 @@ var CuckooFilter = class CuckooFilter {
|
|
|
53
54
|
});
|
|
54
55
|
}
|
|
55
56
|
static from(keys, epsilon, options = {}) {
|
|
56
|
-
const
|
|
57
|
-
const distinct = [];
|
|
57
|
+
const distinct = new DistinctHashes(4);
|
|
58
58
|
for (const key of keys) {
|
|
59
59
|
hash128KeyInto(key, options.seed ?? 0, HASH);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
distinct.add(HASH);
|
|
61
|
+
}
|
|
62
|
+
const f = CuckooFilter.create(Math.max(1, distinct.size), epsilon, options);
|
|
63
|
+
const words = distinct.words;
|
|
64
|
+
for (let at = 0; at < words.length; at += 4) {
|
|
65
|
+
HASH.w0 = words[at] ?? 0;
|
|
66
|
+
HASH.w1 = words[at + 1] ?? 0;
|
|
67
|
+
HASH.w2 = words[at + 2] ?? 0;
|
|
68
|
+
HASH.w3 = words[at + 3] ?? 0;
|
|
69
|
+
f.#derive();
|
|
70
|
+
f.#insert();
|
|
64
71
|
}
|
|
65
|
-
const f = CuckooFilter.create(Math.max(1, distinct.length), epsilon, options);
|
|
66
|
-
for (const k of distinct) f.add(k);
|
|
67
72
|
return f;
|
|
68
73
|
}
|
|
69
74
|
static fromBytes(bytes) {
|
|
@@ -133,6 +138,9 @@ var CuckooFilter = class CuckooFilter {
|
|
|
133
138
|
}
|
|
134
139
|
add(key) {
|
|
135
140
|
this.#hash(key);
|
|
141
|
+
this.#insert();
|
|
142
|
+
}
|
|
143
|
+
#insert() {
|
|
136
144
|
if (this.#replace(this.#i1, 0, this.#fp) || this.#replace(this.#i2, 0, this.#fp)) {
|
|
137
145
|
this.#count++;
|
|
138
146
|
return;
|
|
@@ -201,6 +209,9 @@ var CuckooFilter = class CuckooFilter {
|
|
|
201
209
|
}
|
|
202
210
|
#hash(key) {
|
|
203
211
|
hash128KeyInto(key, this.#seed, HASH);
|
|
212
|
+
this.#derive();
|
|
213
|
+
}
|
|
214
|
+
#derive() {
|
|
204
215
|
this.#fp = HASH.w1 >>> 32 - this.#f || 1;
|
|
205
216
|
this.#i1 = reduce(HASH.w0, this.#buckets);
|
|
206
217
|
this.#i2 = this.#alt(this.#i1, this.#fp);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/core/distinct.ts
|
|
2
|
+
const START = 1024;
|
|
3
|
+
var DistinctHashes = class {
|
|
4
|
+
#width;
|
|
5
|
+
#words;
|
|
6
|
+
#table = new Int32Array(2 * START);
|
|
7
|
+
#size = 0;
|
|
8
|
+
constructor(width) {
|
|
9
|
+
this.#width = width;
|
|
10
|
+
this.#words = new Uint32Array(START * width);
|
|
11
|
+
}
|
|
12
|
+
get size() {
|
|
13
|
+
return this.#size;
|
|
14
|
+
}
|
|
15
|
+
get words() {
|
|
16
|
+
return this.#words.subarray(0, this.#size * this.#width);
|
|
17
|
+
}
|
|
18
|
+
add(hash) {
|
|
19
|
+
const width = this.#width;
|
|
20
|
+
const w0 = hash.w0 >>> 0;
|
|
21
|
+
const w1 = hash.w1 >>> 0;
|
|
22
|
+
const w2 = hash.w2 >>> 0;
|
|
23
|
+
const w3 = hash.w3 >>> 0;
|
|
24
|
+
if ((this.#size + 1) * width > this.#words.length) this.#grow();
|
|
25
|
+
const words = this.#words;
|
|
26
|
+
const mask = this.#table.length - 1;
|
|
27
|
+
let slot = w0 & mask;
|
|
28
|
+
for (;;) {
|
|
29
|
+
const held = this.#table[slot] ?? 0;
|
|
30
|
+
if (held === 0) break;
|
|
31
|
+
const at = (held - 1) * width;
|
|
32
|
+
if (words[at] === w0 && words[at + 1] === w1 && (width === 2 || words[at + 2] === w2 && words[at + 3] === w3)) return false;
|
|
33
|
+
slot = slot + 1 & mask;
|
|
34
|
+
}
|
|
35
|
+
const at = this.#size * width;
|
|
36
|
+
words[at] = w0;
|
|
37
|
+
words[at + 1] = w1;
|
|
38
|
+
if (width === 4) {
|
|
39
|
+
words[at + 2] = w2;
|
|
40
|
+
words[at + 3] = w3;
|
|
41
|
+
}
|
|
42
|
+
this.#size++;
|
|
43
|
+
this.#table[slot] = this.#size;
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
#grow() {
|
|
47
|
+
const words = new Uint32Array(this.#words.length * 2);
|
|
48
|
+
words.set(this.#words);
|
|
49
|
+
this.#words = words;
|
|
50
|
+
this.#table = new Int32Array(this.#table.length * 2);
|
|
51
|
+
for (let i = 0; i < this.#size; i++) this.#place(i);
|
|
52
|
+
}
|
|
53
|
+
#place(i) {
|
|
54
|
+
const mask = this.#table.length - 1;
|
|
55
|
+
let slot = (this.#words[i * this.#width] ?? 0) & mask;
|
|
56
|
+
while ((this.#table[slot] ?? 0) !== 0) slot = slot + 1 & mask;
|
|
57
|
+
this.#table[slot] = i + 1;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { DistinctHashes as t };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/core/distinct.ts
|
|
2
|
+
const START = 1024;
|
|
3
|
+
var DistinctHashes = class {
|
|
4
|
+
#width;
|
|
5
|
+
#words;
|
|
6
|
+
#table = new Int32Array(2 * START);
|
|
7
|
+
#size = 0;
|
|
8
|
+
constructor(width) {
|
|
9
|
+
this.#width = width;
|
|
10
|
+
this.#words = new Uint32Array(START * width);
|
|
11
|
+
}
|
|
12
|
+
get size() {
|
|
13
|
+
return this.#size;
|
|
14
|
+
}
|
|
15
|
+
get words() {
|
|
16
|
+
return this.#words.subarray(0, this.#size * this.#width);
|
|
17
|
+
}
|
|
18
|
+
add(hash) {
|
|
19
|
+
const width = this.#width;
|
|
20
|
+
const w0 = hash.w0 >>> 0;
|
|
21
|
+
const w1 = hash.w1 >>> 0;
|
|
22
|
+
const w2 = hash.w2 >>> 0;
|
|
23
|
+
const w3 = hash.w3 >>> 0;
|
|
24
|
+
if ((this.#size + 1) * width > this.#words.length) this.#grow();
|
|
25
|
+
const words = this.#words;
|
|
26
|
+
const mask = this.#table.length - 1;
|
|
27
|
+
let slot = w0 & mask;
|
|
28
|
+
for (;;) {
|
|
29
|
+
const held = this.#table[slot] ?? 0;
|
|
30
|
+
if (held === 0) break;
|
|
31
|
+
const at = (held - 1) * width;
|
|
32
|
+
if (words[at] === w0 && words[at + 1] === w1 && (width === 2 || words[at + 2] === w2 && words[at + 3] === w3)) return false;
|
|
33
|
+
slot = slot + 1 & mask;
|
|
34
|
+
}
|
|
35
|
+
const at = this.#size * width;
|
|
36
|
+
words[at] = w0;
|
|
37
|
+
words[at + 1] = w1;
|
|
38
|
+
if (width === 4) {
|
|
39
|
+
words[at + 2] = w2;
|
|
40
|
+
words[at + 3] = w3;
|
|
41
|
+
}
|
|
42
|
+
this.#size++;
|
|
43
|
+
this.#table[slot] = this.#size;
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
#grow() {
|
|
47
|
+
const words = new Uint32Array(this.#words.length * 2);
|
|
48
|
+
words.set(this.#words);
|
|
49
|
+
this.#words = words;
|
|
50
|
+
this.#table = new Int32Array(this.#table.length * 2);
|
|
51
|
+
for (let i = 0; i < this.#size; i++) this.#place(i);
|
|
52
|
+
}
|
|
53
|
+
#place(i) {
|
|
54
|
+
const mask = this.#table.length - 1;
|
|
55
|
+
let slot = (this.#words[i * this.#width] ?? 0) & mask;
|
|
56
|
+
while ((this.#table[slot] ?? 0) !== 0) slot = slot + 1 & mask;
|
|
57
|
+
this.#table[slot] = i + 1;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
Object.defineProperty(exports, "DistinctHashes", {
|
|
62
|
+
enumerable: true,
|
|
63
|
+
get: function() {
|
|
64
|
+
return DistinctHashes;
|
|
65
|
+
}
|
|
66
|
+
});
|
package/dist/fuse/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_hasher = require("../hasher-
|
|
2
|
+
const require_hasher = require("../hasher-CKLP9Oqe.cjs");
|
|
3
3
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
4
|
+
const require_distinct = require("../distinct-Ck5PKuCS.cjs");
|
|
4
5
|
//#region src/fuse/fuse.ts
|
|
5
6
|
const ARITY = 3;
|
|
6
7
|
const TYPE_FUSE8 = 3;
|
|
@@ -131,18 +132,12 @@ function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
|
|
|
131
132
|
throw new BinaryFuseBuildError("binary fuse construction failed");
|
|
132
133
|
}
|
|
133
134
|
function buildState(keys, alloc) {
|
|
134
|
-
const
|
|
135
|
-
const seen = new Set();
|
|
135
|
+
const distinct = new require_distinct.DistinctHashes(2);
|
|
136
136
|
for (const key of keys) {
|
|
137
137
|
require_hasher.hash128KeyInto(key, 0, scratchHash);
|
|
138
|
-
|
|
139
|
-
const hi = scratchHash.w1 >>> 0;
|
|
140
|
-
const id = `${String(lo)},${String(hi)}`;
|
|
141
|
-
if (seen.has(id)) continue;
|
|
142
|
-
seen.add(id);
|
|
143
|
-
hashList.push(lo, hi);
|
|
138
|
+
distinct.add(scratchHash);
|
|
144
139
|
}
|
|
145
|
-
const size =
|
|
140
|
+
const size = distinct.size;
|
|
146
141
|
const params = computeParams(size);
|
|
147
142
|
if (size === 0) return {
|
|
148
143
|
fp: alloc(0),
|
|
@@ -150,7 +145,7 @@ function buildState(keys, alloc) {
|
|
|
150
145
|
params,
|
|
151
146
|
size: 0
|
|
152
147
|
};
|
|
153
|
-
const hashes =
|
|
148
|
+
const hashes = distinct.words;
|
|
154
149
|
const fp = alloc(params.arrayLength);
|
|
155
150
|
return {
|
|
156
151
|
fp,
|
package/dist/fuse/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { i as hash128KeyInto, n as RLO, o as mul64, r as fmix64, t as RHI } from "../hasher-
|
|
1
|
+
import { i as hash128KeyInto, n as RLO, o as mul64, r as fmix64, t as RHI } from "../hasher-BQxNrCQC.js";
|
|
2
2
|
import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError } from "../serialize-CMSYFym-.js";
|
|
3
|
+
import { t as DistinctHashes } from "../distinct-BhxDB8mW.js";
|
|
3
4
|
//#region src/fuse/fuse.ts
|
|
4
5
|
const ARITY = 3;
|
|
5
6
|
const TYPE_FUSE8 = 3;
|
|
@@ -130,18 +131,12 @@ function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
|
|
|
130
131
|
throw new BinaryFuseBuildError("binary fuse construction failed");
|
|
131
132
|
}
|
|
132
133
|
function buildState(keys, alloc) {
|
|
133
|
-
const
|
|
134
|
-
const seen = new Set();
|
|
134
|
+
const distinct = new DistinctHashes(2);
|
|
135
135
|
for (const key of keys) {
|
|
136
136
|
hash128KeyInto(key, 0, scratchHash);
|
|
137
|
-
|
|
138
|
-
const hi = scratchHash.w1 >>> 0;
|
|
139
|
-
const id = `${String(lo)},${String(hi)}`;
|
|
140
|
-
if (seen.has(id)) continue;
|
|
141
|
-
seen.add(id);
|
|
142
|
-
hashList.push(lo, hi);
|
|
137
|
+
distinct.add(scratchHash);
|
|
143
138
|
}
|
|
144
|
-
const size =
|
|
139
|
+
const size = distinct.size;
|
|
145
140
|
const params = computeParams(size);
|
|
146
141
|
if (size === 0) return {
|
|
147
142
|
fp: alloc(0),
|
|
@@ -149,7 +144,7 @@ function buildState(keys, alloc) {
|
|
|
149
144
|
params,
|
|
150
145
|
size: 0
|
|
151
146
|
};
|
|
152
|
-
const hashes =
|
|
147
|
+
const hashes = distinct.words;
|
|
153
148
|
const fp = alloc(params.arrayLength);
|
|
154
149
|
return {
|
|
155
150
|
fp,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as
|
|
1
|
+
import { n as encodedBytes, t as encodeKey } from "./bytes-oOWlu7N5.js";
|
|
2
2
|
//#region src/core/hasher.ts
|
|
3
3
|
let RLO = 0;
|
|
4
4
|
let RHI = 0;
|
|
@@ -166,24 +166,9 @@ function computeLanes(bytes, seed, len) {
|
|
|
166
166
|
LANES.w2 = h3;
|
|
167
167
|
LANES.w3 = h4;
|
|
168
168
|
}
|
|
169
|
-
const keyEncoder = new TextEncoder();
|
|
170
|
-
let keyBuf = new Uint8Array(256);
|
|
171
|
-
let encBytes = keyBuf;
|
|
172
|
-
let encLen = 0;
|
|
173
|
-
function encodeKey(key) {
|
|
174
|
-
if (typeof key === "string") {
|
|
175
|
-
const cap = key.length * 3;
|
|
176
|
-
if (keyBuf.length < cap) keyBuf = new Uint8Array(cap);
|
|
177
|
-
encLen = keyEncoder.encodeInto(key, keyBuf).written;
|
|
178
|
-
encBytes = keyBuf;
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
encBytes = normalize(key);
|
|
182
|
-
encLen = encBytes.length;
|
|
183
|
-
}
|
|
184
169
|
function keyToLanes(key, seed) {
|
|
185
|
-
encodeKey(key);
|
|
186
|
-
computeLanes(
|
|
170
|
+
const len = encodeKey(key);
|
|
171
|
+
computeLanes(encodedBytes(), seed, len);
|
|
187
172
|
}
|
|
188
173
|
function hash128KeyInto(key, seed, out) {
|
|
189
174
|
keyToLanes(key, seed);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_bytes = require("./bytes-
|
|
1
|
+
const require_bytes = require("./bytes-DWGupBUE.cjs");
|
|
2
2
|
//#region src/core/hasher.ts
|
|
3
3
|
let RLO = 0;
|
|
4
4
|
let RHI = 0;
|
|
@@ -166,24 +166,9 @@ function computeLanes(bytes, seed, len) {
|
|
|
166
166
|
LANES.w2 = h3;
|
|
167
167
|
LANES.w3 = h4;
|
|
168
168
|
}
|
|
169
|
-
const keyEncoder = new TextEncoder();
|
|
170
|
-
let keyBuf = new Uint8Array(256);
|
|
171
|
-
let encBytes = keyBuf;
|
|
172
|
-
let encLen = 0;
|
|
173
|
-
function encodeKey(key) {
|
|
174
|
-
if (typeof key === "string") {
|
|
175
|
-
const cap = key.length * 3;
|
|
176
|
-
if (keyBuf.length < cap) keyBuf = new Uint8Array(cap);
|
|
177
|
-
encLen = keyEncoder.encodeInto(key, keyBuf).written;
|
|
178
|
-
encBytes = keyBuf;
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
encBytes = require_bytes.normalize(key);
|
|
182
|
-
encLen = encBytes.length;
|
|
183
|
-
}
|
|
184
169
|
function keyToLanes(key, seed) {
|
|
185
|
-
encodeKey(key);
|
|
186
|
-
computeLanes(
|
|
170
|
+
const len = require_bytes.encodeKey(key);
|
|
171
|
+
computeLanes(require_bytes.encodedBytes(), seed, len);
|
|
187
172
|
}
|
|
188
173
|
function hash128KeyInto(key, seed, out) {
|
|
189
174
|
keyToLanes(key, seed);
|
package/dist/hll/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_hasher = require("../hasher-
|
|
2
|
+
const require_hasher = require("../hasher-CKLP9Oqe.cjs");
|
|
3
3
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
4
4
|
const require_params = require("../params-UTZbJ22c.cjs");
|
|
5
5
|
function hllSizing(relativeError) {
|
package/dist/hll/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as hash128KeyInto } from "../hasher-
|
|
1
|
+
import { i as hash128KeyInto } from "../hasher-BQxNrCQC.js";
|
|
2
2
|
import { a as TruncatedError, c as assertBodyLength, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
|
|
3
3
|
import { i as assertProbability, o as assertUint32, t as ParamError } from "../params-CeajSrwv.js";
|
|
4
4
|
function hllSizing(relativeError) {
|
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
package/dist/scalable/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_sizing = require("../sizing-Ch0SDdza.cjs");
|
|
3
|
-
const require_hasher = require("../hasher-
|
|
3
|
+
const require_hasher = require("../hasher-CKLP9Oqe.cjs");
|
|
4
4
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
5
5
|
const require_params = require("../params-UTZbJ22c.cjs");
|
|
6
6
|
//#region src/scalable/scalable.ts
|
package/dist/scalable/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as BitSet, t as bloomSizing } from "../sizing-zxCBlyhO.js";
|
|
2
|
-
import { i as hash128KeyInto, l as probeLanesInto, s as probeAt } from "../hasher-
|
|
2
|
+
import { i as hash128KeyInto, l as probeLanesInto, s as probeAt } from "../hasher-BQxNrCQC.js";
|
|
3
3
|
import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
|
|
4
4
|
import { i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
|
|
5
5
|
//#region src/scalable/scalable.ts
|
package/dist/topk/index.cjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_bytes = require("../bytes-
|
|
2
|
+
const require_bytes = require("../bytes-DWGupBUE.cjs");
|
|
3
3
|
const require_serialize = require("../serialize-CHikZ4GH.cjs");
|
|
4
4
|
const require_params = require("../params-UTZbJ22c.cjs");
|
|
5
5
|
//#region src/topk/halfsip.ts
|
|
6
|
-
function halfSipHash13(bytes, k0, k1) {
|
|
6
|
+
function halfSipHash13(bytes, k0, k1, len = bytes.length) {
|
|
7
7
|
let v0 = k0 | 0;
|
|
8
8
|
let v1 = k1 | 0;
|
|
9
9
|
let v2 = 1819895653 ^ k0 | 0;
|
|
10
10
|
let v3 = 1952801890 ^ k1 | 0;
|
|
11
|
-
const len = bytes.length;
|
|
12
11
|
const end = len & -4;
|
|
13
12
|
for (let i = 0; i < end; i += 4) {
|
|
14
13
|
const m = (bytes[i] ?? 0) | (bytes[i + 1] ?? 0) << 8 | (bytes[i + 2] ?? 0) << 16 | (bytes[i + 3] ?? 0) << 24;
|
|
@@ -250,29 +249,28 @@ var TopK = class TopK {
|
|
|
250
249
|
while (size < this.#capacity && topKLoadLimit(size) < entries) size *= 2;
|
|
251
250
|
return size;
|
|
252
251
|
}
|
|
253
|
-
#slotHolds(slot, bytes) {
|
|
254
|
-
|
|
255
|
-
if (len !== bytes.length) return false;
|
|
252
|
+
#slotHolds(slot, bytes, len) {
|
|
253
|
+
if ((this.#keyLengths[slot] ?? 0) !== len) return false;
|
|
256
254
|
const at = this.#keyOffsets[slot] ?? 0;
|
|
257
255
|
for (let i = 0; i < len; i++) if (this.#arena[at + i] !== bytes[i]) return false;
|
|
258
256
|
return true;
|
|
259
257
|
}
|
|
260
|
-
#storeKey(slot, bytes) {
|
|
258
|
+
#storeKey(slot, bytes, len = bytes.length) {
|
|
261
259
|
let arena = this.#arena;
|
|
262
|
-
if (this.#arenaLen +
|
|
260
|
+
if (this.#arenaLen + len > arena.length) {
|
|
263
261
|
let size = arena.length;
|
|
264
|
-
while (size < this.#arenaLen +
|
|
262
|
+
while (size < this.#arenaLen + len) size *= 2;
|
|
265
263
|
const grown = new Uint8Array(size);
|
|
266
264
|
grown.set(arena.subarray(0, this.#arenaLen));
|
|
267
265
|
arena = grown;
|
|
268
266
|
this.#arena = grown;
|
|
269
267
|
}
|
|
270
|
-
arena.set(bytes, this.#arenaLen);
|
|
268
|
+
arena.set(len === bytes.length ? bytes : bytes.subarray(0, len), this.#arenaLen);
|
|
271
269
|
this.#keyOffsets[slot] = this.#arenaLen;
|
|
272
|
-
this.#keyLengths[slot] =
|
|
273
|
-
this.#arenaLen +=
|
|
270
|
+
this.#keyLengths[slot] = len;
|
|
271
|
+
this.#arenaLen += len;
|
|
274
272
|
}
|
|
275
|
-
#slotFor(bytes) {
|
|
273
|
+
#slotFor(bytes, len = bytes.length) {
|
|
276
274
|
if (!this.#keyed) {
|
|
277
275
|
const key = crypto.getRandomValues(new Uint32Array(2));
|
|
278
276
|
this.#k0 = key[0] ?? 0;
|
|
@@ -280,22 +278,23 @@ var TopK = class TopK {
|
|
|
280
278
|
this.#keyed = true;
|
|
281
279
|
}
|
|
282
280
|
const mask = this.#size - 1;
|
|
283
|
-
let slot = halfSipHash13(bytes, this.#k0, this.#k1) & mask;
|
|
281
|
+
let slot = halfSipHash13(bytes, this.#k0, this.#k1, len) & mask;
|
|
284
282
|
for (;;) {
|
|
285
283
|
if ((this.#counts[slot] ?? 0) === 0) return slot;
|
|
286
|
-
if (this.#slotHolds(slot, bytes)) return slot;
|
|
284
|
+
if (this.#slotHolds(slot, bytes, len)) return slot;
|
|
287
285
|
slot = slot + 1 & mask;
|
|
288
286
|
}
|
|
289
287
|
}
|
|
290
288
|
add(key, count = 1) {
|
|
291
289
|
require_params.assertPositiveInt(count, "count");
|
|
292
290
|
if (this.#total + count > Number.MAX_SAFE_INTEGER) throw new TopKOverflowError(`adding ${String(count)} would carry the total past ${String(Number.MAX_SAFE_INTEGER)}`);
|
|
293
|
-
const
|
|
294
|
-
const
|
|
291
|
+
const len = require_bytes.encodeKey(key);
|
|
292
|
+
const bytes = require_bytes.encodedBytes();
|
|
293
|
+
const slot = this.#slotFor(bytes, len);
|
|
295
294
|
const stored = this.#counts[slot] ?? 0;
|
|
296
295
|
if (stored + count > 4294967295) throw new TopKOverflowError(`adding ${String(count)} would carry a stored count past ${String(4294967295)}`);
|
|
297
296
|
if (stored === 0) {
|
|
298
|
-
this.#storeKey(slot, bytes);
|
|
297
|
+
this.#storeKey(slot, bytes, len);
|
|
299
298
|
this.#entries++;
|
|
300
299
|
}
|
|
301
300
|
this.#counts[slot] = stored + count;
|
|
@@ -306,8 +305,8 @@ var TopK = class TopK {
|
|
|
306
305
|
}
|
|
307
306
|
}
|
|
308
307
|
count(key) {
|
|
309
|
-
const
|
|
310
|
-
const stored = this.#counts[this.#slotFor(
|
|
308
|
+
const len = require_bytes.encodeKey(key);
|
|
309
|
+
const stored = this.#counts[this.#slotFor(require_bytes.encodedBytes(), len)] ?? 0;
|
|
311
310
|
return stored === 0 ? 0 : stored + this.#offset;
|
|
312
311
|
}
|
|
313
312
|
top(k) {
|
package/dist/topk/index.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { t as
|
|
1
|
+
import { n as encodedBytes, t as encodeKey } from "../bytes-oOWlu7N5.js";
|
|
2
2
|
import { a as TruncatedError, c as assertBodyLength, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
|
|
3
3
|
import { i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
|
|
4
4
|
//#region src/topk/halfsip.ts
|
|
5
|
-
function halfSipHash13(bytes, k0, k1) {
|
|
5
|
+
function halfSipHash13(bytes, k0, k1, len = bytes.length) {
|
|
6
6
|
let v0 = k0 | 0;
|
|
7
7
|
let v1 = k1 | 0;
|
|
8
8
|
let v2 = 1819895653 ^ k0 | 0;
|
|
9
9
|
let v3 = 1952801890 ^ k1 | 0;
|
|
10
|
-
const len = bytes.length;
|
|
11
10
|
const end = len & -4;
|
|
12
11
|
for (let i = 0; i < end; i += 4) {
|
|
13
12
|
const m = (bytes[i] ?? 0) | (bytes[i + 1] ?? 0) << 8 | (bytes[i + 2] ?? 0) << 16 | (bytes[i + 3] ?? 0) << 24;
|
|
@@ -249,29 +248,28 @@ var TopK = class TopK {
|
|
|
249
248
|
while (size < this.#capacity && topKLoadLimit(size) < entries) size *= 2;
|
|
250
249
|
return size;
|
|
251
250
|
}
|
|
252
|
-
#slotHolds(slot, bytes) {
|
|
253
|
-
|
|
254
|
-
if (len !== bytes.length) return false;
|
|
251
|
+
#slotHolds(slot, bytes, len) {
|
|
252
|
+
if ((this.#keyLengths[slot] ?? 0) !== len) return false;
|
|
255
253
|
const at = this.#keyOffsets[slot] ?? 0;
|
|
256
254
|
for (let i = 0; i < len; i++) if (this.#arena[at + i] !== bytes[i]) return false;
|
|
257
255
|
return true;
|
|
258
256
|
}
|
|
259
|
-
#storeKey(slot, bytes) {
|
|
257
|
+
#storeKey(slot, bytes, len = bytes.length) {
|
|
260
258
|
let arena = this.#arena;
|
|
261
|
-
if (this.#arenaLen +
|
|
259
|
+
if (this.#arenaLen + len > arena.length) {
|
|
262
260
|
let size = arena.length;
|
|
263
|
-
while (size < this.#arenaLen +
|
|
261
|
+
while (size < this.#arenaLen + len) size *= 2;
|
|
264
262
|
const grown = new Uint8Array(size);
|
|
265
263
|
grown.set(arena.subarray(0, this.#arenaLen));
|
|
266
264
|
arena = grown;
|
|
267
265
|
this.#arena = grown;
|
|
268
266
|
}
|
|
269
|
-
arena.set(bytes, this.#arenaLen);
|
|
267
|
+
arena.set(len === bytes.length ? bytes : bytes.subarray(0, len), this.#arenaLen);
|
|
270
268
|
this.#keyOffsets[slot] = this.#arenaLen;
|
|
271
|
-
this.#keyLengths[slot] =
|
|
272
|
-
this.#arenaLen +=
|
|
269
|
+
this.#keyLengths[slot] = len;
|
|
270
|
+
this.#arenaLen += len;
|
|
273
271
|
}
|
|
274
|
-
#slotFor(bytes) {
|
|
272
|
+
#slotFor(bytes, len = bytes.length) {
|
|
275
273
|
if (!this.#keyed) {
|
|
276
274
|
const key = crypto.getRandomValues(new Uint32Array(2));
|
|
277
275
|
this.#k0 = key[0] ?? 0;
|
|
@@ -279,22 +277,23 @@ var TopK = class TopK {
|
|
|
279
277
|
this.#keyed = true;
|
|
280
278
|
}
|
|
281
279
|
const mask = this.#size - 1;
|
|
282
|
-
let slot = halfSipHash13(bytes, this.#k0, this.#k1) & mask;
|
|
280
|
+
let slot = halfSipHash13(bytes, this.#k0, this.#k1, len) & mask;
|
|
283
281
|
for (;;) {
|
|
284
282
|
if ((this.#counts[slot] ?? 0) === 0) return slot;
|
|
285
|
-
if (this.#slotHolds(slot, bytes)) return slot;
|
|
283
|
+
if (this.#slotHolds(slot, bytes, len)) return slot;
|
|
286
284
|
slot = slot + 1 & mask;
|
|
287
285
|
}
|
|
288
286
|
}
|
|
289
287
|
add(key, count = 1) {
|
|
290
288
|
assertPositiveInt(count, "count");
|
|
291
289
|
if (this.#total + count > Number.MAX_SAFE_INTEGER) throw new TopKOverflowError(`adding ${String(count)} would carry the total past ${String(Number.MAX_SAFE_INTEGER)}`);
|
|
292
|
-
const
|
|
293
|
-
const
|
|
290
|
+
const len = encodeKey(key);
|
|
291
|
+
const bytes = encodedBytes();
|
|
292
|
+
const slot = this.#slotFor(bytes, len);
|
|
294
293
|
const stored = this.#counts[slot] ?? 0;
|
|
295
294
|
if (stored + count > 4294967295) throw new TopKOverflowError(`adding ${String(count)} would carry a stored count past ${String(4294967295)}`);
|
|
296
295
|
if (stored === 0) {
|
|
297
|
-
this.#storeKey(slot, bytes);
|
|
296
|
+
this.#storeKey(slot, bytes, len);
|
|
298
297
|
this.#entries++;
|
|
299
298
|
}
|
|
300
299
|
this.#counts[slot] = stored + count;
|
|
@@ -305,8 +304,8 @@ var TopK = class TopK {
|
|
|
305
304
|
}
|
|
306
305
|
}
|
|
307
306
|
count(key) {
|
|
308
|
-
const
|
|
309
|
-
const stored = this.#counts[this.#slotFor(
|
|
307
|
+
const len = encodeKey(key);
|
|
308
|
+
const stored = this.#counts[this.#slotFor(encodedBytes(), len)] ?? 0;
|
|
310
309
|
return stored === 0 ? 0 : stored + this.#offset;
|
|
311
310
|
}
|
|
312
311
|
top(k) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "distillate",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Probabilistic data structures for JavaScript. Space-efficient, approximate-membership filters (Bloom, Blocked Bloom, Binary Fuse) with tunable error and a portable binary format; zero dependencies, universal.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bloom-filter",
|
|
@@ -113,17 +113,17 @@
|
|
|
113
113
|
],
|
|
114
114
|
"devDependencies": {
|
|
115
115
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
116
|
-
"@microsoft/api-extractor": "^7.59.
|
|
117
|
-
"@types/node": "^22.20.
|
|
118
|
-
"@vitest/coverage-v8": "^5.0.
|
|
119
|
-
"fast-check": "^4.10.
|
|
116
|
+
"@microsoft/api-extractor": "^7.59.2",
|
|
117
|
+
"@types/node": "^22.20.4",
|
|
118
|
+
"@vitest/coverage-v8": "^5.0.2",
|
|
119
|
+
"fast-check": "^4.10.2",
|
|
120
120
|
"mitata": "^1.0.34",
|
|
121
121
|
"publint": "^0.3.24",
|
|
122
122
|
"tsdown": "^0.23.0",
|
|
123
|
-
"tsx": "^4.23.
|
|
123
|
+
"tsx": "^4.23.15",
|
|
124
124
|
"typedoc": "^0.28.20",
|
|
125
125
|
"typescript": "^5.9.3",
|
|
126
|
-
"vitest": "^5.0.
|
|
126
|
+
"vitest": "^5.0.2"
|
|
127
127
|
},
|
|
128
128
|
"engines": {
|
|
129
129
|
"node": ">=22"
|
package/dist/bytes-Be7tq1F7.js
DELETED
|
@@ -1,9 +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
|
-
export { normalize as t };
|
package/dist/bytes-D2duG1jq.cjs
DELETED
|
@@ -1,14 +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
|
-
Object.defineProperty(exports, "normalize", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
get: function() {
|
|
12
|
-
return normalize;
|
|
13
|
-
}
|
|
14
|
-
});
|