布隆,牛逼!布谷鸟,牛逼! (5)

布谷鸟过滤器:我烦死了,TMD!

接下来,说一下“指纹”。

布隆,牛逼!布谷鸟,牛逼!

这是论文中第一次出现“指纹”的地方。

“指纹”其实就是插入的元素进行一个 hash 计算,而 hash 计算的产物就是 几个 bit 位。

布谷鸟过滤器里面存储的就是元素的“指纹”。

查询数据的时候,就是看看对应的位置上有没有对应的“指纹”信息:

布隆,牛逼!布谷鸟,牛逼!

删除数据的时候,也只是抹掉该位置上的“指纹”而已:

布隆,牛逼!布谷鸟,牛逼!

由于是对元素进行 hash 计算,那么必然会出现“指纹”相同的情况,也就是会出现误判的情况。

没有存储原数据,所以牺牲了数据的准确性,但是只保存了几个 bit,因此提升了空间效率。

说到空间利用率,你想想布谷鸟 hash 的空间利用率是多少?

在完美的情况下,也就是没有发生哈希冲突之前,它的空间利用率最高只有 50%。

因为没有发生冲突,说明至少有一半的位置是空着的。

除了只存储“指纹”,布谷鸟过滤器还能怎么提高它的空间利用率的呢?

看看论文里面怎么说的:

布隆,牛逼!布谷鸟,牛逼!

前面的(a)、(b)很简单,还是两个 hash 函数,但是没有用两个数组来存数据,就是基于一维数组的布谷鸟 hash ,核心还是踢来踢去,不多说了。

重点在于(c),对数组进行了展开,从一维变成了二维。

每一个下标,可以放 4 个元素了。

这样一个小小的转变,空间利用率从 50% 直接到了 98%:

布隆,牛逼!布谷鸟,牛逼!

我就问你怕不怕?

上面截图的论文中的第一点就是在陈诉这样一个事实:

当 hash 函数固定为 2 个的时候,如果一个下标只能放一个元素,那么空间利用率是 50%。

但是如果一个下标可以放 2,4,8 个元素的时候,空间利用率就会飙升到 84%,95%,98%。

到这里,我们明白了布谷鸟过滤器对布谷鸟 hash 的优化点和对应的工作原理。

看起来一切都是这么的完美。

各项指标都比布隆过滤器好,主打的是支持删除的操作。

但是真的这么好吗?

当我看到论文第六节的这一段的时候,沉默了:

布隆,牛逼!布谷鸟,牛逼!

对重复数据进行限制:如果需要布谷鸟过滤器支持删除,它必须知道一个数据插入过多少次。不能让同一个数据插入 kb+1 次。其中 k 是 hash 函数的个数,b 是一个下标的位置能放几个元素。

比如 2 个 hash 函数,一个二维数组,它的每个下标最多可以插入 4 个元素。那么对于同一个元素,最多支持插入 8 次。

例如下面这种情况:

布隆,牛逼!布谷鸟,牛逼!

why 已经插入了 8 次了,如果再次插入一个 why,则会出现循环踢出的问题,直到最大循环次数,然后返回一个 false。

怎么避免这个问题呢?

我们维护一个记录表,记录每个元素插入的次数就行了。

虽然逻辑简单,但是架不住数据量大呀。你想想,这个表的存储空间又怎么算呢?

想想就难受。

如果你要用布谷鸟过滤器的删除操作,那么这份难受,你不得不承受。

最后,再看一下各个类型的过滤器的对比图吧:

布隆,牛逼!布谷鸟,牛逼!

还有,其中的数学推理过程,不说了,看的眼睛疼,而且看这玩意容易掉头发。

布隆,牛逼!布谷鸟,牛逼!

荒腔走板

你知道为什么叫做“布谷鸟”吗?

布谷鸟,又叫杜鹃。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfzsx.html