JS實現一個布隆過濾器

之前專門聊過令牌桶算法,而類似的方案還有布隆過濾器。它一般用於高效地查找一個元素是否在一個集合中。
用js實現如下所示:

class BloomFilter {
    constructor(size, hashFunctions) {
        this.size = size;
        this.bitArray = new Array(size).fill(0);
        this.hasFunctions = hashFunctions;
    }

    add(item) {
        for (let i = 0; i < this.hasFunctions.length; i++) {
            const index = this.getHash(this.hasFunctions[i], item) % this.size;
            this.bitArray[index] = 1;
        }
    }

    contain(item) {
        for (let i = 0; i < this.hasFunctions.length; i++) {
            const index = this.getHash(this.hasFunctions[i], item) % this.size;
            if (this.bitArray[index] === 0) return false;
        }
        return true;
    }

    getHash(hasFunction, item) {
        return hasFunction(item);
    }

}

const basicHashFunction = (item) => {
    // Transform the item to string
    const chars = String(item);
    let hash = 0;

    // Perform a simple hash calculation on each character in the string
    for (let i = 0; i < chars.length; i++) {
        hash = (hash << 5) + chars.charCodeAt(i); // combination of the bit operations and character ending
        hash = hash & hash;
        hash = Math.abs(hash);
    }
    return hash;
}

const secondHashFunction = (item) => {
    let hash = 0;
    for (let i = 0; i < item.length; i++) {
        const char = item.charCodeAt(i);
        hash = (hash << 5) - hash + char;
    }
    return hash;
}

// usage
const hashFunctions = [basicHashFunction, secondHashFunction];
const bloomFilter = new BloomFilter(1000, hashFunctions);
bloomFilter.add("item01");
bloomFilter.add("item02");
console.log(bloomFilter.contain("item02")); // output: true
console.log(bloomFilter.contain("item02")); // output: false

在上述代碼中我們通過多個哈希函數計算元素的哈希值,減少哈希衝突問題。哈希函數還可以用第三方庫,不一定非要自己實現,我給出的都是一些簡單實現。
布隆過濾器有很多應用場景:

  1. 防止緩存穿透。判斷數據是否在緩存中,以免不走緩存。
  2. 優化數據庫請求。
  3. 防止惡意訪問。如果該請求ip已經在保存惡意IP的布隆過濾器中,則阻止該請求。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章