-
Notifications
You must be signed in to change notification settings - Fork 3
/
strategy.go
136 lines (117 loc) · 3.44 KB
/
strategy.go
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package bloomfilter
import (
"log"
"math"
"github.com/Workiva/go-datastructures/bitarray"
"github.com/spaolacci/murmur3"
)
// Strategy defines necessary functions for a strategy.
type Strategy interface {
put(key interface{}, numHashFunctions int, array bitarray.BitArray) bool
mightContain(key interface{}, numHashFunctions int, array bitarray.BitArray) bool
getOrdinal() int
}
// Murur128Mitz32 is the implementation of Guava's MURMUR128_MITZ_32 class in Go.
// See https://github.com/google/guava/blob/master/guava/src/com/google/common/hash/BloomFilterStrategies.java#L45 for details.
type Murur128Mitz32 struct{}
func (m *Murur128Mitz32) put(key interface{}, numHashFunctions int, array bitarray.BitArray) bool {
bitSize := array.Capacity()
bytes := GetBytes(key)
if len(bytes) == 0 {
log.Printf("Failed to convert %v to byte array\n", key)
return false
}
hash64, _ := murmur3.Sum128(bytes)
hash1 := int32(hash64)
hash2 := int32(hash64 >> 32)
bitsChanged := false
var i int32 = 0
for ; i < int32(numHashFunctions); i++ {
combinedHash := hash1 + (i * hash2)
if combinedHash < 0 {
combinedHash = int32(uint32(combinedHash) ^ uint32(0xFFFFFFFF))
}
index := uint64(combinedHash) % bitSize
result, _ := array.GetBit(index)
if !result {
bitsChanged = true
array.SetBit(index)
}
}
return bitsChanged
}
func (m *Murur128Mitz32) mightContain(key interface{}, numHashFunctions int, array bitarray.BitArray) bool {
bitSize := array.Capacity()
bytes := GetBytes(key)
if len(bytes) == 0 {
log.Printf("Failed to convert %v to byte array\n", key)
return false
}
hash64, _ := murmur3.Sum128(bytes)
hash1 := int32(hash64)
hash2 := int32(hash64 >> 32)
var i int32 = 0
for ; i < int32(numHashFunctions); i++ {
combinedHash := hash1 + (i * hash2)
if combinedHash < 0 {
combinedHash = int32(uint32(combinedHash) ^ uint32(0xFFFFFFFF))
}
index := uint64(combinedHash) % bitSize
result, _ := array.GetBit(index)
if !result {
return false
}
}
return true
}
func (m *Murur128Mitz32) getOrdinal() int {
return 0
}
// Murur128Mitz64 is the implementation of Guava's MURMUR128_MITZ_64 class in Go.
// See https://github.com/google/guava/blob/master/guava/src/com/google/common/hash/BloomFilterStrategies.java#L93 for details.
type Murur128Mitz64 struct{}
func (m *Murur128Mitz64) put(key interface{}, numHashFunctions int, array bitarray.BitArray) bool {
bitSize := array.Capacity()
bytes := GetBytes(key)
if len(bytes) == 0 {
log.Printf("Failed to convert %v to byte array\n", key)
return false
}
hash1, hash2 := murmur3.Sum128(bytes)
bitsChanged := false
combinedHash := hash1
var index uint64
for i := 0; i < numHashFunctions; i++ {
index = (combinedHash & math.MaxInt64) % bitSize
result, _ := array.GetBit(index)
if !result {
bitsChanged = true
array.SetBit(index)
}
combinedHash += hash2
}
return bitsChanged
}
func (m *Murur128Mitz64) mightContain(key interface{}, numHashFunctions int, array bitarray.BitArray) bool {
bitSize := array.Capacity()
bytes := GetBytes(key)
if len(bytes) == 0 {
log.Printf("Failed to convert %v to byte array\n", key)
return false
}
hash1, hash2 := murmur3.Sum128(bytes)
combinedHash := hash1
var index uint64
for i := 0; i < numHashFunctions; i++ {
index = (combinedHash & math.MaxInt64) % bitSize
result, _ := array.GetBit(index)
if !result {
return false
}
combinedHash += hash2
}
return true
}
func (m *Murur128Mitz64) getOrdinal() int {
return 1
}