标准的Bloom Filter不适合删除元素。原因如下:
假设删除的元素对应的bit位是index11, index12, index13,......,index1k。并且另有一个元素对应的bit位是index21,index22,index23,......,index2k。对于某个i,j(0<= i <= k - 1,0<= j <= k - 1),使得index1i = index2j,当该元素被删除的时候,也就是index1i会被设置为0,同时index2j就是0。这意味着查询另一个元素的时候,无法满足k个bit都是1,也就是查询不到这个元素。这就违背了Bloom Filter的基本原则,在Bloom Filter中的元素一定可以被查到,不在Bloom Filter中的元素有一定的概率会被查到。
为了解决删除元素的问题,论文【Fan et al. 00】提出了Counting Bloom Filter(CBT)。CBT为每个bit位添加了一个计数器,每当添加一个元素时,对应的k个bit位的计数器都要 + 1。删除一个元素的时候,对应k个bit位的计数器 - 1,当计数器为0时,才设置对应的bit位为0。论文【Fan et al. 00】给出了一个结论,当计数器大小为4bit时(0 ~ 15),可以满足大部分应用的使用。
注:黄色方块表示bit置为1,深蓝色表示计数器。
为了得到更加合适的计数器大小,以下给出了具体的分析过程。假设CBT中有n个元素,k个哈希函数,bit数组大小为m。假设c(i)为第i个bit的计数器,P(c(i) = j)表示第i个bit的计数器计数为j的概率。
将上面的问题抽象成将nk个球随机放入到m个槽中,求第i个槽中放入j个球的概率是多少。
1)随机从nk个球中随机选择出j个球,得出概率
2)选择出某个槽,将这j个球都放如到这个槽中概率,每个球放入到其中的概率都是 (1 / m) ,那么总概率就是 (1 / m) ^ j
3)将其余剩下的球随机放入到其他m - 1个槽中,总概率是 (1 - 1 / m) ^ ( n*k - j)
所以总的概率是上面三个概率相乘。
所以任意某个计数器最少是j的概率是
设置 k = ( m / n ) * ln2,得到,
所以当计数器为4bit时,
也就是说当计数器为4bit时,计数器超过16的概率是 1.37 * 10 ^ ( - 15 ) * m
对于越界处理,也就是计数器达到最大值的时候,将计数器设置为其能达到的最大值。仅仅当计数器变为0的时候,才会出现错误,但是如果数据足够随机,计数器从最大值减少到0的时间是非常长的。因此出现错误的概率很小。