实现原理 #
布隆过滤器由一个位数组(bit array)和多个哈希函数(hash functions)组成。其工作原理如下:
- 初始化:
- 创建一个长度为
m的位数组,将所有位初始化为 0。 - 选择
k个独立的哈希函数,每个哈希函数将输入映射到[0, m-1]范围内的一个位置。
- 创建一个长度为
- 插入元素:
- 对于要插入的元素,通过
k个哈希函数分别计算出k个哈希值。 - 将位数组中这
k个位置的值设置为 1。
- 对于要插入的元素,通过
- 查询元素:
- 对于要查询的元素,通过
k个哈希函数分别计算出k个哈希值。 - 检查位数组中这
k个位置的值,如果所有位置的值都为 1,则认为该元素可能在集合中;如果有任何一个位置的值为 0,则认为该元素不在集合中。
- 对于要查询的元素,通过
代码实现 #
package bloomfilter
import (
"hash/fnv"
"math"
)
type BloomFilter struct {
bitset []bool //比特数组
m int //比特数组长度
k int //哈希函数数量
}
func NewBloomFilter(n int, p float64) *BloomFilter {
m := int(math.Ceil(float64(-n) * math.Log(p) / math.Pow(math.Log(2), 2)))
k := int(math.Ceil(math.Log(2) * float64(m) / float64(n)))
return &BloomFilter{
bitset: make([]bool, m),
m: m,
k: k,
}
}
// 哈希函数
func (bf *BloomFilter) hash(data []byte, seed uint32) int {
h := fnv.New32a()
h.Write(data)
hash := h.Sum32()
return int((hash + seed) % uint32(bf.m))
}
// 添加元素
func (bf *BloomFilter) Add(item string) {
for i := 0; i < bf.k; i++ {
pos := bf.hash([]byte(item), uint32(i))
bf.bitset[pos] = true
}
}
// 查找元素
func (bf *BloomFilter) Contains(item string) bool {
for i := 0; i < bf.k; i++ {
pos := bf.hash([]byte(item), uint32(i))
if !bf.bitset[pos] {
return false
}
}
return true
}