github.com/fx-zpy/BloomFilter@v0.0.0-20230301111708-fc3d7eb48353/Bloom_test.go (about) 1 package BloomFilter 2 3 import ( 4 "math/rand" 5 "sync" 6 "testing" 7 "time" 8 ) 9 10 var dict = []rune("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM") 11 12 func RandStringRunes(n int) string { 13 rand.Seed(time.Now().UnixNano()) 14 a := make([]rune, n) 15 for i := range a { 16 a[i] = dict[rand.Intn(len(dict))] 17 } 18 return string(a) 19 } 20 21 func TestAdd(t *testing.T) { 22 filter := New(1024, 3, false) 23 filter.Add([]byte("bloom")). 24 AddString("filter"). 25 AddUint16(uint16(1)). 26 AddUint32(uint32(2)). 27 AddUint64(uint64(4)). 28 AddUint16Batch([]uint16{17, 21, 38}). 29 AddUint32Batch([]uint32{22, 31, 109}). 30 AddUint64Batch([]uint64{35, 29, 91}) 31 32 t.Logf("bloom exist:%t", filter.Test([]byte("bloom"))) 33 t.Logf("filter exist:%t", filter.TestString("filter")) 34 t.Logf("uint16(1) exist:%t", filter.TestUint16(uint16(1))) 35 t.Logf("uint16(17) exist:%t", filter.TestUint16(uint16(17))) 36 t.Logf("uint32(2) exist:%t", filter.TestUint32(uint32(2))) 37 t.Logf("uint32(22) exist:%t", filter.TestUint32(uint32(22))) 38 t.Logf("uint32(4) exist:%t", filter.TestUint64(uint64(4))) 39 t.Logf("uint32(35) exist:%t", filter.TestUint64(uint64(35))) 40 41 t.Logf("blllm exist:%t", filter.Test([]byte("blllm"))) 42 t.Logf("filtrr exist:%t", filter.TestString("filtrr")) 43 t.Logf("uint16(2) exist:%t", filter.TestUint16(uint16(2))) 44 t.Logf("uint16(21) exist:%t", filter.TestUint16(uint16(21))) 45 t.Logf("uint32(67) exist:%t", filter.TestUint32(uint32(67))) 46 t.Logf("uint32(31) exist:%t", filter.TestUint32(uint32(31))) 47 t.Logf("uint32(3) exist:%t", filter.TestUint64(uint64(3))) 48 t.Logf("uint32(91) exist:%t", filter.TestUint64(uint64(91))) 49 50 } 51 52 func TestAddAndGet(t *testing.T) { 53 dataSize := 1000000 54 dataMap := make(map[string]struct{}, dataSize) 55 stringLen := 30 56 filter := New(uint64(dataSize), 3, false) 57 for i := 0; i < dataSize; i++ { 58 randStr := RandStringRunes(stringLen) 59 // add unique random string 60 if _, ok := dataMap[randStr]; !ok { 61 dataMap[randStr] = struct{}{} 62 filter.Add([]byte(randStr)) 63 } 64 } 65 for k := range dataMap { 66 exist := filter.Test([]byte(k)) 67 if !exist { 68 t.Fatalf("key %s not exist", k) 69 } 70 } 71 } 72 73 func TestSync(t *testing.T) { 74 sizeData := 100000 75 stringLen := 30 76 parts := 10 77 78 filter := New(uint64(sizeData), 3, true) 79 // concurrent write and read 80 fn := func(size int, wg *sync.WaitGroup) { 81 defer wg.Done() 82 m := make(map[string]struct{}, size) 83 for i := 0; i < size; i++ { 84 randStr := RandStringRunes(stringLen) 85 // add unique random string 86 if _, ok := m[randStr]; !ok { 87 m[randStr] = struct{}{} 88 // write 89 filter.AddString(randStr) 90 // read 91 exist := filter.TestString(randStr) 92 if !exist { 93 t.Errorf("key %s not exist", randStr) 94 } 95 } 96 } 97 } 98 var waitGroup sync.WaitGroup 99 for i := 0; i < parts; i++ { 100 waitGroup.Add(1) 101 go fn(sizeData/parts, &waitGroup) 102 } 103 waitGroup.Wait() 104 } 105 106 func TestFalsePositive(t *testing.T) { 107 dataSize := 1000000 108 dataNoSize := 100000 109 dataMap := make(map[string]struct{}, dataSize) 110 dataNoMap := make(map[string]struct{}, dataNoSize) 111 stringLen := 30 112 filter := New(uint64(dataSize), 3, false) 113 114 for i := 0; i < dataSize; i++ { 115 randStr := RandStringRunes(stringLen) 116 if _, ok := dataMap[randStr]; !ok { 117 dataMap[randStr] = struct{}{} 118 filter.AddString(randStr) 119 } 120 } 121 for i := 0; i < dataNoSize; i++ { 122 randStr := RandStringRunes(stringLen) 123 // add unique random string 124 _, ok := dataMap[randStr] 125 if !ok { 126 dataNoMap[randStr] = struct{}{} 127 } 128 } 129 falsePositiveCount := 0 130 for k := range dataNoMap { 131 exist := filter.TestString(k) 132 if exist { 133 falsePositiveCount++ 134 } 135 } 136 falsePositiveRatio := float64(falsePositiveCount) / float64(dataNoSize) 137 t.Logf("false positive count:%d,false positive ratio:%f", falsePositiveCount, falsePositiveRatio) 138 } 139 140 func BenchmarkFilter_Add(b *testing.B) { 141 b.StopTimer() 142 dataTestSize := 100000 143 dataTestMap := make(map[string]struct{}, dataTestSize) 144 dataTestArr := make([]string, dataTestSize) 145 stringLen := 100 146 for i := 0; i < dataTestSize; i++ { 147 randStr := RandStringRunes(stringLen) 148 dataTestMap[randStr] = struct{}{} 149 dataTestArr = append(dataTestArr, randStr) 150 } 151 filter := New(uint64(dataTestSize), 3, false) 152 b.ResetTimer() 153 b.StartTimer() 154 for i := 0; i < len(dataTestArr); i++ { 155 filter.Add([]byte(dataTestArr[i])) 156 } 157 158 }