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的布隆过滤器中,则阻止该请求。
posted @ 2024-02-18 20:16  freephp  阅读(92)  评论(0编辑  收藏  举报