github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitree/bithash_test.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package bitree 16 17 import ( 18 "fmt" 19 "os" 20 "testing" 21 "time" 22 23 "github.com/stretchr/testify/require" 24 "github.com/zuoyebang/bitalosdb/bithash" 25 "github.com/zuoyebang/bitalosdb/internal/base" 26 "github.com/zuoyebang/bitalosdb/internal/hash" 27 ) 28 29 func TestBithash_Compact(t *testing.T) { 30 defer os.RemoveAll(testDir) 31 os.RemoveAll(testDir) 32 33 testBithashSize = 1 << 20 34 btree, _ := testOpenBitree() 35 36 num := 2000 37 seqNum := uint64(0) 38 kvList := testMakeSortedKV(num, seqNum, 2048) 39 seqNum += uint64(num) 40 41 writeFunc := func() { 42 bw, err := btree.NewBitreeWriter() 43 require.NoError(t, err) 44 for i := 0; i < num; i++ { 45 pn, sentinel, closer := btree.FindKeyPageNum(kvList[i].Key.UserKey) 46 closer() 47 require.NotEqual(t, nilPageNum, pn) 48 require.NoError(t, bw.set(*kvList[i].Key, kvList[i].Value, pn, sentinel)) 49 } 50 require.NoError(t, bw.Finish()) 51 time.Sleep(1 * time.Second) 52 } 53 54 deleteFunc := func(n int) { 55 bw, err := btree.NewBitreeWriter() 56 require.NoError(t, err) 57 for i := 0; i < num; i++ { 58 if n > 0 && i%n == 0 { 59 continue 60 } 61 pn, sentinel, closer := btree.FindKeyPageNum(kvList[i].Key.UserKey) 62 closer() 63 require.NotEqual(t, nilPageNum, pn) 64 kvList[i].Key.SetKind(base.InternalKeyKindDelete) 65 kvList[i].Key.SetSeqNum(seqNum) 66 kvList[i].Value = []byte(nil) 67 require.NoError(t, bw.set(*kvList[i].Key, kvList[i].Value, pn, sentinel)) 68 seqNum++ 69 } 70 require.NoError(t, bw.Finish()) 71 time.Sleep(1 * time.Second) 72 } 73 74 readFun := func() int { 75 btree, _ = testOpenBitree() 76 findNum := 0 77 for i := 0; i < num; i++ { 78 key := kvList[i].Key.UserKey 79 value, vexist, vpool := btree.Get(key, hash.Crc32(key)) 80 if !vexist { 81 continue 82 } 83 require.Equal(t, kvList[i].Value, value) 84 vpool() 85 findNum++ 86 } 87 return findNum 88 } 89 90 writeFunc() 91 deleteFunc(2) 92 93 btree.CompactBithash(0.05) 94 require.NoError(t, testBitreeClose(btree)) 95 96 readNum := readFun() 97 require.Equal(t, int(1000), readNum) 98 require.Equal(t, bithash.FileNum(4), btree.bhash.GetFileNumMap(bithash.FileNum(4))) 99 require.NoError(t, testBitreeClose(btree)) 100 101 btree, _ = testOpenBitree() 102 deleteFunc(3) 103 btree.CompactBithash(0.05) 104 require.NoError(t, testBitreeClose(btree)) 105 106 readNum = readFun() 107 require.Equal(t, int(334), readNum) 108 require.NoError(t, testBitreeClose(btree)) 109 110 btree, _ = testOpenBitree() 111 deleteFunc(0) 112 btree.CompactBithash(0.05) 113 require.NoError(t, testBitreeClose(btree)) 114 115 readNum = readFun() 116 require.Equal(t, int(0), readNum) 117 require.NoError(t, testBitreeClose(btree)) 118 } 119 120 func TestBithash_Compact2(t *testing.T) { 121 defer os.RemoveAll(testDir) 122 os.RemoveAll(testDir) 123 124 testBithashSize = 10 << 20 125 btree, _ := testOpenBitree() 126 127 writeNum := 0 128 deleteNum := 0 129 curNum := 0 130 num := 30000 131 seqNum := uint64(0) 132 kvList := testMakeSortedKV(num, seqNum, 2048) 133 seqNum += uint64(num) 134 135 writeFunc := func() { 136 bw, err := btree.NewBitreeWriter() 137 require.NoError(t, err) 138 for writeNum < num { 139 item := kvList[writeNum] 140 pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey) 141 closer() 142 require.NotEqual(t, nilPageNum, pn) 143 require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel)) 144 writeNum++ 145 if writeNum%10000 == 0 { 146 break 147 } 148 } 149 require.NoError(t, bw.Finish()) 150 time.Sleep(1 * time.Second) 151 } 152 153 deleteFunc := func() { 154 bw, err := btree.NewBitreeWriter() 155 require.NoError(t, err) 156 for curNum < writeNum { 157 item := kvList[curNum] 158 pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey) 159 closer() 160 require.NotEqual(t, nilPageNum, pn) 161 item.Key.SetKind(base.InternalKeyKindDelete) 162 item.Key.SetSeqNum(seqNum) 163 item.Value = []byte(nil) 164 require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel)) 165 seqNum++ 166 deleteNum++ 167 curNum++ 168 if curNum > writeNum-100 { 169 break 170 } 171 } 172 curNum = writeNum 173 require.NoError(t, bw.Finish()) 174 time.Sleep(1 * time.Second) 175 } 176 177 readFun := func() int { 178 btree, _ = testOpenBitree() 179 findNum := 0 180 for i := 0; i < num; i++ { 181 key := kvList[i].Key.UserKey 182 value, vexist, vpool := btree.Get(key, hash.Crc32(key)) 183 if !vexist { 184 continue 185 } 186 require.Equal(t, kvList[i].Value, value) 187 vpool() 188 findNum++ 189 } 190 return findNum 191 } 192 193 for writeNum < num { 194 writeFunc() 195 deleteFunc() 196 btree.CompactBithash(0.05) 197 } 198 199 require.NoError(t, testBitreeClose(btree)) 200 readNum := readFun() 201 require.Equal(t, num-deleteNum, readNum) 202 require.NoError(t, testBitreeClose(btree)) 203 } 204 205 func TestBithash_Compact3(t *testing.T) { 206 defer os.RemoveAll(testDir) 207 os.RemoveAll(testDir) 208 209 testBithashSize = 1 << 20 210 btree, _ := testOpenBitree() 211 212 num := 10000 213 seqNum := uint64(0) 214 kvList := testMakeSortedKV(num, seqNum, 2048) 215 seqNum += uint64(num) 216 writeNum := 0 217 deleteNum := 0 218 219 writeFunc := func() { 220 bw, err := btree.NewBitreeWriter() 221 require.NoError(t, err) 222 for writeNum < num { 223 item := kvList[writeNum] 224 pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey) 225 closer() 226 require.NotEqual(t, nilPageNum, pn) 227 require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel)) 228 writeNum++ 229 } 230 require.NoError(t, bw.Finish()) 231 time.Sleep(1 * time.Second) 232 } 233 234 deleteFunc := func() { 235 bw, err := btree.NewBitreeWriter() 236 require.NoError(t, err) 237 for i := 0; i < writeNum; i++ { 238 item := kvList[i] 239 if i > writeNum-100 { 240 break 241 } 242 pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey) 243 closer() 244 require.NotEqual(t, nilPageNum, pn) 245 item.Key.SetKind(base.InternalKeyKindDelete) 246 item.Key.SetSeqNum(seqNum) 247 item.Value = []byte(nil) 248 require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel)) 249 deleteNum++ 250 seqNum++ 251 } 252 require.NoError(t, bw.Finish()) 253 time.Sleep(1 * time.Second) 254 } 255 256 writeFunc() 257 deleteFunc() 258 btree.CompactBithash(0.05) 259 fmt.Println("db.bhash.Stats()", btree.bhash.Stats()) 260 require.NoError(t, testBitreeClose(btree)) 261 262 btree, _ = testOpenBitree() 263 readNum := 0 264 for i := 0; i < writeNum; i++ { 265 item := kvList[i] 266 key := item.Key.UserKey 267 value, vexist, vpool := btree.Get(key, hash.Crc32(key)) 268 if i > writeNum-100 { 269 if !vexist { 270 t.Fatalf("key not find key=%s", item.Key.String()) 271 } 272 require.Equal(t, item.Value, value) 273 vpool() 274 readNum++ 275 } else if vexist { 276 t.Fatalf("delete key find key=%s", item.Key.String()) 277 } 278 } 279 require.Equal(t, num-deleteNum, readNum) 280 require.NoError(t, testBitreeClose(btree)) 281 }