min-mphash 0.5.0 → 0.5.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/README.en.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [中文 README](./README.zh.md)
6
6
 
7
- `MinMPHash` can map a set of n strings to the integer range `[0, n-1]` without any collisions.
7
+ `MinMPHash` can map a set of n strings to the integer range `[0, n-1]` without any collisions. If only the hash function is used, the package size is less than 3KB (Gzip).
8
8
 
9
9
  `MinMPLookup` is a minimal perfect lookup table tool implemented based on `MinMPHash`.
10
10
 
@@ -121,6 +121,19 @@ You might think that hash functions like MD5 or SHA-1 can also generate identifi
121
121
  npm install min-mphash
122
122
  ```
123
123
 
124
+ This package only provides ESM, and using build tools can effectively perform tree-shaking to reduce the size.
125
+
126
+ ```
127
+ // hash build & hush function
128
+ min-mphash/index.js 34.7 kB
129
+ min-mphash/index.min.js 14.6 kB 4.9 kB(Gzip)
130
+
131
+
132
+ // hush function only
133
+ min-mphash/runtime.js 18.3 kB
134
+ min-mphash/runtime.min.js 7.9 kB 2.8 kB(Gzip)
135
+ ```
136
+
124
137
  ### MinMPHash Usage
125
138
 
126
139
  This is the core function, used to map a set of strings to integers in `[0, n-1]`.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  [中文 README](./README.zh.md)
8
8
 
9
- TypeScript/JavaScript 平台上的最小完美哈希与查找工具实现。
9
+ TypeScript/JavaScript 平台上的最小完美哈希与查找工具实现。如果只使用哈希函数包体积小于 3KB(Gzip)。
10
10
 
11
11
  `MinMPHash` 可以把一组数量为 n 的字符串映射到 `[0, n-1]` 的整数范围内,且不会有冲突。
12
12
 
@@ -18,7 +18,7 @@ TypeScript/JavaScript 平台上的最小完美哈希与查找工具实现。
18
18
 
19
19
  ---
20
20
 
21
- `MinMPHash` can map a set of n strings to the integer range `[0, n-1]` without any collisions.
21
+ `MinMPHash` can map a set of n strings to the integer range `[0, n-1]` without any collisions. If only the hash function is used, the package size is less than 3KB (Gzip).
22
22
 
23
23
  `MinMPLookup` is a minimal perfect lookup table tool implemented based on `MinMPHash`.
24
24
 
@@ -135,6 +135,19 @@ You might think that hash functions like MD5 or SHA-1 can also generate identifi
135
135
  npm install min-mphash
136
136
  ```
137
137
 
138
+ This package only provides ESM, and using build tools can effectively perform tree-shaking to reduce the size.
139
+
140
+ ```
141
+ // hash build & hush function
142
+ min-mphash/index.js 34.7 kB
143
+ min-mphash/index.min.js 14.6 kB 4.9 kB(Gzip)
144
+
145
+
146
+ // hush function only
147
+ min-mphash/runtime.js 18.3 kB
148
+ min-mphash/runtime.min.js 7.9 kB 2.8 kB(Gzip)
149
+ ```
150
+
138
151
  ### MinMPHash Usage
139
152
 
140
153
  This is the core function, used to map a set of strings to integers in `[0, n-1]`.
package/README.zh.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [English README](./README.en.md)
6
6
 
7
- TypeScript/JavaScript 平台上的最小完美哈希与查找工具实现。
7
+ TypeScript/JavaScript 平台上的最小完美哈希与查找工具实现。如果只使用哈希函数包体积小于 3KB(Gzip)。
8
8
 
9
9
  `MinMPHash` 可以把一组数量为 n 的字符串映射到 `[0, n-1]` 的整数范围内,且不会有冲突。
10
10
 
