d-left 计数布隆过滤器
计数的布隆过滤器(Count Bloom Filter)是为了弥补普通布隆过滤器不支持删除的缺陷而出现的,但是其大部分空间的值都为0,非常浪费空间。因此思科联合哈佛大学和斯坦福大学于 2006 年提出基于 d-left hashing来提高空间利用率的布隆过滤器, 与此同时还能得到更低的误判率。论文详见An Improved Construction for Counting Bloom Filters。
文中指出利用d-left hashing来构造d个相互隔离的子表,每个子表下包含若干个bucket,每个bucket下包含若干个cell,每个cell下包含一个哈希指纹和一个用于计数的counter,且子表是从左到右连续运行。
d-left 计数布隆过滤器的原理:
- 定义:将计数布隆过滤器的存储空间(通常为比特数组)划分为d个子表(d-left中的’d’),每个子哈希表包含n个bucket,每个bucket下包含若干个cell,每个cell下包含一个哈希指纹和一个用于计数的counter。
- 插入:每个传入的数据都要经过哈希处理,得到一个由d+1部分组成的哈希值,高d段的值用于定位哈希子表中的bucket,第d+1段作为哈希指纹定位cell,插入时在d个位置中选择元素最少的一个,如果元素数量一样,优先选择最左边一个。如果cell的哈希指纹相同,则计数加 1。反之新加一个cell,用于计数的counter初始化为 1。
- 删除:同插入逻辑找到对应哈希子表、bucket和cell,然后将用于计数的counter - 1,减到0时删除。
- 查询:从左到右依次遍历d个哈希子表,只要其中一个位置的cell中有对应元素的哈希指纹,就判定存在。
由此可见,d-left中的’d’描述的是将原来的哈希表拆分为多少个子表,left描述的是选择bucket的规则(元素相同则靠左优先)。
以hello为例,处理过程如下:
- 根据r-left分为两个哈希子表,其每个哈希子表下包含4个bucket,插入hello之前的的现状如下图绿色部分所示;
- hello经过哈希函数后得到一个2+1段的哈希值(bucket1=2,bucket2=3,R1),其中bucket1和bucket2指定元素落在两个哈希子表的哪一个bucket中,R1则是指纹;
- 因为下图绿色部分现状所示两个哈希子表的bucket中的元素数量相同,根据靠左优先原则,当前hello的R1指纹落在哈希子表1中。
原文中列出了d-left 计数布隆过滤器和原始计数布隆过滤器之间空间利用率和误判率推演过程,详情可阅读An Improved Construction for Counting Bloom Filters。