实现
leveldb中的布隆过滤器实现较为简单,以goleveldb为例,有关的代码在filter/bloom.go中。
定义如下,bloom过滤器只是一个int数字。
- type bloomFilter int
创建一个布隆过滤器时,只需要指定为每个key分配的位数即可,如结论2所示,只要该值(m/n)大于1.44即可,一般可以取10。
- func NewBloomFilter(bitsPerKey int) Filter {
- return bloomFilter(bitsPerKey)
- }
创建一个generator, 这一步中需要指定哈希函数的个数k,可以看到k = f *ln2,而f = m/n,即数学结论1。
返回的generator中可以添加新的key信息,调用generate函数时,将所有的key构建成一个位数组写在指定的位置。
- func (f bloomFilter) NewGenerator() FilterGenerator {
- // Round down to reduce probing cost a little bit.
- k := uint8(f * 69 / 100) // 0.69 =~ ln(2)
- if k < 1 {
- k = 1
- } else if k > 30 {
- k = 30
- }
- return &bloomFilterGenerator{
- n: int(f),
- k: k,
- }
- }
generator主要有两个函数:
- Add
- GenerateAdd函数中,只是简单地将key的哈希散列值存储在一个整型数组中
- func (g *bloomFilterGenerator) Add(key []byte) {
- // Use double-hashing to generate a sequence of hash values.
- // See analysis in [Kirsch,Mitzenmacher 2006].
- g.keyHashes = append(g.keyHashes, bloomHash(key))
- }
Generate函数中,将之前一段时间内所有添加的key信息用来构建一个位数组,该位数组中包含了所有key的存在信息。
位数组的大小为用户指定的每个key所分配的位数 乘以 key的个数。
位数组的最末尾用来存储k的大小。
- func (g *bloomFilterGenerator) Generate(b Buffer) {
- // Compute bloom filter size (in both bits and bytes)
- // len(g.keyHashes) 可以理解为n, g.n可以理解为m/n
- // nBits可以理解为m
- nBits := uint32(len(g.keyHashes) * g.n)
- // For small n, we can see a very high false positive rate. Fix it
- // by enforcing a minimum bloom filter length.
- if nBits < 64 {
- nBits = 64
- }
- nBytes := (nBits + 7) / 8
- nBits = nBytes * 8
- dest := b.Alloc(int(nBytes) + 1)
- dest[nBytes] = g.k
- for _, kh := range g.keyHashes {
- // Double Hashing
- delta := (kh >> 17) | (kh << 15) // Rotate right 17 bits
- for j := uint8(0); j < g.k; j++ {
- bitpos := kh % nBits
- dest[bitpos/8] |= (1 << (bitpos % 8))
- kh += delta
- }
- }
- g.keyHashes = g.keyHashes[:0]
- }
Contain函数用来判断指定的key是否存在。
- func (f bloomFilter) Contains(filter, key []byte) bool {
- nBytes := len(filter) - 1
- if nBytes < 1 {
- return false
- }
- nBits := uint32(nBytes * 8)
- // Use the encoded k so that we can read filters generated by
- // bloom filters created using different parameters.
- k := filter[nBytes]
- if k > 30 {
- // Reserved for potentially new encodings for short bloom filters.
- // Consider it a match.
- return true
- }
- kh := bloomHash(key)
- delta := (kh >> 17) | (kh << 15) // Rotate right 17 bits
- for j := uint8(0); j < k; j++ {
- bitpos := kh % nBits
- if (uint32(filter[bitpos/8]) & (1 << (bitpos % 8))) == 0 {
- return false
- }
- kh += delta
- }
- return true
- }
当前内容版权归 rjl493456442 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 rjl493456442 .