github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitable_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 bitalosdb 16 17 import ( 18 "fmt" 19 "os" 20 "testing" 21 22 "github.com/stretchr/testify/require" 23 "github.com/zuoyebang/bitalosdb/internal/base" 24 "github.com/zuoyebang/bitalosdb/internal/utils" 25 ) 26 27 var defaultLargeVal = testRandBytes(1024) 28 29 func bdbWriteKVRange(t *testing.T, db *DB, start, end int, kprefix, vprefix string) { 30 for i := start; i <= end; i++ { 31 key := makeTestKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 32 value := []byte(fmt.Sprintf("%s_%s%s", key, defaultLargeVal, vprefix)) 33 require.NoError(t, db.Set(key, value, nil)) 34 } 35 require.NoError(t, db.Flush()) 36 } 37 38 func bdbReadKV(t *testing.T, db *DB, num int, kprefix, vprefix string) { 39 for i := 1; i <= num; i++ { 40 key := makeTestKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 41 value := []byte(fmt.Sprintf("%s_%s%s", key, defaultLargeVal, vprefix)) 42 require.NoError(t, verifyGet(db, key, value)) 43 } 44 } 45 46 func bdbWriteSameKVRange(t *testing.T, db *DB, start, end int, kprefix, vprefix string) { 47 for i := start; i <= end; i++ { 48 key := makeTestSlotKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 49 value := []byte(fmt.Sprintf("%s_%s%s", key, defaultLargeVal, vprefix)) 50 require.NoError(t, db.Set(key, value, nil)) 51 } 52 require.NoError(t, db.Flush()) 53 } 54 55 func bdbReadSameKV(t *testing.T, db *DB, num int, kprefix, vprefix string) { 56 for i := 1; i <= num; i++ { 57 key := makeTestSlotKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 58 value := []byte(fmt.Sprintf("%s_%s%s", key, defaultLargeVal, vprefix)) 59 require.NoError(t, verifyGet(db, key, value)) 60 } 61 } 62 63 func bdbDeleteKV(t *testing.T, db *DB, num int, kprefix string) { 64 for i := 1; i <= num; i++ { 65 if i%2 == 0 { 66 continue 67 } 68 key := makeTestKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 69 require.NoError(t, db.Delete(key, nil)) 70 } 71 require.NoError(t, db.Flush()) 72 } 73 74 func bdbDeleteSameKV(t *testing.T, db *DB, num int, kprefix string) { 75 for i := 1; i <= num; i++ { 76 if i%2 == 0 { 77 continue 78 } 79 key := makeTestSlotKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 80 require.NoError(t, db.Delete(key, nil)) 81 } 82 require.NoError(t, db.Flush()) 83 } 84 85 func bdbReadDeleteKV(t *testing.T, db *DB, num int, kprefix, vprefix string) { 86 for i := 1; i <= num; i++ { 87 newKey := makeTestKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 88 newValue := []byte(fmt.Sprintf("%s_%s%s", newKey, defaultLargeVal, vprefix)) 89 v, closer, err := db.Get(newKey) 90 if i%2 == 0 { 91 require.NoError(t, err) 92 require.Equal(t, newValue, v) 93 } else { 94 require.Equal(t, ErrNotFound, err) 95 } 96 97 if closer != nil { 98 closer() 99 } 100 } 101 } 102 103 func bdbReadDeleteSameKV(t *testing.T, db *DB, num int, kprefix, vprefix string) { 104 for i := 1; i <= num; i++ { 105 newKey := makeTestSlotKey([]byte(fmt.Sprintf("key_%d%s", i, kprefix))) 106 newValue := []byte(fmt.Sprintf("%s_%s%s", newKey, defaultLargeVal, vprefix)) 107 v, closer, err := db.Get(newKey) 108 if i%2 == 0 { 109 require.NoError(t, err) 110 require.Equal(t, newValue, v) 111 } else { 112 require.Equal(t, ErrNotFound, err) 113 } 114 115 if closer != nil { 116 closer() 117 } 118 } 119 } 120 121 func TestBitableWriteRead(t *testing.T) { 122 defer os.RemoveAll(testDirname) 123 os.RemoveAll(testDirname) 124 125 testOptsUseBitable = true 126 db := openTestDB(testDirname, nil) 127 num := 100 128 bdbWriteKVRange(t, db, 1, num, "bitableKey1", "bitableValue1") 129 bdbReadKV(t, db, num, "bitableKey1", "bitableValue1") 130 require.Equal(t, false, db.isFlushedBitable()) 131 db.compactToBitable(1) 132 bdbReadKV(t, db, num, "bitableKey1", "bitableValue1") 133 bdbWriteKVRange(t, db, 1, num, "bdbKey1", "bdbValue1") 134 require.Equal(t, true, db.isFlushedBitable()) 135 require.NoError(t, db.Close()) 136 testOptsUseBitable = true 137 db = openTestDB(testDirname, nil) 138 require.Equal(t, true, db.isFlushedBitable()) 139 bdbReadKV(t, db, num, "bitableKey1", "bitableValue1") 140 bdbReadKV(t, db, num, "bdbKey1", "bdbValue1") 141 require.NoError(t, db.Close()) 142 } 143 144 func TestBitableDelete(t *testing.T) { 145 defer os.RemoveAll(testDirname) 146 os.RemoveAll(testDirname) 147 testOptsUseBitable = true 148 db := openTestDB(testDirname, nil) 149 num := 1000 150 bdbWriteKVRange(t, db, 1, 500, "", "") 151 db.compactToBitable(1) 152 bdbWriteKVRange(t, db, 501, num, "", "") 153 bdbDeleteKV(t, db, num, "") 154 bdbReadDeleteKV(t, db, num, "", "") 155 require.NoError(t, db.Close()) 156 } 157 158 func TestBitableIter(t *testing.T) { 159 defer os.RemoveAll(testDirname) 160 os.RemoveAll(testDirname) 161 testOptsUseBitable = true 162 db := openTestDB(testDirname, nil) 163 num := 100 164 bdbWriteSameKVRange(t, db, 1, 50, "", "") 165 db.compactToBitable(1) 166 bdbWriteSameKVRange(t, db, 51, 100, "", "") 167 bdbReadSameKV(t, db, num, "", "") 168 require.NoError(t, db.Close()) 169 testOptsUseBitable = true 170 testIterSeek(t) 171 testOptsUseBitable = true 172 testIter(t) 173 } 174 175 func TestBitableIterSeek(t *testing.T) { 176 defer os.RemoveAll(testDirname) 177 os.RemoveAll(testDirname) 178 testOptsUseBitable = true 179 db := openTestDB(testDirname, nil) 180 defer func() { 181 require.NoError(t, db.Close()) 182 }() 183 184 makeKey := func(i int) []byte { 185 return makeTestSlotKey([]byte(fmt.Sprintf("key_%d", i))) 186 } 187 188 value := utils.FuncRandBytes(520) 189 num := 100 190 writeKV := func(filter int) { 191 for i := 0; i < num; i++ { 192 if i >= 1 && i < 10 { 193 continue 194 } 195 if i%2 == filter { 196 continue 197 } 198 newKey := makeKey(i) 199 require.NoError(t, db.Set(newKey, value, nil)) 200 } 201 require.NoError(t, db.Flush()) 202 } 203 204 writeKV(0) 205 db.compactToBitable(1) 206 writeKV(1) 207 208 seekGE := func(it *Iterator, seek, want int) { 209 exist := it.SeekGE(makeKey(seek)) 210 if want == -1 { 211 require.Equal(t, false, exist) 212 require.Equal(t, false, it.Valid()) 213 } else { 214 require.Equal(t, true, exist) 215 require.Equal(t, true, it.Valid()) 216 require.Equal(t, makeKey(want), it.Key()) 217 require.Equal(t, value, it.Value()) 218 } 219 } 220 iter := db.NewIter(&IterOptions{SlotId: uint32(testSlotId)}) 221 seekGE(iter, 14, 14) 222 seekGE(iter, 141, 15) 223 seekGE(iter, 29, 29) 224 seekGE(iter, 290, 30) 225 seekGE(iter, 491, 50) 226 seekGE(iter, 990, -1) 227 require.NoError(t, iter.Close()) 228 229 seekLT := func(it *Iterator, seek, want int) { 230 exist := it.SeekLT(makeKey(seek)) 231 if want == -1 { 232 require.Equal(t, false, exist) 233 require.Equal(t, false, it.Valid()) 234 } else { 235 require.Equal(t, true, exist) 236 require.Equal(t, true, it.Valid()) 237 require.Equal(t, makeKey(want), it.Key()) 238 require.Equal(t, value, it.Value()) 239 } 240 } 241 iter = db.NewIter(&IterOptions{SlotId: uint32(testSlotId)}) 242 seekLT(iter, 14, 13) 243 seekLT(iter, 141, 14) 244 seekLT(iter, 30, 29) 245 seekLT(iter, 31, 30) 246 seekLT(iter, 50, 49) 247 seekLT(iter, 990, 99) 248 seekLT(iter, 0, -1) 249 require.NoError(t, iter.Close()) 250 251 for i := 0; i < num; i++ { 252 if i > 0 && i < 90 { 253 continue 254 } 255 newKey := makeKey(i) 256 if err := db.Delete(newKey, nil); err != nil { 257 t.Fatal("delete err", string(newKey), err) 258 } 259 } 260 require.NoError(t, db.Flush()) 261 262 searchKV := func(it *Iterator) { 263 defer func() { 264 require.NoError(t, iter.Close()) 265 }() 266 require.Equal(t, true, iter.First()) 267 require.Equal(t, makeKey(10), iter.Key()) 268 require.Equal(t, value, iter.Value()) 269 require.Equal(t, true, iter.Next()) 270 require.Equal(t, makeKey(11), iter.Key()) 271 require.Equal(t, value, iter.Value()) 272 seekGE(iter, 2, 20) 273 require.Equal(t, true, iter.Prev()) 274 require.Equal(t, makeKey(19), iter.Key()) 275 require.Equal(t, value, iter.Value()) 276 require.Equal(t, true, iter.Next()) 277 require.Equal(t, makeKey(20), iter.Key()) 278 require.Equal(t, value, iter.Value()) 279 require.Equal(t, true, iter.Last()) 280 require.Equal(t, makeKey(89), iter.Key()) 281 require.Equal(t, value, iter.Value()) 282 require.Equal(t, true, iter.Prev()) 283 require.Equal(t, makeKey(88), iter.Key()) 284 require.Equal(t, value, iter.Value()) 285 seekLT(iter, 60, 59) 286 require.Equal(t, true, iter.Next()) 287 require.Equal(t, makeKey(60), iter.Key()) 288 require.Equal(t, value, iter.Value()) 289 require.Equal(t, true, iter.Prev()) 290 require.Equal(t, makeKey(59), iter.Key()) 291 require.Equal(t, value, iter.Value()) 292 } 293 294 iter = db.NewIter(&IterOptions{SlotId: uint32(testSlotId)}) 295 searchKV(iter) 296 iter = db.NewIter(&IterOptions{IsAll: true}) 297 searchKV(iter) 298 299 require.NoError(t, db.Flush()) 300 iter = db.NewIter(&IterOptions{SlotId: uint32(testSlotId)}) 301 searchKV(iter) 302 iter = db.NewIter(&IterOptions{IsAll: true}) 303 searchKV(iter) 304 } 305 306 func TestBitableSameDelete(t *testing.T) { 307 defer os.RemoveAll(testDirname) 308 os.RemoveAll(testDirname) 309 testOptsUseBitable = true 310 db := openTestDB(testDirname, nil) 311 defer func() { 312 require.NoError(t, db.Close()) 313 }() 314 315 num := 1000 316 bdbWriteSameKVRange(t, db, 1, 500, "", "") 317 db.compactToBitable(1) 318 bdbWriteSameKVRange(t, db, 501, num, "", "") 319 bdbDeleteSameKV(t, db, num, "") 320 bdbReadDeleteSameKV(t, db, num, "", "") 321 } 322 323 func TestBitableCompactDelete(t *testing.T) { 324 defer os.RemoveAll(testDirname) 325 os.RemoveAll(testDirname) 326 327 db := testOpenDB(false) 328 bw, err := db.newFlushWriter() 329 require.NoError(t, err) 330 largeValue := utils.FuncRandBytes(1900) 331 smallValue := utils.FuncRandBytes(2100) 332 seqNum := uint64(0) 333 keyCount := 10000 334 kvList := testMakeSortedKVList(0, keyCount, seqNum, 1) 335 seqNum += uint64(keyCount) 336 337 for i := 0; i < keyCount; i++ { 338 if i%2 == 0 { 339 kvList[i].Value = smallValue 340 } else { 341 kvList[i].Value = largeValue 342 } 343 require.NoError(t, bw.Set(*kvList[i].Key, kvList[i].Value)) 344 } 345 require.NoError(t, bw.Finish()) 346 347 readKV := func(hasDel bool) { 348 for i := 0; i < keyCount; i++ { 349 v, vcloser, err := db.Get(kvList[i].Key.UserKey) 350 if hasDel && i%9 == 0 { 351 require.Equal(t, ErrNotFound, err) 352 require.Equal(t, 0, len(v)) 353 } else { 354 require.Equal(t, kvList[i].Value, v) 355 vcloser() 356 } 357 } 358 } 359 360 readKV(false) 361 db.compactToBitable(1) 362 readKV(false) 363 364 bw, err = db.newFlushWriter() 365 require.NoError(t, err) 366 largeValue = utils.FuncRandBytes(1900) 367 smallValue = utils.FuncRandBytes(2100) 368 for i := 0; i < keyCount; i++ { 369 if i%9 == 0 { 370 kvList[i].Key.SetKind(base.InternalKeyKindDelete) 371 kvList[i].Key.SetSeqNum(seqNum) 372 kvList[i].Value = []byte(nil) 373 } else { 374 if i%2 == 0 { 375 kvList[i].Value = smallValue 376 } else { 377 kvList[i].Value = largeValue 378 } 379 kvList[i].Key.SetKind(base.InternalKeyKindSet) 380 kvList[i].Key.SetSeqNum(seqNum) 381 } 382 seqNum++ 383 require.NoError(t, bw.Set(*kvList[i].Key, kvList[i].Value)) 384 } 385 require.NoError(t, bw.Finish()) 386 387 readKV(true) 388 389 require.NoError(t, db.Close()) 390 }