@@ -123,6 +123,19 @@ let found = Object.entries(FontMapWithHash).find(([family, hashes]) =>
123
123
  npm install min-mphash
124
124
  ```
125
125
 
126
+ 此包仅提供 ESM,使用构建工具可以很的进行 tree-shaking 以减小体积。
127
+
128
+ ```
129
+ // hash build & hush function
130
+ min-mphash/index.js 34.7 kB
131
+ min-mphash/index.min.js 14.6 kB 4.9 kB(Gzip)
132
+
133
+
134
+ // hush function only
135
+ min-mphash/runtime.js 18.3 kB
136
+ min-mphash/runtime.min.js 7.9 kB 2.8 kB(Gzip)
137
+ ```
138
+
126
139
  ### MinMPHash 最小完美哈希的使用
127
140
 
128
141
  这是最核心的功能,用于将一组字符串映射到 `[0, n-1]` 的整数。
@@ -93,12 +93,12 @@ export declare function serializeMinMPLookupDict(dict: IMinMPLookupDict): Uint8A
93
93
  *```
94
94
  */
95
95
  export declare class MinMPLookup {
96
- private dict;
97
96
  private mph;
97
+ private dict;
98
98
  private _invertedIndex;
99
99
  static fromCompressed(data: Uint8Array): Promise<MinMPLookup>;
100
100
  static fromBinary(data: Uint8Array): MinMPLookup;
101
- constructor(dict: IMinMPLookupDict);
101
+ constructor(dict: IMinMPLookupDict | Uint8Array);
102
102
  private buildInvertedIndex;
103
103
  /**
104
104
  * 查找 value 对应的第一个 key
package/dist/index.js CHANGED
@@ -693,7 +693,7 @@ function serializeMinMPLookupDict(dict) {
693
693
  parts.push(keyBytes);
694
694
  }
695
695
  if (dict.valueToKeyIndexes && void 0 !== dict.bitsPerKey) {
696
- parts.push(writeU32(0xFFFFFFFF));
696
+ parts.push(writeU32(0xffffffff));
697
697
  parts.push(writeU32(dict.bitsPerKey));
698
698
  parts.push(writeU32(dict.valueToKeyIndexes.length));
699
699
  parts.push(dict.valueToKeyIndexes);
@@ -775,7 +775,7 @@ function deserializeLookupDict(data) {
775
775
  keys.push(decoder.decode(kBytes));
776
776
  }
777
777
  const sectionLen = readU32();
778
- if (0xFFFFFFFF === sectionLen) {
778
+ if (0xffffffff === sectionLen) {
779
779
  const bitsPerKey = readU32();
780
780
  const dataLen = readU32();
781
781
  const valueToKeyIndexes = data.subarray(offset, offset + dataLen);
@@ -925,11 +925,11 @@ class MinMPLookup {
925
925
  return this.dict.keys;
926
926
  }
927
927
  constructor(dict){
928
- MinMPLookup_define_property(this, "dict", void 0);
929
928
  MinMPLookup_define_property(this, "mph", void 0);
930
- MinMPLookup_define_property(this, "_invertedIndex", void 0);
929
+ MinMPLookup_define_property(this, "dict", void 0);
930
+ MinMPLookup_define_property(this, "_invertedIndex", null);
931
+ if (dict instanceof Uint8Array) dict = deserializeLookupDict(dict);
931
932
  this.dict = dict;
932
- this._invertedIndex = null;
933
933
  this.mph = new MinMPHash(dict.mmpHashDictBin);
934
934
  if (dict.keyToHashes) this.buildInvertedIndex();
935
935
  }
@@ -0,0 +1 @@
1
+ function e(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function t(e,t,i){let n=0;for(;e>=128;){let r=127&e|128;Array.isArray(t)?t.push(r):void 0!==i&&(t[i+n]=r),e>>>=7,n++}return Array.isArray(t)?t.push(e):void 0!==i&&(t[i+n]=e),n+1}function i(e,t){let i=0,n=0,r=0;for(;;){let s=e[t+r];if(i|=(127&s)<<n,r++,(128&s)==0)break;n+=7}return{value:i,bytes:r}}let n={encodeInt(e,t){e<24?t.push(0|e):e<=255?t.push(24,e):e<=65535?t.push(25,e>>8,255&e):t.push(26,e>>>24&255,e>>>16&255,e>>>8&255,255&e)},encodeBytes(e,t){let i=e.byteLength;i<24?t.push(64|i):i<=255?t.push(88,i):i<=65535?t.push(89,i>>8,255&i):t.push(90,i>>>24&255,i>>>16&255,i>>>8&255,255&i);for(let n=0;n<i;n++)t.push(e[n])},encodeNull(e){e.push(246)},encodeArrayHead(e,t){e<24&&t.push(128|e)},decode(e,t){let i=e.getUint8(t.current++),r=224&i,s=31&i,l=0;if(s<24)l=s;else if(24===s)l=e.getUint8(t.current),t.current+=1;else if(25===s)l=e.getUint16(t.current,!1),t.current+=2;else if(26===s)l=e.getUint32(t.current,!1),t.current+=4;else throw Error("Unsupported CBOR size");if(0===r)return l;if(64===r){let i=l,n=new Uint8Array(e.buffer.slice(e.byteOffset+t.current,e.byteOffset+t.current+i));return t.current+=i,n}if(128===r){let i=l,r=[];for(let s=0;s<i;s++)r.push(n.decode(e,t));return r}if(246===i)return null;throw Error(`Unknown CBOR type: ${i.toString(16)}`)}},r={none:0,4:1,8:2,16:3,32:4,2:5},s=["none","4","8","16","32","2"];function l(e){let t=[];if(n.encodeArrayHead(9,t),n.encodeInt(e.n,t),n.encodeInt(e.m,t),n.encodeInt(e.seed0,t),n.encodeBytes(e.bucketSizes,t),n.encodeBytes(e.seedStream,t),n.encodeInt(r[e.validationMode],t),e.fingerprints&&"none"!==e.validationMode){let i;if(e.fingerprints instanceof Uint8Array)i=e.fingerprints;else if(e.fingerprints instanceof Uint16Array||e.fingerprints instanceof Uint32Array)i=new Uint8Array(e.fingerprints.buffer,e.fingerprints.byteOffset,e.fingerprints.byteLength);else{let t,n=e.validationMode;t="2"===n||"4"===n||"8"===n?new Uint8Array(e.fingerprints):"16"===n?new Uint16Array(e.fingerprints):new Uint32Array(e.fingerprints),i=new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}n.encodeBytes(i,t)}else n.encodeNull(t);return e.seedZeroBitmap?n.encodeBytes(e.seedZeroBitmap,t):n.encodeNull(t),n.encodeInt(e.hashSeed||0,t),new Uint8Array(t)}async function o(e){let t=new Blob([e]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(t).arrayBuffer())}async function f(e){let t=new Blob([e]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(t).arrayBuffer())}class h{write(e,t){for(let i=0;i<t;i++){let t=e>>i&1;this.currentByte|=t<<this.bitCount,this.bitCount++,8===this.bitCount&&(this.buffer.push(this.currentByte),this.currentByte=0,this.bitCount=0)}}flush(){this.bitCount>0&&(this.buffer.push(this.currentByte),this.currentByte=0,this.bitCount=0)}getData(){return this.flush(),new Uint8Array(this.buffer)}constructor(){e(this,"buffer",[]),e(this,"currentByte",0),e(this,"bitCount",0)}}class a{read(e){let t=0;for(let i=0;i<e;i++){if(this.byteOffset>=this.buffer.length)return 0;t|=(this.buffer[this.byteOffset]>>this.bitOffset&1)<<i,this.bitOffset++,8===this.bitOffset&&(this.byteOffset++,this.bitOffset=0)}return t}constructor(t){e(this,"buffer",void 0),e(this,"byteOffset",0),e(this,"bitOffset",0),this.buffer=t}}function u(e,t,i){let n=0,r=t;for(let t=0;t<i;t++){let i=r>>>3,s=7&r;if(i>=e.length)return 0;n|=(e[i]>>s&1)<<t,r++}return n}function d(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function c(e,t){let i=e.length;if(0===i){let e={n:0,m:0,seed0:0,seedStream:new Uint8Array(0),bucketSizes:new Uint8Array(0),validationMode:"none"};return t?.outputBinary?l(e):e}let n=t?.level??5,r="none";t?.onlySet===!0?r="8":"string"==typeof t?.onlySet&&(r=t.onlySet);let s=i>5e5?Math.max(1,.9*n):n,f=Math.max(1,Math.ceil(i/s)),h=new Uint32Array(i),a=new Uint32Array(i),u=0;for(;;){let t=new Map,n=new Map,r=!1;for(let s=0;s<i;s++){let i=b(e[s],u),l=b(e[s],~u),o=!1;if(n.has(i)){let e=n.get(i);e.has(l)?o=!0:e.add(l)}else if(t.has(i)){let e=t.get(i);if(e===l)o=!0;else{let r=new Set;r.add(e),r.add(l),n.set(i,r),t.delete(i)}}else t.set(i,l);if(o){r=!0;break}h[s]=i,a[s]=l}if(!r)break;if(++u>100)throw Error(`Could not find a collision-free hash seed after ${u} attempts.`)}let d=new Int32Array(f).fill(-1),c=new Int32Array(i).fill(-1),g=0,m=1/0,A=new Int32Array(f),M=new Int32Array(i),v=new Int32Array(f);for(let e=0;e<2e3;e++){let t=Math.floor(0xffffffff*Math.random());A.fill(-1),v.fill(0);let n=0;for(let e=0;e<i;e++){let i=Math.floor(((p(h[e],t)^a[e])>>>0)/0x100000000*f);M[e]=A[i],A[i]=e,v[i]++,v[i]>n&&(n=v[i])}if(n<13){g=t,d.set(A),c.set(M),m=n;break}if(n<m&&(m=n,g=t,d.set(A),c.set(M)),m<16&&e>50)break}if(m>=16)throw Error(`MPHF Build Failed: Could not find a bucket distribution with max size < 16 (best: ${m}). Try reducing the optimization level (current: ${t?.level??5}).`);let U=new Uint8Array(Math.ceil(f/2));for(let e=0;e<f;e++){let t=0,i=d[e];for(;-1!==i;)t++,i=c[i];let n=e>>>1;(1&e)==0?U[n]|=t:U[n]|=t<<4}let k=new w,x=new Uint8Array(Math.ceil(f/8));for(let e=0;e<f;e++){let t=0,i=d[e];for(;-1!==i;)t++,i=c[i];if(t<=1){x[e>>>3]|=1<<(7&e);continue}let n=0,r=!1,s=t>14?5e7:5e6;for(;!r;){let i=0,l=!1,o=d[e];for(;-1!==o;){let e=((p(h[o],n)^a[o])>>>0)%t;if((i&1<<e)!=0){l=!0;break}i|=1<<e,o=c[o]}if(l){if(++n>s)throw Error(`MPHF Failed: Bucket ${e} (size ${t}) is too hard.`)}else 0===n?x[e>>>3]|=1<<(7&e):k.write(n),r=!0}}let B={n:i,m:f,seed0:g,hashSeed:u,seedStream:k.toUint8Array(),bucketSizes:U,seedZeroBitmap:x,validationMode:r};if("none"!==r){let t;t="2"===r?new Uint8Array(Math.ceil(i/4)):"4"===r?new Uint8Array(Math.ceil(i/2)):"8"===r?new Uint8Array(i):"16"===r?new Uint16Array(i):new Uint32Array(i);let n=new y({...B,validationMode:"none"});for(let s=0;s<i;s++){let l=e[s],o=n.hash(l);if(o>=0&&o<i){let e=b(l,0x1234abcd);if("2"===r){let i=3&e,n=o>>>2,r=(3&o)<<1;t[n]|=i<<r}else if("4"===r){let i=15&e,n=o>>>1;(1&o)==0?t[n]|=i:t[n]|=i<<4}else"8"===r?t[o]=255&e:"16"===r?t[o]=65535&e:t[o]=e>>>0}}B.fingerprints=t}if(t?.outputBinary){let e=l(B);return t.enableCompression?o(e):e}return B}class y{static async fromCompressed(e){return new y(await f(e))}hash(e){if(0===this.n)return -1;let t=b(e,this.hashSeed),i=b(e,~this.hashSeed),n=Math.floor(((p(t,this.seed0)^i)>>>0)/0x100000000*this.m),r=this.offsets[n],s=this.offsets[n+1]-r;if(0===s)return -1;let l=0;if(l=1===s?r:r+((p(t,this.seeds[n])^i)>>>0)%s,"none"!==this.validationMode&&this.fingerprints){let t=b(e,y.FP_SEED);if("2"===this.validationMode){let e=l>>>2,i=(3&l)<<1;if((this.fingerprints[e]>>>i&3)!=(3&t))return -1}else if("4"===this.validationMode){let e=l>>>1,i=this.fingerprints[e];if(((1&l)==0?15&i:i>>>4&15)!=(15&t))return -1}else if("8"===this.validationMode){if(this.fingerprints[l]!==(255&t))return -1}else if("16"===this.validationMode){if(this.fingerprints[l]!==(65535&t))return -1}else if(this.fingerprints[l]!==t>>>0)return -1}return l}constructor(e){if(d(this,"n",void 0),d(this,"m",void 0),d(this,"seed0",void 0),d(this,"hashSeed",void 0),d(this,"offsets",void 0),d(this,"seeds",void 0),d(this,"validationMode",void 0),d(this,"fingerprints",null),e instanceof Uint8Array&&(e=function(e){let t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),r=n.decode(i,{current:0});if(!Array.isArray(r)||r.length<7)throw Error("Invalid CBOR format");let[l,o,f,h,a,u,d,c,y]=r,p=s[u]||"none";return d&&"none"!==p&&("2"===p||"4"===p||"8"===p?t=d:"16"===p?t=new Uint16Array(d.buffer,d.byteOffset,d.byteLength/2):"32"===p&&(t=new Uint32Array(d.buffer,d.byteOffset,d.byteLength/4))),{n:l,m:o,seed0:f,hashSeed:y||0,bucketSizes:h,seedStream:a,validationMode:p,fingerprints:t,seedZeroBitmap:c||void 0}}(e)),this.n=e.n,this.m=e.m,this.seed0=e.seed0,this.hashSeed=e.hashSeed||0,this.validationMode=e.validationMode||"none",0===this.n){this.offsets=new Uint32Array(0),this.seeds=new Int32Array(0);return}this.offsets=new Uint32Array(this.m+1);let t=0;for(let i=0;i<this.m;i++){this.offsets[i]=t;let n=e.bucketSizes[i>>>1];t+=1&i?n>>>4:15&n}this.offsets[this.m]=t,this.seeds=new Int32Array(this.m);let i=0,r=e.seedStream,l=e.seedZeroBitmap;for(let e=0;e<this.m;e++){let t=!1;if(l&&(l[e>>>3]&1<<(7&e))!=0&&(t=!0),t)this.seeds[e]=0;else{let t=0,n=0;for(;;){let e=r[i++];if(t|=(127&e)<<n,(128&e)==0)break;n+=7}this.seeds[e]=t}}if("none"!==this.validationMode&&e.fingerprints){let t=e.fingerprints;"2"===this.validationMode||"4"===this.validationMode||"8"===this.validationMode?this.fingerprints=t instanceof Uint8Array?t:new Uint8Array(t):"16"===this.validationMode?this.fingerprints=t instanceof Uint16Array?t:new Uint16Array(t):this.fingerprints=t instanceof Uint32Array?t:new Uint32Array(t)}}}function p(e,t){return e^=t,e=Math.imul(e,0x85ebca6b),e^=e>>>13,e=Math.imul(e,0xc2b2ae35),(e^=e>>>16)>>>0}function b(e,t){let i=t;for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);i^=n=Math.imul(n=(n=Math.imul(n,0xcc9e2d51))<<15|n>>>17,0x1b873593),i=Math.imul(i=i<<13|i>>>19,5)+0xe6546b64}return i^=e.length,i^=i>>>16,i=Math.imul(i,0x85ebca6b),i^=i>>>13,i=Math.imul(i,0xc2b2ae35),(i^=i>>>16)>>>0}d(y,"FP_SEED",0x1234abcd);class w{write(e){for(;e>=128;)this.buffer.push(127&e|128),e>>>=7;this.buffer.push(e)}toUint8Array(){return new Uint8Array(this.buffer)}constructor(){d(this,"buffer",[])}}function g(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function m(e,i){let n,r=Object.keys(e),s=new Set;for(let t of r)for(let i of e[t])s.add(i);let l=Array.from(s),f=c(l,{level:i?.level,outputBinary:!0,onlySet:i?.onlySet??"8"}),a=new y(f),u=new Map;for(let t=0;t<r.length;t++)for(let i of e[r[t]])u.has(i)||u.set(i,[]),u.get(i).push(t);let d=0;for(let[e,t]of u)t.length>1&&d++;if(d<.1*l.length){let e=Math.ceil(Math.log2(r.length+1)),t=new h,i=new Map,s=new Int32Array(a.n).fill(-1);for(let[e,t]of u){let n=a.hash(e);n>=0&&(1===t.length?s[n]=t[0]:(s[n]=r.length,i.set(n,t)))}for(let i=0;i<a.n;i++){let n=s[i];t.write(n>=0?n:0,e)}n={mmpHashDictBin:f,keys:r,valueToKeyIndexes:t.getData(),bitsPerKey:e,collisionMap:i.size>0?i:void 0}}else{let t=[];for(let i of r){let n=e[i],r=[];for(let e of n){let t=a.hash(e);t>=0&&r.push(t)}r.sort((e,t)=>e-t),t.push(new Uint32Array(r))}n={mmpHashDictBin:f,keys:r,keyToHashes:t}}if(i?.outputBinary){let e=function(e){let i=[],n=new TextEncoder,r=e=>{let t=new Uint8Array(4);return new DataView(t.buffer).setUint32(0,e,!1),t};for(let t of(i.push(r(e.mmpHashDictBin.length)),i.push(e.mmpHashDictBin),i.push(r(e.keys.length)),e.keys)){let e=n.encode(t);i.push(r(e.length)),i.push(e)}if(e.valueToKeyIndexes&&void 0!==e.bitsPerKey)if(i.push(r(0xffffffff)),i.push(r(e.bitsPerKey)),i.push(r(e.valueToKeyIndexes.length)),i.push(e.valueToKeyIndexes),e.collisionMap&&e.collisionMap.size>0){let n=[];t(e.collisionMap.size,n);let s=Array.from(e.collisionMap.keys()).sort((e,t)=>e-t),l=0;for(let i of s){t(i-l,n),l=i;let r=e.collisionMap.get(i);t(r.length,n),r.sort((e,t)=>e-t);let s=0;for(let e of r)t(e-s,n),s=e}let o=new Uint8Array(n);i.push(r(o.length)),i.push(o)}else i.push(r(0));else if(e.keyToHashes){let n=[];for(let i of e.keyToHashes){if(t(i.length,n),0===i.length)continue;let e=0,r=0,s=[];for(let t=0;t<i.length;t++){let n=i[t],l=n-r;s.push(l),l>e&&(e=l),r=n}let l=0;e>0&&(l=Math.ceil(Math.log2(e+1))),n.push(l);let o=new h;for(let e of s)o.write(e,l);let f=o.getData();for(let e=0;e<f.length;e++)n.push(f[e])}let s=new Uint8Array(n);i.push(r(s.length)),i.push(s)}let s=new Uint8Array(i.reduce((e,t)=>e+t.length,0)),l=0;for(let e of i)s.set(e,l),l+=e.length;return s}(n);return i?.enableCompression?o(e):e}return i?.enableCompression?Promise.resolve(n):n}function A(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),n=0,r=new TextDecoder,s=()=>{let e=t.getUint32(n,!1);return n+=4,e},l=s(),o=e.subarray(n,n+l);n+=l;let f=s(),h=[];for(let t=0;t<f;t++){let t=s(),i=e.subarray(n,n+t);n+=t,h.push(r.decode(i))}let u=s();if(0xffffffff===u){let t,r=s(),l=s(),f=e.subarray(n,n+l);n+=l;let a=s();if(a>0){let r=e.subarray(n,n+a);n+=a,t=new Map;let s=0,{value:l,bytes:o}=i(r,0);s+=o;let f=0;for(let e=0;e<l;e++){let{value:e,bytes:n}=i(r,s);s+=n;let l=f+e;f=l;let{value:o,bytes:h}=i(r,s);s+=h;let a=[],u=0;for(let e=0;e<o;e++){let{value:e,bytes:t}=i(r,s);s+=t;let n=u+e;u=n,a.push(n)}t.set(l,a)}}return{mmpHashDictBin:o,keys:h,valueToKeyIndexes:f,bitsPerKey:r,collisionMap:t}}{let t=e.subarray(n,n+u);n+=u;let r=[],s=0;for(let e=0;e<f;e++){let{value:e,bytes:n}=i(t,s);if(s+=n,0===e){r.push(new Uint32Array(0));continue}let l=t[s];s+=1;let o=Math.ceil(l*e/8),f=t.subarray(s,s+o);s+=o;let h=new a(f),u=new Uint32Array(e),d=0;for(let t=0;t<e;t++)d+=h.read(l),u[t]=d;r.push(u)}return{mmpHashDictBin:o,keys:h,keyToHashes:r}}}class M{static async fromCompressed(e){return new M(A(await f(e)))}static fromBinary(e){return new M(A(e))}buildInvertedIndex(){if(!this.dict.keyToHashes)return;let e=this.mph.n;this._invertedIndex=Array.from({length:e},()=>[]);for(let t=0;t<this.dict.keys.length;t++){let i=this.dict.keyToHashes[t];for(let n=0;n<i.length;n++){let r=i[n];r<e&&this._invertedIndex[r].push(t)}}}query(e){if(this.dict.valueToKeyIndexes&&this.dict.bitsPerKey){let t=this.mph.hash(e);if(t<0||t>=this.mph.n)return null;let i=u(this.dict.valueToKeyIndexes,t*this.dict.bitsPerKey,this.dict.bitsPerKey);if(i===this.dict.keys.length){if(this.dict.collisionMap&&this.dict.collisionMap.has(t)){let e=this.dict.collisionMap.get(t);return e.length>0?this.dict.keys[e[0]]:null}return null}return i>=this.dict.keys.length?null:this.dict.keys[i]}let t=this.queryAll(e);return t&&t.length>0?t[0]:null}queryAll(e){if(this.dict.valueToKeyIndexes&&this.dict.bitsPerKey){let t=this.mph.hash(e);if(t<0||t>=this.mph.n)return null;let i=u(this.dict.valueToKeyIndexes,t*this.dict.bitsPerKey,this.dict.bitsPerKey);return i===this.dict.keys.length?this.dict.collisionMap&&this.dict.collisionMap.has(t)?this.dict.collisionMap.get(t).map(e=>this.dict.keys[e]):null:i>=this.dict.keys.length?null:[this.dict.keys[i]]}let t=this.mph.hash(e);if(t<0||!this._invertedIndex||t>=this._invertedIndex.length)return null;let i=this._invertedIndex[t];if(0===i.length)return null;let n=[];for(let e of i)n.push(this.dict.keys[e]);return n.length>0?n:null}keys(){return this.dict.keys}constructor(e){g(this,"mph",void 0),g(this,"dict",void 0),g(this,"_invertedIndex",null),e instanceof Uint8Array&&(e=A(e)),this.dict=e,this.mph=new y(e.mmpHashDictBin),e.keyToHashes&&this.buildInvertedIndex()}}export{y as MinMPHash,M as MinMPLookup,c as createMinMPHashDict,m as createMinMPLookupDict};
@@ -0,0 +1,2 @@
1
+ export { MinMPLookup } from "./MinMPLookup";
2
+ export { MinMPHash } from "./MinMPHash";
@@ -0,0 +1,492 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) Object.defineProperty(obj, key, {
3
+ value: value,
4
+ enumerable: true,
5
+ configurable: true,
6
+ writable: true
7
+ });
8
+ else obj[key] = value;
9
+ return obj;
10
+ }
11
+ function readVarInt(buffer, offset) {
12
+ let val = 0;
13
+ let shift = 0;
14
+ let bytes = 0;
15
+ while(true){
16
+ const b = buffer[offset + bytes];
17
+ val |= (0x7f & b) << shift;
18
+ bytes++;
19
+ if ((0x80 & b) === 0) break;
20
+ shift += 7;
21
+ }
22
+ return {
23
+ value: val,
24
+ bytes
25
+ };
26
+ }
27
+ const CBOR = {
28
+ encodeInt (val, buffer) {
29
+ const major = 0x00;
30
+ if (val < 24) buffer.push(major | val);
31
+ else if (val <= 0xff) buffer.push(24 | major, val);
32
+ else if (val <= 0xffff) buffer.push(25 | major, val >> 8, 0xff & val);
33
+ else buffer.push(26 | major, val >>> 24 & 0xff, val >>> 16 & 0xff, val >>> 8 & 0xff, 0xff & val);
34
+ },
35
+ encodeBytes (bytes, buffer) {
36
+ const major = 0x40;
37
+ const len = bytes.byteLength;
38
+ if (len < 24) buffer.push(major | len);
39
+ else if (len <= 0xff) buffer.push(24 | major, len);
40
+ else if (len <= 0xffff) buffer.push(25 | major, len >> 8, 0xff & len);
41
+ else buffer.push(26 | major, len >>> 24 & 0xff, len >>> 16 & 0xff, len >>> 8 & 0xff, 0xff & len);
42
+ for(let i = 0; i < len; i++)buffer.push(bytes[i]);
43
+ },
44
+ encodeNull (buffer) {
45
+ buffer.push(0xf6);
46
+ },
47
+ encodeArrayHead (len, buffer) {
48
+ const major = 0x80;
49
+ if (len < 24) buffer.push(major | len);
50
+ },
51
+ decode (view, offsetRef) {
52
+ const byte = view.getUint8(offsetRef.current++);
53
+ const major = 0xe0 & byte;
54
+ const additional = 0x1f & byte;
55
+ let val = 0;
56
+ if (additional < 24) val = additional;
57
+ else if (24 === additional) {
58
+ val = view.getUint8(offsetRef.current);
59
+ offsetRef.current += 1;
60
+ } else if (25 === additional) {
61
+ val = view.getUint16(offsetRef.current, false);
62
+ offsetRef.current += 2;
63
+ } else if (26 === additional) {
64
+ val = view.getUint32(offsetRef.current, false);
65
+ offsetRef.current += 4;
66
+ } else throw new Error("Unsupported CBOR size");
67
+ if (0x00 === major) return val;
68
+ if (0x40 === major) {
69
+ const len = val;
70
+ const buf = new Uint8Array(view.buffer.slice(view.byteOffset + offsetRef.current, view.byteOffset + offsetRef.current + len));
71
+ offsetRef.current += len;
72
+ return buf;
73
+ }
74
+ if (0x80 === major) {
75
+ const len = val;
76
+ const arr = [];
77
+ for(let i = 0; i < len; i++)arr.push(CBOR.decode(view, offsetRef));
78
+ return arr;
79
+ }
80
+ if (0xf6 === byte) return null;
81
+ throw new Error(`Unknown CBOR type: ${byte.toString(16)}`);
82
+ }
83
+ };
84
+ const INT_TO_MODE = [
85
+ "none",
86
+ "4",
87
+ "8",
88
+ "16",
89
+ "32",
90
+ "2"
91
+ ];
92
+ function dictFromCBOR(bin) {
93
+ const view = new DataView(bin.buffer, bin.byteOffset, bin.byteLength);
94
+ const offsetRef = {
95
+ current: 0
96
+ };
97
+ const arr = CBOR.decode(view, offsetRef);
98
+ if (!Array.isArray(arr) || arr.length < 7) throw new Error("Invalid CBOR format");
99
+ const [n, m, seed0, bucketSizes, seedStream, modeInt, fpRaw, seedZeroBitmap, hashSeed] = arr;
100
+ const validationMode = INT_TO_MODE[modeInt] || "none";
101
+ let fingerprints;
102
+ if (fpRaw && "none" !== validationMode) {
103
+ if ("2" === validationMode || "4" === validationMode || "8" === validationMode) fingerprints = fpRaw;
104
+ else if ("16" === validationMode) fingerprints = new Uint16Array(fpRaw.buffer, fpRaw.byteOffset, fpRaw.byteLength / 2);
105
+ else if ("32" === validationMode) fingerprints = new Uint32Array(fpRaw.buffer, fpRaw.byteOffset, fpRaw.byteLength / 4);
106
+ }
107
+ return {
108
+ n,
109
+ m,
110
+ seed0,
111
+ hashSeed: hashSeed || 0,
112
+ bucketSizes,
113
+ seedStream,
114
+ validationMode,
115
+ fingerprints,
116
+ seedZeroBitmap: seedZeroBitmap || void 0
117
+ };
118
+ }
119
+ async function decompressIBinary(data) {
120
+ const stream = new Blob([
121
+ data
122
+ ]).stream().pipeThrough(new DecompressionStream("gzip"));
123
+ return new Uint8Array(await new Response(stream).arrayBuffer());
124
+ }
125
+ class BitReader {
126
+ read(bits) {
127
+ let value = 0;
128
+ for(let i = 0; i < bits; i++){
129
+ if (this.byteOffset >= this.buffer.length) return 0;
130
+ const bit = this.buffer[this.byteOffset] >> this.bitOffset & 1;
131
+ value |= bit << i;
132
+ this.bitOffset++;
133
+ if (8 === this.bitOffset) {
134
+ this.byteOffset++;
135
+ this.bitOffset = 0;
136
+ }
137
+ }
138
+ return value;
139
+ }
140
+ constructor(buffer){
141
+ _define_property(this, "buffer", void 0);
142
+ _define_property(this, "byteOffset", 0);
143
+ _define_property(this, "bitOffset", 0);
144
+ this.buffer = buffer;
145
+ }
146
+ }
147
+ function readBitsAt(buffer, bitOffset, bitLength) {
148
+ let value = 0;
149
+ let currentBit = bitOffset;
150
+ for(let i = 0; i < bitLength; i++){
151
+ const byteIdx = currentBit >>> 3;
152
+ const bitIdx = 7 & currentBit;
153
+ if (byteIdx >= buffer.length) return 0;
154
+ const bit = buffer[byteIdx] >> bitIdx & 1;
155
+ value |= bit << i;
156
+ currentBit++;
157
+ }
158
+ return value;
159
+ }
160
+ function MinMPHash_define_property(obj, key, value) {
161
+ if (key in obj) Object.defineProperty(obj, key, {
162
+ value: value,
163
+ enumerable: true,
164
+ configurable: true,
165
+ writable: true
166
+ });
167
+ else obj[key] = value;
168
+ return obj;
169
+ }
170
+ class MinMPHash_MinMPHash {
171
+ static async fromCompressed(data) {
172
+ const decompressed = await decompressIBinary(data);
173
+ return new MinMPHash_MinMPHash(decompressed);
174
+ }
175
+ hash(input) {
176
+ if (0 === this.n) return -1;
177
+ const h1 = murmurHash3_32(input, this.hashSeed);
178
+ const h2 = murmurHash3_32(input, ~this.hashSeed);
179
+ const h0 = (scramble(h1, this.seed0) ^ h2) >>> 0;
180
+ const bIdx = Math.floor(h0 / 4294967296 * this.m);
181
+ const offset = this.offsets[bIdx];
182
+ const nextOffset = this.offsets[bIdx + 1];
183
+ const bucketSize = nextOffset - offset;
184
+ if (0 === bucketSize) return -1;
185
+ let resultIdx = 0;
186
+ if (1 === bucketSize) resultIdx = offset;
187
+ else {
188
+ const s = this.seeds[bIdx];
189
+ const h = (scramble(h1, s) ^ h2) >>> 0;
190
+ resultIdx = offset + h % bucketSize;
191
+ }
192
+ if ("none" !== this.validationMode && this.fingerprints) {
193
+ const fpHash = murmurHash3_32(input, MinMPHash_MinMPHash.FP_SEED);
194
+ if ("2" === this.validationMode) {
195
+ const expectedFp2 = 0x03 & fpHash;
196
+ const byteIdx = resultIdx >>> 2;
197
+ const shift = (3 & resultIdx) << 1;
198
+ if ((this.fingerprints[byteIdx] >>> shift & 0x03) !== expectedFp2) return -1;
199
+ } else if ("4" === this.validationMode) {
200
+ const expectedFp4 = 0x0f & fpHash;
201
+ const byteIdx = resultIdx >>> 1;
202
+ const storedByte = this.fingerprints[byteIdx];
203
+ const storedFp4 = (1 & resultIdx) === 0 ? 0x0f & storedByte : storedByte >>> 4 & 0x0f;
204
+ if (storedFp4 !== expectedFp4) return -1;
205
+ } else if ("8" === this.validationMode) {
206
+ if (this.fingerprints[resultIdx] !== (0xff & fpHash)) return -1;
207
+ } else if ("16" === this.validationMode) {
208
+ if (this.fingerprints[resultIdx] !== (0xffff & fpHash)) return -1;
209
+ } else if (this.fingerprints[resultIdx] !== fpHash >>> 0) return -1;
210
+ }
211
+ return resultIdx;
212
+ }
213
+ constructor(dict){
214
+ MinMPHash_define_property(this, "n", void 0);
215
+ MinMPHash_define_property(this, "m", void 0);
216
+ MinMPHash_define_property(this, "seed0", void 0);
217
+ MinMPHash_define_property(this, "hashSeed", void 0);
218
+ MinMPHash_define_property(this, "offsets", void 0);
219
+ MinMPHash_define_property(this, "seeds", void 0);
220
+ MinMPHash_define_property(this, "validationMode", void 0);
221
+ MinMPHash_define_property(this, "fingerprints", null);
222
+ if (dict instanceof Uint8Array) dict = dictFromCBOR(dict);
223
+ this.n = dict.n;
224
+ this.m = dict.m;
225
+ this.seed0 = dict.seed0;
226
+ this.hashSeed = dict.hashSeed || 0;
227
+ this.validationMode = dict.validationMode || "none";
228
+ if (0 === this.n) {
229
+ this.offsets = new Uint32Array(0);
230
+ this.seeds = new Int32Array(0);
231
+ return;
232
+ }
233
+ this.offsets = new Uint32Array(this.m + 1);
234
+ let currentOffset = 0;
235
+ for(let i = 0; i < this.m; i++){
236
+ this.offsets[i] = currentOffset;
237
+ const byte = dict.bucketSizes[i >>> 1];
238
+ const len = 1 & i ? byte >>> 4 : 0x0f & byte;
239
+ currentOffset += len;
240
+ }
241
+ this.offsets[this.m] = currentOffset;
242
+ this.seeds = new Int32Array(this.m);
243
+ let ptr = 0;
244
+ const buf = dict.seedStream;
245
+ const bitmap = dict.seedZeroBitmap;
246
+ for(let i = 0; i < this.m; i++){
247
+ let isZero = false;
248
+ if (bitmap) {
249
+ if ((bitmap[i >>> 3] & 1 << (7 & i)) !== 0) isZero = true;
250
+ }
251
+ if (isZero) this.seeds[i] = 0;
252
+ else {
253
+ let result = 0;
254
+ let shift = 0;
255
+ while(true){
256
+ const byte = buf[ptr++];
257
+ result |= (0x7f & byte) << shift;
258
+ if ((0x80 & byte) === 0) break;
259
+ shift += 7;
260
+ }
261
+ this.seeds[i] = result;
262
+ }
263
+ }
264
+ if ("none" !== this.validationMode && dict.fingerprints) {
265
+ const raw = dict.fingerprints;
266
+ if ("2" === this.validationMode || "4" === this.validationMode || "8" === this.validationMode) this.fingerprints = raw instanceof Uint8Array ? raw : new Uint8Array(raw);
267
+ else if ("16" === this.validationMode) this.fingerprints = raw instanceof Uint16Array ? raw : new Uint16Array(raw);
268
+ else this.fingerprints = raw instanceof Uint32Array ? raw : new Uint32Array(raw);
269
+ }
270
+ }
271
+ }
272
+ MinMPHash_define_property(MinMPHash_MinMPHash, "FP_SEED", 0x1234abcd);
273
+ function scramble(k, seed) {
274
+ k ^= seed;
275
+ k = Math.imul(k, 0x85ebca6b);
276
+ k ^= k >>> 13;
277
+ k = Math.imul(k, 0xc2b2ae35);
278
+ k ^= k >>> 16;
279
+ return k >>> 0;
280
+ }
281
+ function murmurHash3_32(key, seed) {
282
+ let h1 = seed;
283
+ const c1 = 0xcc9e2d51;
284
+ const c2 = 0x1b873593;
285
+ for(let i = 0; i < key.length; i++){
286
+ let k1 = key.charCodeAt(i);
287
+ k1 = Math.imul(k1, c1);
288
+ k1 = k1 << 15 | k1 >>> 17;
289
+ k1 = Math.imul(k1, c2);
290
+ h1 ^= k1;
291
+ h1 = h1 << 13 | h1 >>> 19;
292
+ h1 = Math.imul(h1, 5) + 0xe6546b64;
293
+ }
294
+ h1 ^= key.length;
295
+ h1 ^= h1 >>> 16;
296
+ h1 = Math.imul(h1, 0x85ebca6b);
297
+ h1 ^= h1 >>> 13;
298
+ h1 = Math.imul(h1, 0xc2b2ae35);
299
+ h1 ^= h1 >>> 16;
300
+ return h1 >>> 0;
301
+ }
302
+ function MinMPLookup_define_property(obj, key, value) {
303
+ if (key in obj) Object.defineProperty(obj, key, {
304
+ value: value,
305
+ enumerable: true,
306
+ configurable: true,
307
+ writable: true
308
+ });
309
+ else obj[key] = value;
310
+ return obj;
311
+ }
312
+ function deserializeLookupDict(data) {
313
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
314
+ let offset = 0;
315
+ const decoder = new TextDecoder();
316
+ const readU32 = ()=>{
317
+ const val = view.getUint32(offset, false);
318
+ offset += 4;
319
+ return val;
320
+ };
321
+ const mphLen = readU32();
322
+ const mmpHashDictBin = data.subarray(offset, offset + mphLen);
323
+ offset += mphLen;
324
+ const keysCount = readU32();
325
+ const keys = [];
326
+ for(let i = 0; i < keysCount; i++){
327
+ const kLen = readU32();
328
+ const kBytes = data.subarray(offset, offset + kLen);
329
+ offset += kLen;
330
+ keys.push(decoder.decode(kBytes));
331
+ }
332
+ const sectionLen = readU32();
333
+ if (0xffffffff === sectionLen) {
334
+ const bitsPerKey = readU32();
335
+ const dataLen = readU32();
336
+ const valueToKeyIndexes = data.subarray(offset, offset + dataLen);
337
+ offset += dataLen;
338
+ const colMapLen = readU32();
339
+ let collisionMap;
340
+ if (colMapLen > 0) {
341
+ const colBytes = data.subarray(offset, offset + colMapLen);
342
+ offset += colMapLen;
343
+ collisionMap = new Map();
344
+ let cOffset = 0;
345
+ const { value: count, bytes: b1 } = readVarInt(colBytes, cOffset);
346
+ cOffset += b1;
347
+ let prevHash = 0;
348
+ for(let i = 0; i < count; i++){
349
+ const { value: deltaHash, bytes: b2 } = readVarInt(colBytes, cOffset);
350
+ cOffset += b2;
351
+ const h = prevHash + deltaHash;
352
+ prevHash = h;
353
+ const { value: kCount, bytes: b3 } = readVarInt(colBytes, cOffset);
354
+ cOffset += b3;
355
+ const kIndices = [];
356
+ let prevKey = 0;
357
+ for(let j = 0; j < kCount; j++){
358
+ const { value: deltaKey, bytes: b4 } = readVarInt(colBytes, cOffset);
359
+ cOffset += b4;
360
+ const k = prevKey + deltaKey;
361
+ prevKey = k;
362
+ kIndices.push(k);
363
+ }
364
+ collisionMap.set(h, kIndices);
365
+ }
366
+ }
367
+ return {
368
+ mmpHashDictBin,
369
+ keys,
370
+ valueToKeyIndexes,
371
+ bitsPerKey,
372
+ collisionMap
373
+ };
374
+ }
375
+ {
376
+ const hashBytesLen = sectionLen;
377
+ const hashBytes = data.subarray(offset, offset + hashBytesLen);
378
+ offset += hashBytesLen;
379
+ const keyToHashes = [];
380
+ let hOffset = 0;
381
+ for(let i = 0; i < keysCount; i++){
382
+ const { value: count, bytes: b1 } = readVarInt(hashBytes, hOffset);
383
+ hOffset += b1;
384
+ if (0 === count) {
385
+ keyToHashes.push(new Uint32Array(0));
386
+ continue;
387
+ }
388
+ const bits = hashBytes[hOffset];
389
+ hOffset += 1;
390
+ const totalBits = bits * count;
391
+ const packedBytesLen = Math.ceil(totalBits / 8);
392
+ const packedData = hashBytes.subarray(hOffset, hOffset + packedBytesLen);
393
+ hOffset += packedBytesLen;
394
+ const br = new BitReader(packedData);
395
+ const hashes = new Uint32Array(count);
396
+ let prev = 0;
397
+ for(let j = 0; j < count; j++){
398
+ const delta = br.read(bits);
399
+ prev += delta;
400
+ hashes[j] = prev;
401
+ }
402
+ keyToHashes.push(hashes);
403
+ }
404
+ return {
405
+ mmpHashDictBin,
406
+ keys,
407
+ keyToHashes
408
+ };
409
+ }
410
+ }
411
+ class MinMPLookup {
412
+ static async fromCompressed(data) {
413
+ const decompressed = await decompressIBinary(data);
414
+ const dict = deserializeLookupDict(decompressed);
415
+ return new MinMPLookup(dict);
416
+ }
417
+ static fromBinary(data) {
418
+ const dict = deserializeLookupDict(data);
419
+ return new MinMPLookup(dict);
420
+ }
421
+ buildInvertedIndex() {
422
+ if (!this.dict.keyToHashes) return;
423
+ const n = this.mph.n;
424
+ this._invertedIndex = Array.from({
425
+ length: n
426
+ }, ()=>[]);
427
+ for(let i = 0; i < this.dict.keys.length; i++){
428
+ const hashes = this.dict.keyToHashes[i];
429
+ for(let j = 0; j < hashes.length; j++){
430
+ const h = hashes[j];
431
+ if (h < n) this._invertedIndex[h].push(i);
432
+ }
433
+ }
434
+ }
435
+ query(value) {
436
+ if (this.dict.valueToKeyIndexes && this.dict.bitsPerKey) {
437
+ const h = this.mph.hash(value);
438
+ if (h < 0 || h >= this.mph.n) return null;
439
+ const keyIdx = readBitsAt(this.dict.valueToKeyIndexes, h * this.dict.bitsPerKey, this.dict.bitsPerKey);
440
+ if (keyIdx === this.dict.keys.length) {
441
+ if (this.dict.collisionMap && this.dict.collisionMap.has(h)) {
442
+ const indices = this.dict.collisionMap.get(h);
443
+ return indices.length > 0 ? this.dict.keys[indices[0]] : null;
444
+ }
445
+ return null;
446
+ }
447
+ if (keyIdx >= this.dict.keys.length) return null;
448
+ return this.dict.keys[keyIdx];
449
+ }
450
+ const keys = this.queryAll(value);
451
+ return keys && keys.length > 0 ? keys[0] : null;
452
+ }
453
+ queryAll(value) {
454
+ if (this.dict.valueToKeyIndexes && this.dict.bitsPerKey) {
455
+ const h = this.mph.hash(value);
456
+ if (h < 0 || h >= this.mph.n) return null;
457
+ const keyIdx = readBitsAt(this.dict.valueToKeyIndexes, h * this.dict.bitsPerKey, this.dict.bitsPerKey);
458
+ if (keyIdx === this.dict.keys.length) {
459
+ if (this.dict.collisionMap && this.dict.collisionMap.has(h)) {
460
+ const indices = this.dict.collisionMap.get(h);
461
+ return indices.map((i)=>this.dict.keys[i]);
462
+ }
463
+ return null;
464
+ }
465
+ if (keyIdx >= this.dict.keys.length) return null;
466
+ return [
467
+ this.dict.keys[keyIdx]
468
+ ];
469
+ }
470
+ const idx = this.mph.hash(value);
471
+ if (idx < 0 || !this._invertedIndex) return null;
472
+ if (idx >= this._invertedIndex.length) return null;
473
+ const keyIndices = this._invertedIndex[idx];
474
+ if (0 === keyIndices.length) return null;
475
+ const results = [];
476
+ for (const keyIdx of keyIndices)results.push(this.dict.keys[keyIdx]);
477
+ return results.length > 0 ? results : null;
478
+ }
479
+ keys() {
480
+ return this.dict.keys;
481
+ }
482
+ constructor(dict){
483
+ MinMPLookup_define_property(this, "mph", void 0);
484
+ MinMPLookup_define_property(this, "dict", void 0);
485
+ MinMPLookup_define_property(this, "_invertedIndex", null);
486
+ if (dict instanceof Uint8Array) dict = deserializeLookupDict(dict);
487
+ this.dict = dict;
488
+ this.mph = new MinMPHash_MinMPHash(dict.mmpHashDictBin);
489
+ if (dict.keyToHashes) this.buildInvertedIndex();
490
+ }
491
+ }
492
+ export { MinMPHash_MinMPHash as MinMPHash, MinMPLookup };
@@ -0,0 +1 @@
1
+ function e(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function t(e,t){let i=0,s=0,r=0;for(;;){let n=e[t+r];if(i|=(127&n)<<s,r++,(128&n)==0)break;s+=7}return{value:i,bytes:r}}let i={encodeInt(e,t){e<24?t.push(0|e):e<=255?t.push(24,e):e<=65535?t.push(25,e>>8,255&e):t.push(26,e>>>24&255,e>>>16&255,e>>>8&255,255&e)},encodeBytes(e,t){let i=e.byteLength;i<24?t.push(64|i):i<=255?t.push(88,i):i<=65535?t.push(89,i>>8,255&i):t.push(90,i>>>24&255,i>>>16&255,i>>>8&255,255&i);for(let s=0;s<i;s++)t.push(e[s])},encodeNull(e){e.push(246)},encodeArrayHead(e,t){e<24&&t.push(128|e)},decode(e,t){let s=e.getUint8(t.current++),r=224&s,n=31&s,h=0;if(n<24)h=n;else if(24===n)h=e.getUint8(t.current),t.current+=1;else if(25===n)h=e.getUint16(t.current,!1),t.current+=2;else if(26===n)h=e.getUint32(t.current,!1),t.current+=4;else throw Error("Unsupported CBOR size");if(0===r)return h;if(64===r){let i=h,s=new Uint8Array(e.buffer.slice(e.byteOffset+t.current,e.byteOffset+t.current+i));return t.current+=i,s}if(128===r){let s=h,r=[];for(let n=0;n<s;n++)r.push(i.decode(e,t));return r}if(246===s)return null;throw Error(`Unknown CBOR type: ${s.toString(16)}`)}},s=["none","4","8","16","32","2"];async function r(e){let t=new Blob([e]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(t).arrayBuffer())}class n{read(e){let t=0;for(let i=0;i<e;i++){if(this.byteOffset>=this.buffer.length)return 0;t|=(this.buffer[this.byteOffset]>>this.bitOffset&1)<<i,this.bitOffset++,8===this.bitOffset&&(this.byteOffset++,this.bitOffset=0)}return t}constructor(t){e(this,"buffer",void 0),e(this,"byteOffset",0),e(this,"bitOffset",0),this.buffer=t}}function h(e,t,i){let s=0,r=t;for(let t=0;t<i;t++){let i=r>>>3,n=7&r;if(i>=e.length)return 0;s|=(e[i]>>n&1)<<t,r++}return s}function l(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}class f{static async fromCompressed(e){return new f(await r(e))}hash(e){if(0===this.n)return -1;let t=o(e,this.hashSeed),i=o(e,~this.hashSeed),s=Math.floor(((a(t,this.seed0)^i)>>>0)/0x100000000*this.m),r=this.offsets[s],n=this.offsets[s+1]-r;if(0===n)return -1;let h=0;if(h=1===n?r:r+((a(t,this.seeds[s])^i)>>>0)%n,"none"!==this.validationMode&&this.fingerprints){let t=o(e,f.FP_SEED);if("2"===this.validationMode){let e=h>>>2,i=(3&h)<<1;if((this.fingerprints[e]>>>i&3)!=(3&t))return -1}else if("4"===this.validationMode){let e=h>>>1,i=this.fingerprints[e];if(((1&h)==0?15&i:i>>>4&15)!=(15&t))return -1}else if("8"===this.validationMode){if(this.fingerprints[h]!==(255&t))return -1}else if("16"===this.validationMode){if(this.fingerprints[h]!==(65535&t))return -1}else if(this.fingerprints[h]!==t>>>0)return -1}return h}constructor(e){if(l(this,"n",void 0),l(this,"m",void 0),l(this,"seed0",void 0),l(this,"hashSeed",void 0),l(this,"offsets",void 0),l(this,"seeds",void 0),l(this,"validationMode",void 0),l(this,"fingerprints",null),e instanceof Uint8Array&&(e=function(e){let t,r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=i.decode(r,{current:0});if(!Array.isArray(n)||n.length<7)throw Error("Invalid CBOR format");let[h,l,f,a,o,u,d,c,y]=n,b=s[u]||"none";return d&&"none"!==b&&("2"===b||"4"===b||"8"===b?t=d:"16"===b?t=new Uint16Array(d.buffer,d.byteOffset,d.byteLength/2):"32"===b&&(t=new Uint32Array(d.buffer,d.byteOffset,d.byteLength/4))),{n:h,m:l,seed0:f,hashSeed:y||0,bucketSizes:a,seedStream:o,validationMode:b,fingerprints:t,seedZeroBitmap:c||void 0}}(e)),this.n=e.n,this.m=e.m,this.seed0=e.seed0,this.hashSeed=e.hashSeed||0,this.validationMode=e.validationMode||"none",0===this.n){this.offsets=new Uint32Array(0),this.seeds=new Int32Array(0);return}this.offsets=new Uint32Array(this.m+1);let t=0;for(let i=0;i<this.m;i++){this.offsets[i]=t;let s=e.bucketSizes[i>>>1];t+=1&i?s>>>4:15&s}this.offsets[this.m]=t,this.seeds=new Int32Array(this.m);let r=0,n=e.seedStream,h=e.seedZeroBitmap;for(let e=0;e<this.m;e++){let t=!1;if(h&&(h[e>>>3]&1<<(7&e))!=0&&(t=!0),t)this.seeds[e]=0;else{let t=0,i=0;for(;;){let e=n[r++];if(t|=(127&e)<<i,(128&e)==0)break;i+=7}this.seeds[e]=t}}if("none"!==this.validationMode&&e.fingerprints){let t=e.fingerprints;"2"===this.validationMode||"4"===this.validationMode||"8"===this.validationMode?this.fingerprints=t instanceof Uint8Array?t:new Uint8Array(t):"16"===this.validationMode?this.fingerprints=t instanceof Uint16Array?t:new Uint16Array(t):this.fingerprints=t instanceof Uint32Array?t:new Uint32Array(t)}}}function a(e,t){return e^=t,e=Math.imul(e,0x85ebca6b),e^=e>>>13,e=Math.imul(e,0xc2b2ae35),(e^=e>>>16)>>>0}function o(e,t){let i=t;for(let t=0;t<e.length;t++){let s=e.charCodeAt(t);i^=s=Math.imul(s=(s=Math.imul(s,0xcc9e2d51))<<15|s>>>17,0x1b873593),i=Math.imul(i=i<<13|i>>>19,5)+0xe6546b64}return i^=e.length,i^=i>>>16,i=Math.imul(i,0x85ebca6b),i^=i>>>13,i=Math.imul(i,0xc2b2ae35),(i^=i>>>16)>>>0}function u(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function d(e){let i=new DataView(e.buffer,e.byteOffset,e.byteLength),s=0,r=new TextDecoder,h=()=>{let e=i.getUint32(s,!1);return s+=4,e},l=h(),f=e.subarray(s,s+l);s+=l;let a=h(),o=[];for(let t=0;t<a;t++){let t=h(),i=e.subarray(s,s+t);s+=t,o.push(r.decode(i))}let u=h();if(0xffffffff===u){let i,r=h(),n=h(),l=e.subarray(s,s+n);s+=n;let a=h();if(a>0){let r=e.subarray(s,s+a);s+=a,i=new Map;let n=0,{value:h,bytes:l}=t(r,0);n+=l;let f=0;for(let e=0;e<h;e++){let{value:e,bytes:s}=t(r,n);n+=s;let h=f+e;f=h;let{value:l,bytes:a}=t(r,n);n+=a;let o=[],u=0;for(let e=0;e<l;e++){let{value:e,bytes:i}=t(r,n);n+=i;let s=u+e;u=s,o.push(s)}i.set(h,o)}}return{mmpHashDictBin:f,keys:o,valueToKeyIndexes:l,bitsPerKey:r,collisionMap:i}}{let i=e.subarray(s,s+u);s+=u;let r=[],h=0;for(let e=0;e<a;e++){let{value:e,bytes:s}=t(i,h);if(h+=s,0===e){r.push(new Uint32Array(0));continue}let l=i[h];h+=1;let f=Math.ceil(l*e/8),a=i.subarray(h,h+f);h+=f;let o=new n(a),u=new Uint32Array(e),d=0;for(let t=0;t<e;t++)d+=o.read(l),u[t]=d;r.push(u)}return{mmpHashDictBin:f,keys:o,keyToHashes:r}}}l(f,"FP_SEED",0x1234abcd);class c{static async fromCompressed(e){return new c(d(await r(e)))}static fromBinary(e){return new c(d(e))}buildInvertedIndex(){if(!this.dict.keyToHashes)return;let e=this.mph.n;this._invertedIndex=Array.from({length:e},()=>[]);for(let t=0;t<this.dict.keys.length;t++){let i=this.dict.keyToHashes[t];for(let s=0;s<i.length;s++){let r=i[s];r<e&&this._invertedIndex[r].push(t)}}}query(e){if(this.dict.valueToKeyIndexes&&this.dict.bitsPerKey){let t=this.mph.hash(e);if(t<0||t>=this.mph.n)return null;let i=h(this.dict.valueToKeyIndexes,t*this.dict.bitsPerKey,this.dict.bitsPerKey);if(i===this.dict.keys.length){if(this.dict.collisionMap&&this.dict.collisionMap.has(t)){let e=this.dict.collisionMap.get(t);return e.length>0?this.dict.keys[e[0]]:null}return null}return i>=this.dict.keys.length?null:this.dict.keys[i]}let t=this.queryAll(e);return t&&t.length>0?t[0]:null}queryAll(e){if(this.dict.valueToKeyIndexes&&this.dict.bitsPerKey){let t=this.mph.hash(e);if(t<0||t>=this.mph.n)return null;let i=h(this.dict.valueToKeyIndexes,t*this.dict.bitsPerKey,this.dict.bitsPerKey);return i===this.dict.keys.length?this.dict.collisionMap&&this.dict.collisionMap.has(t)?this.dict.collisionMap.get(t).map(e=>this.dict.keys[e]):null:i>=this.dict.keys.length?null:[this.dict.keys[i]]}let t=this.mph.hash(e);if(t<0||!this._invertedIndex||t>=this._invertedIndex.length)return null;let i=this._invertedIndex[t];if(0===i.length)return null;let s=[];for(let e of i)s.push(this.dict.keys[e]);return s.length>0?s:null}keys(){return this.dict.keys}constructor(e){u(this,"mph",void 0),u(this,"dict",void 0),u(this,"_invertedIndex",null),e instanceof Uint8Array&&(e=d(e)),this.dict=e,this.mph=new f(e.mmpHashDictBin),e.keyToHashes&&this.buildInvertedIndex()}}export{f as MinMPHash,c as MinMPLookup};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "min-mphash",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "type": "module",
5
5
  "author": "git@qzrzz.com",
6
6
  "license": "MIT",
@@ -9,6 +9,10 @@
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.js"
12
+ },
13
+ "./runtime": {
14
+ "types": "./dist/runtime.d.ts",
15
+ "import": "./dist/runtime.js"
12
16
  }
13
17
  },
14
18
  "types": "./dist/index.d.ts",