github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/bitpage_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 bitpage 16 17 import ( 18 "bytes" 19 "fmt" 20 "math/rand" 21 "os" 22 "sync" 23 "testing" 24 "time" 25 26 "github.com/stretchr/testify/require" 27 "github.com/zuoyebang/bitalosdb/internal/consts" 28 "github.com/zuoyebang/bitalosdb/internal/hash" 29 "github.com/zuoyebang/bitalosdb/internal/options" 30 "github.com/zuoyebang/bitalosdb/internal/sortedkv" 31 "github.com/zuoyebang/bitalosdb/internal/utils" 32 ) 33 34 const testDir = "test" 35 const testSlotId uint16 = 1 36 37 var nilInternalKey = (*internalKey)(nil) 38 39 var testParams = [][]bool{ 40 {true, false, false}, 41 {true, true, false}, 42 {true, false, true}, 43 {true, true, true}, 44 } 45 46 func testMakeSortedKV(num int, seqNum uint64, vsize int) sortedkv.SortedKVList { 47 return sortedkv.MakeSortedKVList(0, num, seqNum, vsize) 48 } 49 50 func testMakeSortedKVForBitrie(num int, seqNum uint64, vsize int) sortedkv.SortedKVList { 51 return sortedkv.MakeSortedKVListForBitrie(0, num, seqNum, vsize) 52 } 53 54 func testInitDir() { 55 _, err := os.Stat(testDir) 56 if nil != err && !os.IsExist(err) { 57 err = os.MkdirAll(testDir, 0775) 58 } 59 } 60 61 func testInitOpts() *options.BitpageOptions { 62 optspool := options.InitTestDefaultsOptionsPool() 63 opts := optspool.CloneBitpageOptions() 64 return opts 65 } 66 67 func testOpenBitpage(UseMapIndex bool) (*Bitpage, error) { 68 testInitDir() 69 opts := testInitOpts() 70 opts.Index = 1 71 opts.UseMapIndex = UseMapIndex 72 return Open(testDir, opts) 73 } 74 75 func testOpenBitpage2(dir string, mapIndex, prefix, block bool) (*Bitpage, error) { 76 testInitDir() 77 opts := testInitOpts() 78 opts.Index = 1 79 opts.UseMapIndex = mapIndex 80 opts.UsePrefixCompress = prefix 81 opts.UseBlockCompress = block 82 return Open(dir, opts) 83 } 84 85 func testCloseBitpage(t *testing.T, b *Bitpage) { 86 require.NoError(t, b.Close()) 87 b.opts.DeleteFilePacer.Close() 88 } 89 90 func makeTestKey(i int) []byte { 91 return []byte(fmt.Sprintf("bitpage_key_%d", i)) 92 } 93 94 func TestBitpage_Open(t *testing.T) { 95 defer os.RemoveAll(testDir) 96 os.RemoveAll(testDir) 97 bp, err := testOpenBitpage(true) 98 require.NoError(t, err) 99 pn, err1 := bp.NewPage() 100 require.NoError(t, err1) 101 p := bp.GetPage(pn) 102 paths := p.getFilesPath() 103 testCloseBitpage(t, bp) 104 105 bp, err = testOpenBitpage(true) 106 require.NoError(t, err) 107 for i := range paths { 108 require.Equal(t, true, utils.IsFileExist(paths[i])) 109 } 110 testCloseBitpage(t, bp) 111 } 112 113 func TestBitpage_Writer(t *testing.T) { 114 defer os.RemoveAll(testDir) 115 os.RemoveAll(testDir) 116 117 bp, err := testOpenBitpage(true) 118 require.NoError(t, err) 119 120 pn, err1 := bp.NewPage() 121 require.NoError(t, err1) 122 123 count := 1000 124 seqNum := uint64(1) 125 kvList := testMakeSortedKV(count, seqNum, 10) 126 seqNum += uint64(count) 127 128 wr := bp.GetPageWriter(pn, nil) 129 writeKV := func(pos int) { 130 require.NoError(t, wr.Set(*kvList[pos].Key, kvList[pos].Value)) 131 } 132 133 for i := 0; i < count; i++ { 134 if i >= 10 && i < 20 { 135 kvList[i].Key.SetKind(internalKeyKindDelete) 136 } 137 writeKV(i) 138 } 139 require.NoError(t, wr.FlushFinish()) 140 141 p := bp.GetPage(pn) 142 for i := 0; i < count; i++ { 143 uk := kvList[i].Key.UserKey 144 v, vexist, vcloser, kind := p.get(uk, hash.Crc32(uk)) 145 if i >= 10 && i < 20 { 146 require.Equal(t, false, vexist) 147 require.Equal(t, internalKeyKindDelete, kind) 148 } else { 149 require.Equal(t, kvList[i].Value, v) 150 require.Equal(t, internalKeyKindSet, kind) 151 } 152 if vcloser != nil { 153 vcloser() 154 } 155 } 156 157 for i := 10; i < 20; i++ { 158 kvList[i].Key.SetKind(internalKeyKindSet) 159 kvList[i].Key.SetSeqNum(seqNum) 160 seqNum++ 161 writeKV(i) 162 } 163 require.NoError(t, wr.FlushFinish()) 164 165 for i := 0; i < count; i++ { 166 uk := kvList[i].Key.UserKey 167 v, vexist, vcloser, kind := p.get(uk, hash.Crc32(uk)) 168 require.Equal(t, true, vexist) 169 require.Equal(t, kvList[i].Value, v) 170 require.Equal(t, internalKeyKindSet, kind) 171 vcloser() 172 } 173 174 testCloseBitpage(t, bp) 175 } 176 177 func TestBitpage_StMmapExpand(t *testing.T) { 178 defer os.RemoveAll(testDir) 179 os.RemoveAll(testDir) 180 181 bp, err := testOpenBitpage(true) 182 require.NoError(t, err) 183 pn, err1 := bp.NewPage() 184 require.NoError(t, err1) 185 186 count := 10000 187 seqNum := uint64(1) 188 kvList := testMakeSortedKV(count, seqNum, 10) 189 seqNum += uint64(count) 190 wr := bp.GetPageWriter(pn, nil) 191 for i := 0; i < count; i++ { 192 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 193 } 194 require.NoError(t, wr.FlushFinish()) 195 196 p := bp.GetPage(pn) 197 wg := sync.WaitGroup{} 198 closeCh := make(chan struct{}) 199 wg.Add(100) 200 for i := 0; i < 100; i++ { 201 if i%2 == 0 { 202 go func() { 203 defer wg.Done() 204 for { 205 select { 206 case <-closeCh: 207 return 208 default: 209 ri := rand.Intn(count) 210 uk := kvList[ri].Key.UserKey 211 v, vexist, vcloser, kind := p.get(uk, hash.Crc32(uk)) 212 require.Equal(t, internalKeyKindSet, kind) 213 require.Equal(t, true, vexist) 214 require.Equal(t, kvList[ri].Value, v) 215 vcloser() 216 } 217 } 218 }() 219 } else { 220 go func() { 221 defer wg.Done() 222 for { 223 select { 224 case <-closeCh: 225 return 226 default: 227 iter := p.newIter(nil) 228 pos := rand.Intn(count - 20) 229 uk := kvList[pos].Key.UserKey 230 j := 0 231 for ik, iv := iter.SeekGE(uk); ik != nil; ik, iv = iter.Next() { 232 require.Equal(t, kvList[pos].Key, ik) 233 require.Equal(t, kvList[pos].Value, iv) 234 if j == 10 { 235 break 236 } 237 j++ 238 pos++ 239 } 240 require.NoError(t, iter.Close()) 241 } 242 } 243 }() 244 } 245 246 } 247 248 time.Sleep(2 * time.Second) 249 wr = bp.GetPageWriter(pn, nil) 250 kvList1 := sortedkv.MakeSortedKVList(count, count+10, seqNum, 10) 251 for i := 0; i < 10; i++ { 252 require.NoError(t, wr.Set(*kvList1[i].Key, kvList1[i].Value)) 253 } 254 255 wr.p.mu.stMutable.grow(consts.BitpageInitMmapSize + 1) 256 require.NoError(t, wr.FlushFinish()) 257 require.Equal(t, consts.BitpageInitMmapSize*2, wr.p.mu.stMutable.tbl.Capacity()) 258 259 close(closeCh) 260 wg.Wait() 261 262 testCloseBitpage(t, bp) 263 } 264 265 func TestBitpage_OpenPages(t *testing.T) { 266 defer os.RemoveAll(testDir) 267 os.RemoveAll(testDir) 268 269 var pageNums []PageNum 270 count := 1000 271 pagesCnt := 10 272 stCnt := 5 273 seqNum := uint64(1) 274 num := count * stCnt 275 kvList := testMakeSortedKV(num, seqNum, 10) 276 seqNum += uint64(num) 277 278 writePage := func(b *Bitpage) { 279 for i := 0; i < pagesCnt; i++ { 280 pn, err1 := b.NewPage() 281 require.NoError(t, err1) 282 pageNums = append(pageNums, pn) 283 wr := b.GetPageWriter(pn, nil) 284 for j := 0; j < stCnt; j++ { 285 start := j * count 286 end := start + count 287 for index := start; index < end; index++ { 288 require.NoError(t, wr.Set(*kvList[index].Key, kvList[index].Value)) 289 } 290 wr.FlushFinish() 291 require.NoError(t, wr.p.makeMutableForWrite(false)) 292 } 293 } 294 } 295 296 readPage := func(b *Bitpage, pn PageNum) { 297 p := b.GetPage(pn) 298 for i := 0; i < num; i++ { 299 key := kvList[i].Key.UserKey 300 v, vexist, vcloser, kind := p.get(key, hash.Crc32(key)) 301 require.Equal(t, true, vexist) 302 require.Equal(t, kvList[i].Value, v) 303 require.Equal(t, internalKeyKindSet, kind) 304 vcloser() 305 } 306 } 307 308 bp, err := testOpenBitpage(true) 309 require.NoError(t, err) 310 writePage(bp) 311 testCloseBitpage(t, bp) 312 313 bp1, err1 := testOpenBitpage(true) 314 require.NoError(t, err1) 315 for _, pn := range pageNums { 316 readPage(bp1, pn) 317 } 318 writePage(bp1) 319 testCloseBitpage(t, bp1) 320 321 bp2, err2 := testOpenBitpage(true) 322 require.NoError(t, err2) 323 for _, pn := range pageNums { 324 readPage(bp2, pn) 325 } 326 testCloseBitpage(t, bp2) 327 } 328 329 func TestBitpage_Iter_SameKey(t *testing.T) { 330 defer os.RemoveAll(testDir) 331 os.RemoveAll(testDir) 332 333 bp, err := testOpenBitpage(true) 334 require.NoError(t, err) 335 pn, err1 := bp.NewPage() 336 require.NoError(t, err1) 337 338 wr := bp.GetPageWriter(pn, nil) 339 seqNum := uint64(1) 340 count := 100 341 kvList := testMakeSortedKV(count, seqNum, 10) 342 seqNum += uint64(count) 343 344 for j := 0; j < 100; j++ { 345 for i := 0; i < count; i++ { 346 kvList[i].Key.SetSeqNum(seqNum) 347 seqNum++ 348 kvList[i].Value = utils.FuncRandBytes(10) 349 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 350 } 351 require.NoError(t, wr.FlushFinish()) 352 } 353 354 checkKV := func(i int, ikey *internalKey, ival []byte) { 355 require.Equal(t, kvList[i].Key.UserKey, ikey.UserKey) 356 require.Equal(t, kvList[i].Value, ival) 357 require.Equal(t, internalKeyKindSet, ikey.Kind()) 358 } 359 360 rangeFunc := func(p *page) { 361 iter := p.newIter(nil) 362 i := 0 363 for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() { 364 checkKV(i, ik, iv) 365 i++ 366 } 367 require.NoError(t, iter.Close()) 368 369 iter = p.newIter(nil) 370 i = len(kvList) - 1 371 for ik, iv := iter.Last(); ik != nil; ik, iv = iter.Prev() { 372 checkKV(i, ik, iv) 373 i-- 374 } 375 require.NoError(t, iter.Close()) 376 } 377 378 seekFunc := func(p *page) { 379 iter := p.newIter(nil) 380 for i := 0; i < count; i++ { 381 ik, iv := iter.SeekGE(kvList[i].Key.UserKey) 382 checkKV(i, ik, iv) 383 } 384 require.NoError(t, iter.Close()) 385 } 386 387 pg := bp.GetPage(pn) 388 rangeFunc(pg) 389 seekFunc(pg) 390 testCloseBitpage(t, bp) 391 392 bp2, err2 := testOpenBitpage(true) 393 require.NoError(t, err2) 394 pg2 := bp2.GetPage(pn) 395 rangeFunc(pg2) 396 seekFunc(pg2) 397 testCloseBitpage(t, bp2) 398 } 399 400 func TestBitpage_Iter_StGet(t *testing.T) { 401 defer os.RemoveAll(testDir) 402 os.RemoveAll(testDir) 403 404 bp, err := testOpenBitpage(true) 405 require.NoError(t, err) 406 pn, err1 := bp.NewPage() 407 require.NoError(t, err1) 408 wr := bp.GetPageWriter(pn, nil) 409 410 seqNum := uint64(1) 411 count := 100 412 kvList := testMakeSortedKV(count, seqNum, 10) 413 seqNum += uint64(count) 414 key := kvList[0].Key.UserKey 415 for i := 0; i < count; i++ { 416 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 417 } 418 require.NoError(t, wr.FlushFinish()) 419 420 seekFunc := func(p *page) { 421 iter := p.newIter(nil) 422 ik, iv := iter.SeekGE(key) 423 require.Equal(t, kvList[0].Key, ik) 424 require.Equal(t, kvList[0].Value, iv) 425 ik, iv = iter.SeekLT(key) 426 require.Equal(t, nilInternalKey, ik) 427 require.NoError(t, iter.Close()) 428 } 429 430 pg := bp.GetPage(pn) 431 seekFunc(pg) 432 testCloseBitpage(t, bp) 433 434 bp2, err2 := testOpenBitpage(true) 435 require.NoError(t, err2) 436 pg2 := bp2.GetPage(pn) 437 seekFunc(pg2) 438 testCloseBitpage(t, bp2) 439 } 440 441 func testcase(caseFunc func(int, []bool)) { 442 for i, params := range testParams { 443 fmt.Printf("testcase params:%v\n", params) 444 caseFunc(i, params) 445 } 446 } 447 448 func TestBitpageWriterDelete(t *testing.T) { 449 testcase(func(index int, params []bool) { 450 dir := testDir 451 defer os.RemoveAll(dir) 452 os.RemoveAll(dir) 453 bp, err := testOpenBitpage2(dir, params[0], params[1], params[2]) 454 require.NoError(t, err) 455 count := 1000 456 seqNum := uint64(1) 457 kvList := testMakeSortedKV(count, seqNum, 10) 458 seqNum += uint64(count) 459 pn, err1 := bp.NewPage() 460 require.NoError(t, err1) 461 wr := bp.GetPageWriter(pn, nil) 462 writeKV := func(pos int) { 463 require.NoError(t, wr.Set(*kvList[pos].Key, kvList[pos].Value)) 464 } 465 466 for i := 0; i < count; i++ { 467 writeKV(i) 468 } 469 require.NoError(t, wr.FlushFinish()) 470 471 p := bp.GetPage(pn) 472 for i := 0; i < count; i++ { 473 key := kvList[i].Key.UserKey 474 v, vexist, vcloser, kind := p.get(key, hash.Crc32(key)) 475 require.Equal(t, true, vexist) 476 require.Equal(t, kvList[i].Value, v) 477 require.Equal(t, internalKeyKindSet, kind) 478 vcloser() 479 } 480 481 require.NoError(t, p.flush(nil, "")) 482 483 for i := 10; i < 20; i++ { 484 kvList[i].Key.SetKind(internalKeyKindDelete) 485 kvList[i].Key.SetSeqNum(seqNum) 486 seqNum++ 487 writeKV(i) 488 } 489 require.NoError(t, wr.FlushFinish()) 490 491 for i := 0; i < count; i++ { 492 key := kvList[i].Key.UserKey 493 v, vexist, vcloser, kind := p.get(key, hash.Crc32(key)) 494 if i >= 10 && i < 20 { 495 require.Equal(t, true, vcloser == nil) 496 require.Equal(t, false, vexist) 497 require.Equal(t, internalKeyKindDelete, kind) 498 } else { 499 require.Equal(t, true, vexist) 500 require.Equal(t, kvList[i].Value, v) 501 require.Equal(t, internalKeyKindSet, kind) 502 vcloser() 503 } 504 } 505 506 testCloseBitpage(t, bp) 507 }) 508 } 509 510 func TestBitpageIter(t *testing.T) { 511 testcase(func(index int, params []bool) { 512 dir := testDir 513 defer os.RemoveAll(dir) 514 os.RemoveAll(dir) 515 bp, err := testOpenBitpage2(dir, params[0], params[1], params[2]) 516 require.NoError(t, err) 517 pn, err1 := bp.NewPage() 518 require.NoError(t, err1) 519 wr := bp.GetPageWriter(pn, nil) 520 seqNum := uint64(1) 521 count := 100 522 kvList := testMakeSortedKV(count, seqNum, 10) 523 seqNum += uint64(count) 524 525 for i := 0; i < count; i++ { 526 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 527 } 528 require.NoError(t, wr.FlushFinish()) 529 530 pg := bp.GetPage(pn) 531 require.NoError(t, pg.flush(nil, "")) 532 for i := 20; i < 30; i++ { 533 kvList[i].Key.SetKind(internalKeyKindDelete) 534 kvList[i].Key.SetSeqNum(seqNum) 535 kvList[i].Value = nil 536 seqNum++ 537 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 538 } 539 require.NoError(t, wr.FlushFinish()) 540 541 for i := 80; i < count; i++ { 542 kvList[i].Key.SetSeqNum(seqNum) 543 kvList[i].Value = utils.FuncRandBytes(10) 544 seqNum++ 545 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 546 } 547 require.NoError(t, wr.FlushFinish()) 548 549 checkKV := func(i int, ikey *internalKey, ival []byte) { 550 if i < 0 { 551 require.Equal(t, nilInternalKey, ikey) 552 require.Equal(t, 0, len(ival)) 553 } else { 554 require.Equal(t, kvList[i].Key.UserKey, ikey.UserKey) 555 if i >= 20 && i < 30 { 556 require.Equal(t, 0, len(ival)) 557 require.Equal(t, internalKeyKindDelete, ikey.Kind()) 558 } else { 559 require.Equal(t, kvList[i].Value, ival) 560 require.Equal(t, internalKeyKindSet, ikey.Kind()) 561 } 562 } 563 } 564 565 rangeFunc := func(p *page) { 566 iter := p.newIter(nil) 567 setCnt := 0 568 delCnt := 0 569 index := 0 570 for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() { 571 checkKV(index, ik, iv) 572 if ik.Kind() == internalKeyKindSet { 573 setCnt++ 574 } else if ik.Kind() == internalKeyKindDelete { 575 delCnt++ 576 } 577 index++ 578 } 579 require.Equal(t, count-10, setCnt) 580 require.Equal(t, 10, delCnt) 581 582 setCnt = 0 583 delCnt = 0 584 index = 99 585 for ik, iv := iter.Last(); ik != nil; ik, iv = iter.Prev() { 586 checkKV(index, ik, iv) 587 if ik.Kind() == internalKeyKindSet { 588 setCnt++ 589 } else if ik.Kind() == internalKeyKindDelete { 590 delCnt++ 591 } 592 index-- 593 } 594 require.Equal(t, count-10, setCnt) 595 require.Equal(t, 10, delCnt) 596 require.NoError(t, iter.Close()) 597 } 598 599 seekFunc := func(p *page) { 600 iter := p.newIter(nil) 601 for i := 0; i < count; i++ { 602 key := kvList[i].Key.UserKey 603 ik, iv := iter.SeekGE(key) 604 checkKV(i, ik, iv) 605 } 606 require.NoError(t, iter.Close()) 607 } 608 609 seekFunc1 := func(p *page) { 610 iter := p.newIter(nil) 611 612 ik, iv := iter.Prev() 613 checkKV(99, ik, iv) 614 615 ik, iv = iter.First() 616 checkKV(0, ik, iv) 617 ik, iv = iter.Next() 618 checkKV(1, ik, iv) 619 ik, iv = iter.Prev() 620 checkKV(0, ik, iv) 621 ik, iv = iter.Last() 622 checkKV(99, ik, iv) 623 ik, iv = iter.Prev() 624 checkKV(98, ik, iv) 625 626 ik, iv = iter.SeekGE(kvList[15].Key.UserKey) 627 checkKV(15, ik, iv) 628 ik, iv = iter.SeekGE(kvList[99].Key.UserKey) 629 checkKV(99, ik, iv) 630 631 ik, iv = iter.SeekGE(sortedkv.MakeSortedKey(990)) 632 checkKV(-1, ik, iv) 633 ik, iv = iter.SeekGE(sortedkv.MakeSortedKey(-1)) 634 checkKV(0, ik, iv) 635 636 ik, iv = iter.SeekLT(kvList[35].Key.UserKey) 637 checkKV(34, ik, iv) 638 ik, iv = iter.Prev() 639 checkKV(33, ik, iv) 640 641 ik, iv = iter.SeekGE(kvList[20].Key.UserKey) 642 checkKV(20, ik, iv) 643 ik, iv = iter.SeekGE(kvList[29].Key.UserKey) 644 checkKV(29, ik, iv) 645 ik, iv = iter.Next() 646 checkKV(30, ik, iv) 647 648 ik, iv = iter.SeekLT(kvList[30].Key.UserKey) 649 checkKV(29, ik, iv) 650 ik, iv = iter.Prev() 651 checkKV(28, ik, iv) 652 653 ik, iv = iter.SeekLT(kvList[21].Key.UserKey) 654 checkKV(20, ik, iv) 655 ik, iv = iter.SeekLT(kvList[20].Key.UserKey) 656 checkKV(19, ik, iv) 657 ik, iv = iter.Prev() 658 checkKV(18, ik, iv) 659 660 ik, iv = iter.SeekLT(sortedkv.MakeSortedKey(990)) 661 checkKV(99, ik, iv) 662 ik, iv = iter.SeekLT(sortedkv.MakeSortedKey(-1)) 663 checkKV(-1, ik, iv) 664 665 require.NoError(t, iter.Close()) 666 } 667 668 rangeFunc(pg) 669 seekFunc(pg) 670 seekFunc1(pg) 671 testCloseBitpage(t, bp) 672 673 bp2, err2 := testOpenBitpage2(dir, params[0], params[1], params[2]) 674 require.NoError(t, err2) 675 pg2 := bp2.GetPage(pn) 676 rangeFunc(pg2) 677 seekFunc(pg2) 678 seekFunc1(pg2) 679 testCloseBitpage(t, bp2) 680 }) 681 } 682 683 func TestBitpageIterRange(t *testing.T) { 684 testcase(func(index int, params []bool) { 685 dir := testDir 686 defer os.RemoveAll(dir) 687 os.RemoveAll(dir) 688 bp, err := testOpenBitpage2(dir, params[0], params[1], params[2]) 689 require.NoError(t, err) 690 pn, err1 := bp.NewPage() 691 require.NoError(t, err1) 692 wr := bp.GetPageWriter(pn, nil) 693 seqNum := uint64(1) 694 count := 10000 695 kvList := testMakeSortedKV(count+1, seqNum, 100) 696 seqNum += uint64(count) 697 698 rangeIter := func(p *page) { 699 iter := p.newIter(nil) 700 i := 0 701 for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() { 702 require.Equal(t, kvList[i].Key.UserKey, ik.UserKey) 703 require.Equal(t, kvList[i].Value, iv) 704 i++ 705 } 706 require.Equal(t, i, count) 707 require.NoError(t, iter.Close()) 708 709 iter = p.newIter(nil) 710 for i = 0; i < count; i++ { 711 ik, iv := iter.SeekGE(kvList[i].Key.UserKey) 712 require.Equal(t, kvList[i].Key.UserKey, ik.UserKey) 713 require.Equal(t, kvList[i].Value, iv) 714 } 715 require.NoError(t, iter.Close()) 716 } 717 718 rangeReverseIter := func(p *page) { 719 iter := p.newIter(nil) 720 i := count - 1 721 for ik, iv := iter.Last(); ik != nil; ik, iv = iter.Prev() { 722 require.Equal(t, kvList[i].Key.UserKey, ik.UserKey) 723 require.Equal(t, kvList[i].Value, iv) 724 i-- 725 } 726 require.Equal(t, -1, i) 727 require.NoError(t, iter.Close()) 728 729 iter = p.newIter(nil) 730 for i = count; i >= 0; i-- { 731 ik, iv := iter.SeekLT(kvList[i].Key.UserKey) 732 if i == 0 { 733 require.Equal(t, nilInternalKey, ik) 734 require.Equal(t, []byte(nil), iv) 735 } else { 736 require.Equal(t, kvList[i-1].Key.UserKey, ik.UserKey) 737 require.Equal(t, kvList[i-1].Value, iv) 738 } 739 } 740 require.NoError(t, iter.Close()) 741 } 742 743 for i := 0; i < count; i++ { 744 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 745 } 746 require.NoError(t, wr.FlushFinish()) 747 748 pg := bp.GetPage(pn) 749 rangeIter(pg) 750 rangeReverseIter(pg) 751 require.NoError(t, pg.flush(nil, "")) 752 rangeIter(pg) 753 rangeReverseIter(pg) 754 testCloseBitpage(t, bp) 755 756 bp2, err2 := testOpenBitpage2(dir, params[0], params[1], params[2]) 757 require.NoError(t, err2) 758 pg2 := bp2.GetPage(pn) 759 rangeIter(pg2) 760 rangeReverseIter(pg2) 761 testCloseBitpage(t, bp2) 762 }) 763 } 764 765 func TestBitpageCheckpoint(t *testing.T) { 766 testcase(func(index int, params []bool) { 767 defer os.RemoveAll(testDir) 768 os.RemoveAll(testDir) 769 openBitpage := func(dir string) *Bitpage { 770 b, err := testOpenBitpage2(dir, params[0], params[1], params[2]) 771 require.NoError(t, err) 772 return b 773 } 774 bp := openBitpage(testDir) 775 pn, err := bp.NewPage() 776 require.NoError(t, err) 777 pg := bp.GetPage(pn) 778 dstDir := fmt.Sprintf("%s_ck", testDir) 779 os.RemoveAll(dstDir) 780 defer os.RemoveAll(dstDir) 781 require.NoError(t, bp.Checkpoint(bp.opts.FS, dstDir)) 782 bp1 := openBitpage(dstDir) 783 pg1 := bp1.GetPage(pn) 784 require.Equal(t, 1, len(pg.mu.stQueue)) 785 require.Equal(t, 1, len(pg1.mu.stQueue)) 786 require.Equal(t, true, pg.mu.arrtable == nil) 787 require.Equal(t, true, pg1.mu.arrtable == nil) 788 require.NoError(t, bp1.Close()) 789 require.NoError(t, os.RemoveAll(dstDir)) 790 791 wr := bp.GetPageWriter(pn, nil) 792 seqNum := uint64(1) 793 count := 2000 794 kvList := testMakeSortedKV(count, seqNum, 10) 795 seqNum += uint64(count) 796 797 for i := 0; i < 1000; i++ { 798 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 799 } 800 require.NoError(t, wr.FlushFinish()) 801 require.NoError(t, pg.flush(nil, "")) 802 for i := 1000; i < 2000; i++ { 803 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 804 } 805 require.NoError(t, wr.FlushFinish()) 806 807 for i := 0; i < 3; i++ { 808 fmt.Println("checkpoint", i) 809 dstDir = fmt.Sprintf("%s_ck_%d", testDir, i) 810 require.NoError(t, os.RemoveAll(dstDir)) 811 require.NoError(t, bp.Checkpoint(bp.opts.FS, dstDir)) 812 bp1 = openBitpage(dstDir) 813 pg1 = bp1.GetPage(pn) 814 require.Equal(t, 2, len(pg.mu.stQueue)) 815 require.Equal(t, 1, len(pg1.mu.stQueue)) 816 require.Equal(t, true, pg.mu.arrtable != nil) 817 require.Equal(t, true, pg1.mu.arrtable != nil) 818 for j := 0; j < 2000; j++ { 819 key := kvList[j].Key.UserKey 820 v, vexist, vcloser, kind := pg1.get(key, hash.Crc32(key)) 821 require.Equal(t, true, vexist) 822 require.Equal(t, kvList[j].Value, v) 823 require.Equal(t, internalKeyKindSet, kind) 824 vcloser() 825 v, vexist, vcloser, kind = pg.get(key, hash.Crc32(key)) 826 require.Equal(t, true, vexist) 827 require.Equal(t, kvList[j].Value, v) 828 require.Equal(t, internalKeyKindSet, kind) 829 vcloser() 830 } 831 testCloseBitpage(t, bp1) 832 require.NoError(t, os.RemoveAll(dstDir)) 833 } 834 835 testCloseBitpage(t, bp) 836 }) 837 } 838 839 func TestBitpageCheckpoint1(t *testing.T) { 840 testcase(func(index int, params []bool) { 841 defer os.RemoveAll(testDir) 842 os.RemoveAll(testDir) 843 openBitpage := func(dir string) *Bitpage { 844 b, err := testOpenBitpage2(dir, params[0], params[1], params[2]) 845 require.NoError(t, err) 846 return b 847 } 848 bp := openBitpage(testDir) 849 pn, err := bp.NewPage() 850 require.NoError(t, err) 851 wr := bp.GetPageWriter(pn, nil) 852 seqNum := uint64(1) 853 count := 20000 854 kvList := testMakeSortedKV(count, seqNum, 100) 855 seqNum += uint64(count) 856 857 for i := 0; i < count/2; i++ { 858 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 859 } 860 require.NoError(t, wr.FlushFinish()) 861 862 pg := bp.GetPage(pn) 863 require.NoError(t, pg.flush(nil, "")) 864 865 for i := count / 2; i < count; i++ { 866 require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value)) 867 } 868 require.NoError(t, wr.FlushFinish()) 869 870 sps, err2 := bp.PageSplitStart(pn, "test") 871 require.NoError(t, err2) 872 bp.PageSplitEnd(pn, sps, nil) 873 fmt.Println("page split ok") 874 875 dstDir := fmt.Sprintf("%s_ck", testDir) 876 os.RemoveAll(dstDir) 877 defer os.RemoveAll(dstDir) 878 require.NoError(t, bp.Checkpoint(bp.opts.FS, dstDir)) 879 require.Equal(t, consts.BitpageSplitNum+1, bp.GetPageCount()) 880 require.Equal(t, true, bp.PageSplitted2(pn)) 881 require.Equal(t, true, pg.mu.arrtable != nil) 882 bp1 := openBitpage(dstDir) 883 pg1 := bp1.GetPage(pn) 884 require.Equal(t, true, pg1 == nil) 885 for i := range sps { 886 spn := bp1.GetPage(sps[i].Pn) 887 require.Equal(t, true, spn != nil) 888 require.Equal(t, 1, len(spn.mu.stQueue)) 889 require.Equal(t, true, spn.mu.arrtable != nil) 890 } 891 892 for j := 0; j < count; j++ { 893 key := kvList[j].Key.UserKey 894 v, vexist, vcloser, kind := pg.get(key, hash.Crc32(key)) 895 require.Equal(t, true, vexist) 896 require.Equal(t, kvList[j].Value, v) 897 require.Equal(t, internalKeyKindSet, kind) 898 vcloser() 899 900 find := false 901 for i := range sps { 902 if bytes.Compare(key, sps[i].Sentinel) <= 0 { 903 v, vexist, vcloser, kind = bp1.Get(sps[i].Pn, key, hash.Crc32(key)) 904 require.Equal(t, true, vexist) 905 require.Equal(t, kvList[j].Value, v) 906 require.Equal(t, internalKeyKindSet, kind) 907 vcloser() 908 find = true 909 break 910 } 911 } 912 require.Equal(t, true, find) 913 } 914 915 testCloseBitpage(t, bp) 916 }) 917 }