转载地址:https://blog.csdn.net/jiaomeng/article/details/1543751
Spectral bloom filter(SBF)在counting bloom filter(CBF)的基础上提出了元素出现频率查询的概念,将CBF的应用扩展到了multi-set的领域。但是,SBF为解决动态counter的存储问题,引入了复杂的索引结构,这让每个counter的访问变得复杂而耗时。有没有一种解决方案既支持元素出现频率查询,结构又相对比较简单呢?Dynamic count filter(DCF)尝试回答了这个问题。
要支持元素出现频率查询,就需要解决变化范围可能很大的counter的存储问题。DCF和SBF的不同之处,也就是counter的存储结构。DCF使用两个数组来存储所有的counter,它们的长度都为m(即bloom filter的位数组长度)。第一个数组是一个基本的CBF(即下图中的CBFV,counting bloom filter vector),counter的长度固定,为x = log(M/n),其中M是集合中所有元素的个数,n为集合中不同元素的个数。第二个数组用来处理counter的溢出(即下图中的OFV,overflow vector),数组每一项的长度并不固定,根据counter的溢出情况动态调整。假设OFj是OFV中某一项的值,那么OFV中每一项的长度y = floor(log(max(OFj))) + 1,即最大值决定了每项长度。
上图中最右一列是counter的值,从图中我们可以清楚地看出OFV和CBFV的作用。比如第5个counter的值是1026,二进制为10000000010。我们把这个二进制位串分成两段100和00000010,分别就对应着OFV和CBFV中的值。图中我们也可以看出x + y就等于counter的最大值的二进制位数。
在查询一个counter时,DCF要求两次内存访问。假设想查询位置为j的counter的值,我们先读出CBFV和OFV的值,分别为Cj和OFj,那么counter的值就可以表示为Vj = (2x×OFj + Cj)。
在集合增加元素时,如果OFV的最大值从2x – 1增加到2x,OFV就需要给每一项增加1位,否则就会溢出。每次OFV大小改变的时候都需要重建。重建是一件开销很大的工作,必须重新创建一个OFV数组,然后把旧OFV数组的值拷贝到新建的OFV数组中,最后把旧OFV数组的空间释放掉。如果说增加时的overflow必须重建的话,那么集合元素减少时的underflow则有更多选择。当OFV的最大值从2x减少到2x – 1时,我们可以选择马上重建OFV,也可以采用一些策略延迟OFV的重建,以避免一些临时性的减少导致OFV反复重建。
从上面的介绍可以看出,DCF中最大的那个counter决定了整个结构所占的空间。因此,在counter的值普遍不大的情况下,DCF由于不用维护复杂的索引结构,所以占用空间比SBF要少。如果将counter的值逐渐增大,SBF在空间占用上的优势就会越来越明显。在counter存取时间上,DCF占有绝对的优势,只比CBF多访问了一次内存。在不同的实际应用场合中对比SBF和DCF,论文作者发现DCF整体占用的空间以及执行时间都比SBF少了一半还多。最后,我们给出一个将CBF、SBF和DCF定性比较的表格:
参考论文:http://www.sigmod.org/sigmod/record/issues/0603/p26-article-pey.pdf