84 lines
2.8 KiB
Plaintext
84 lines
2.8 KiB
Plaintext
// minimal implementation MurmurHash2 hash function
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
Object.defineProperty(exports, "BloomFilter", {
|
|
enumerable: true,
|
|
get: function() {
|
|
return BloomFilter;
|
|
}
|
|
});
|
|
function murmurhash2(str) {
|
|
let h = 0;
|
|
for(let i = 0; i < str.length; i++){
|
|
const c = str.charCodeAt(i);
|
|
h = Math.imul(h ^ c, 0x5bd1e995);
|
|
h ^= h >>> 13;
|
|
h = Math.imul(h, 0x5bd1e995);
|
|
}
|
|
return h >>> 0;
|
|
}
|
|
class BloomFilter {
|
|
static from(items, errorRate) {
|
|
if (errorRate === void 0) errorRate = 0.01;
|
|
const filter = new BloomFilter(items.length, errorRate);
|
|
for (const item of items){
|
|
filter.add(item);
|
|
}
|
|
return filter;
|
|
}
|
|
export() {
|
|
const data = {
|
|
numItems: this.numItems,
|
|
errorRate: this.errorRate,
|
|
numBits: this.numBits,
|
|
numHashes: this.numHashes,
|
|
bitArray: this.bitArray
|
|
};
|
|
if (typeof window === "undefined" && process.env.NEXT_RUNTIME !== "edge") {
|
|
if (this.errorRate < 0.01) {
|
|
const filterData = JSON.stringify(data);
|
|
const gzipSize = require("next/dist/compiled/gzip-size").sync(filterData);
|
|
if (gzipSize > 1024) {
|
|
console.warn("Creating filter with error rate less than 1% (0.01) can increase the size dramatically proceed with caution. Received error rate " + this.errorRate + " resulted in size " + filterData.length + " bytes, " + gzipSize + " bytes (gzip)");
|
|
}
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
import(data) {
|
|
this.numItems = data.numItems;
|
|
this.errorRate = data.errorRate;
|
|
this.numBits = data.numBits;
|
|
this.numHashes = data.numHashes;
|
|
this.bitArray = data.bitArray;
|
|
}
|
|
add(item) {
|
|
const hashValues = this.getHashValues(item);
|
|
hashValues.forEach((hash)=>{
|
|
this.bitArray[hash] = 1;
|
|
});
|
|
}
|
|
contains(item) {
|
|
const hashValues = this.getHashValues(item);
|
|
return hashValues.every((hash)=>this.bitArray[hash]);
|
|
}
|
|
getHashValues(item) {
|
|
const hashValues = [];
|
|
for(let i = 1; i <= this.numHashes; i++){
|
|
const hash = murmurhash2("" + item + i) % this.numBits;
|
|
hashValues.push(hash);
|
|
}
|
|
return hashValues;
|
|
}
|
|
constructor(numItems, errorRate){
|
|
this.numItems = numItems;
|
|
this.errorRate = errorRate;
|
|
this.numBits = Math.ceil(-(numItems * Math.log(errorRate)) / (Math.log(2) * Math.log(2)));
|
|
this.numHashes = Math.ceil(this.numBits / numItems * Math.log(2));
|
|
this.bitArray = new Array(this.numBits).fill(0);
|
|
}
|
|
}
|
|
|
|
//# sourceMappingURL=bloom-filter.js.map |