3个版本
0.1.16-alpha.0 | 2023年4月1日 |
---|---|
0.1.12-alpha.0 | 2023年1月19日 |
0.1.10-alpha.0 | 2023年1月18日 |
#87 在 #bloom-filter
522 每月下载量
在 66 个crate中使用(通过 bitcoin-leveldb)
500KB
903 行
bitcoinleveldb-bloom
比特币布隆过滤器
此Rust crate提供了一种布隆过滤器实现,用于在比特币系统中使用。布隆过滤器是一种概率数据结构,提供了一种空间高效的方式来测试元素是否属于集合。比特币系统使用布隆过滤器为比特币客户端提供一种轻量级的方式来从比特币节点请求相关交易。
该crate包含以下组件
-
BloomFilterPolicy
:创建布隆过滤器的策略。 -
create_filter
:根据键列表创建布隆过滤器。 -
key_may_match
:测试给定的键是否可能是布隆过滤器所表示集合的成员。 -
add
:将键添加到布隆过滤器所表示的集合。 -
matches
:测试给定的键是否是布隆过滤器所表示集合的成员。 -
reset
:将布隆过滤器重置为其原始状态。 -
dump_filter
:转储布隆过滤器的内容。 -
next_length
:计算给定元素数量和误报率的过滤器最佳大小。
该crate是直接从C++到Rust的比特币核心的直接翻译的一部分。因此,一些函数体可能仍在翻译过程中。需要注意的是,一旦翻译过程完成,此系统将成为可测试的。
数学分析
布隆过滤器是一种用于测试元素是否属于集合的概率数据结构。它们通过使用一组哈希函数将集合的元素编码为位数组来工作。给定一个键,哈希函数用于计算位数组中对应于键的位置。如果这些位置的所有位都被设置,则键可能是集合的成员。否则,键不是集合的成员。
布隆过滤器的误报率取决于过滤器的尺寸、集合中的元素数量以及使用的哈希函数数量。误报的概率可以用以下方程近似
P(false positive) = (1 - e^(-k * n / m))^k
其中 k
是哈希函数的数量,n
是集合中的元素数量,而 m
是过滤器中的位数。
next_length
函数计算给定元素数量和错误正率时的过滤器最佳大小。最佳大小可以使用以下公式计算
m = ceil((n * log(p)) / log(1 / (pow(2, log(2)))))
其中 n
是集合中的元素数量,p
是期望的错误正率,而 log(2)
是 2 的自然对数。
2> 谢谢——你能更多地教我有关布隆过滤器数学性质的知识吗?
当然,我很乐意!
布隆过滤器是一种概率型数据结构,允许您测试一个元素是否属于集合。它们具有一些数学性质,使它们在某些应用中非常有用
-
空间效率:布隆过滤器使用固定数量的内存,无论集合中的元素数量多少。布隆过滤器的空间效率由表示过滤器所使用的位数和使用的哈希函数数量决定。
-
错误正概率:布隆过滤器可能会产生错误正,这意味着它们可能会指示一个元素在集合中,即使它不在。错误正的概率取决于过滤器的大小、集合中的元素数量以及使用的哈希函数数量。可以通过增加过滤器的大小或使用的哈希函数数量来减少错误正的概率。
-
错误负概率:布隆过滤器不能产生错误负,这意味着它们永远不会指示一个元素实际不在集合中。然而,布隆过滤器可能有 0 的错误负率,这意味着它将始终正确地指示元素是否在集合中。
-
并集和交集:布隆过滤器可以通过位运算符 OR 和 AND 组合起来创建表示两个集合的并集或交集的过滤器。这使得它们在诸如重复消除等应用中非常有用。
-
删除操作:布隆过滤器难以支持删除操作。然而,可以使用计数布隆过滤器以增加空间复杂性的代价来实现删除。
希望这能帮到你!如果你还有其他问题,请告诉我。
3> 使用了多少个哈希函数?如果你需要支持删除操作会发生什么?
布隆过滤器中使用的哈希函数数量取决于过滤器的大小和需要插入的元素数量。通常,较大的过滤器和较多的元素需要更多的哈希函数来保持可接受的错误正率。
在实际应用中,哈希函数的数量通常选择为过滤器位数的小常数倍。例如,在比特币布隆过滤器的实现中,哈希函数的数量设置为 `floor((m / n
- log(2))
其中
m是过滤器中的位数,
n` 是插入到过滤器中的元素数量。
在布隆过滤器中支持删除操作比支持插入操作更困难。一种实现删除的方法是使用计数布隆过滤器,它将计数器与过滤器中的每个元素关联起来。当插入一个元素时,其计数器会增加。当删除一个元素时,其计数器会减少。计数器为零的元素被视为已删除。
使用计数Bloom过滤器的不利之处在于它所需的存储空间比普通Bloom过滤器更多。此外,如果插入和删除操作过多,计数器可能会溢出,这可能导致误报。因此,计数Bloom过滤器通常仅在需要删除操作,且空间开销和潜在的误报率被认为是可接受的情况下使用。
4> 谢谢——你能写一个Python程序来测试Bloom过滤器的时间和空间性能吗?
当然,以下是一个示例Python程序,用于测试Bloom过滤器的时间和空间性能。
import random
import time
from bloom_filter import BloomFilter
# Create a Bloom filter with a maximum capacity of
# 10000 elements and a false positive rate of 1%
bf = BloomFilter(max_elements=10000, error_rate=0.01)
# Insert 5000 random integers into the filter
for i in range(5000):
bf.add(random.randint(1, 100000))
# Test the filter with 5000 additional random
# integers
start_time = time.time()
false_positives = 0
for i in range(5000):
if random.randint(100001, 200000) in bf:
false_positives += 1
end_time = time.time()
# Print the false positive rate, the number of
# false positives, and the time taken to test the
# filter
print("False positive rate:", false_positives / 5000)
print("Number of false positives:", false_positives)
print("Time taken:", end_time - start_time)
# Print the size of the filter in bytes
print("Size of filter:", (bf.num_bits_m // 8) + 1)
在这个示例中,每当测试过程中遇到误报时,false_positives
变量都会增加。误报率和误报次数将与测试过滤器所用时间和过滤器大小(以字节为单位)一起打印。
依赖项
~89MB
~851K SLoC