布隆过滤器的简单实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 package utilsimport ( "hash" "math" "sync" "github.com/bits-and-blooms/bitset" "github.com/twmb/murmur3" ) type BloomFilter struct { bitset *bitset.BitSet size uint64 hashFuncs []hash.Hash64 mutex sync.RWMutex } func NewWithFalsePositiveRate (expectedItems uint64 , falsePositiveRate float64 ) *BloomFilter { m, k := optimalParameters(expectedItems, falsePositiveRate) funcs := make ([]hash.Hash64, k) for i := 0 ; i < k; i++ { funcs[i] = murmur3.SeedNew64(uint64 (i)) } return &BloomFilter{ bitset: bitset.New(uint (m)), size: m, hashFuncs: funcs, mutex: sync.RWMutex{}, } } func optimalParameters (n uint64 , p float64 ) (uint64 , int ) { m := uint64 (math.Ceil(-float64 (n) * math.Log(p) / (math.Ln2 * math.Ln2))) k := int (math.Ceil(math.Ln2 * float64 (m) / float64 (n))) return m, k } func (bf *BloomFilter) Add(item []byte ) { bf.mutex.Lock() defer bf.mutex.Unlock() for _, h := range bf.hashFuncs { h.Reset() _, _ = h.Write(item) index := h.Sum64() % bf.size bf.bitset.Set(uint (index)) } } func (bf *BloomFilter) Contains(item []byte ) bool { bf.mutex.RLock() defer bf.mutex.RUnlock() for _, h := range bf.hashFuncs { h.Reset() _, _ = h.Write(item) index := h.Sum64() % bf.size if !bf.bitset.Test(uint (index)) { return false } } return true }
Reference 图解各类限流算法|固定窗口/计数器、滑动窗口、漏桶算法、令牌桶算法
bloom-filter.go