package mainimport ( "fmt" "math" "strconv"
) type BloomFilter struct { * bitMapk uint64 m uint64 n uint64 p float64 p_true float64
} func ( b * BloomFilter) Insert ( id uint64 ) { for i := 0 ; uint64 ( i) < b. k; i++ { b. bitMap. insert ( getHash ( strconv. Itoa ( int ( id) ) , uint64 ( i) ) % b. bitMap. Size) }
} func ( b * BloomFilter) IsExist ( id uint64 ) bool { for i := 0 ; uint64 ( i) < b. k; i++ { if ! b. bitMap. isExist ( getHash ( strconv. Itoa ( int ( id) ) , uint64 ( i) ) % b. bitMap. Size) { return false } } return true
} func NewBloomFilter ( p float64 , n uint64 ) * BloomFilter { m := uint64 ( - ( float64 ( n) * math. Log2 ( p) ) / ( math. Ln2* math. Ln2) + 0.5 ) k := uint64 ( math. Ln2* ( float64 ( m) / float64 ( n) ) + 0.5 ) p_true := math. Pow ( 1 - math. Pow ( math. E, - ( float64 ( n) * float64 ( k) ) / float64 ( m) ) , float64 ( k) ) bl := & BloomFilter{ bitMap: newBitMap ( m/ 64 + 1 ) } bl. m = m bl. n = n bl. k = k bl. p = p bl. p_true = p_true return bl
} func main ( ) { bl := NewBloomFilter ( 0.00000001 , 100 ) bl. Insert ( 10000 ) fmt. Println ( bl. IsExist ( 10000 ) ) fmt. Println ( bl. IsExist ( 10001 ) )
} func main1 ( ) { p := 0.00000000001 n := 100 m := uint ( - ( float64 ( n) * math. Log2 ( p) ) / ( math. Ln2* math. Ln2) + 0.5 ) fmt. Println ( m/ 64 + 1 ) k := uint64 ( math. Ln2* ( float64 ( m) / float64 ( n) ) + 0.5 ) fmt. Println ( m) fmt. Println ( k) p_true := float64 ( 0 ) p_true = math. Pow ( 1 - math. Pow ( math. E, - ( float64 ( n) * float64 ( k) ) / float64 ( m) ) , float64 ( k) ) fmt. Println ( p_true < p) } type bitMap struct { Map [ ] uint64 Cap uint64 Size uint64
} func newBitMap ( cap uint64 ) * bitMap { return & bitMap{ make ( [ ] uint64 , cap ) , cap , cap * 64 }
} func ( b * bitMap) insert ( id uint64 ) { b. Map[ id/ 64 ] |= 1 << ( id % 64 )
} func ( b * bitMap) isExist ( id uint64 ) bool { return ( b. Map[ id/ 64 ] ) & ( 1 << ( id% 64 ) ) > 0
} func ( b * bitMap) delete ( id uint64 ) { b. Map[ id/ 64 ] &^= 1 << ( id % 64 )
} func ( b * bitMap) range_ ( ) ( res [ ] uint64 ) { for i := 0 ; uint64 ( i) < b. Cap; i++ { if b. Map[ i] > 0 { for j, bits := 0 , b. Map[ i] ; bits > 0 ; j, bits = j+ 1 , bits>> 1 { if bits& 1 == 1 { res = append ( res, uint64 ( i) * 64 + uint64 ( j) ) } } } } return res
} func getHash ( str string , i uint64 ) uint64 { return hash ( str) + i* hash1 ( str)
} func hash ( str string ) ( res uint64 ) { factor := ")k+,p-m~90$#2(*&6q}ev73541]n{fl['?|c" str = str + factor[ : 16 - ( len ( str) % 16 ) ] for start, end := 0 , len ( str) / 16 ; end > 0 ; start, end = start+ 16 , end- 1 { h0 := uint64 ( 0 ) for i := 15 ; i >= 0 ; i-- { h0 += uint64 ( str[ start+ i] - byte ( i) ) * uint64 ( pow ( 36 , i) ) ^ uint64 ( factor[ ( i+ start) % 36 ] ) } h0 *= 0x12345 res += ( res >> 30 ) ^ h0<< 34 res += ( res >> 32 ) | ( h0 << 32 ) ^ uint64 ( start* start* start) ^ uint64 ( factor[ start% 36 ] ) res += ( res>> 16 ) & ( h0<< 48 ) ^ uint64 ( factor[ 35 - start% 36 ] ) ^ uint64 ( start- end* end) res += ( res >> 17 ) | ( h0 << 47 ) ^ uint64 ( start* start) } res += 235791113 << 32 | 1719232931 >> 32 return res
} func hash1 ( str string ) ( res uint64 ) { factor := ")k+,p-m~90$#2(*&6q}ev73541]n{fl['?|c" str = str + factor[ : 16 - ( len ( str) % 16 ) ] for start, end := 0 , len ( str) / 16 ; end > 0 ; start, end = start+ 16 , end- 1 { h0 := uint64 ( 0 ) for i := 15 ; i >= 0 ; i-- { h0 += uint64 ( str[ start+ i] - byte ( i) ) * uint64 ( pow ( 36 , i) ) ^ uint64 ( factor[ ( i+ start) % 36 ] ) } h0 *= 0x54321 res += ( res >> 32 ) | ( h0 << 32 ) ^ uint64 ( start* start* start) ^ uint64 ( factor[ start% 36 ] ) res += ( res>> 16 ) & ( h0<< 48 ) ^ uint64 ( factor[ 35 - start% 36 ] ) ^ uint64 ( start- end* end) res += ( res >> 17 ) | ( h0 << 47 ) ^ uint64 ( start* start) res += ( res >> 30 ) ^ h0<< 34 } res += 1719232931 << 32 | 235791113 >> 32 return res
} func pow ( x, n int ) int { if n == 0 { return 1 } else { for ( n & 1 ) == 0 { n, x = n>> 1 , x* x} } result := xn >>= 1 for n != 0 { x *= xif n& 1 == 1 { result *= x} n >>= 1 } return result
}