github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/array_table_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 "os" 21 "testing" 22 "time" 23 24 "github.com/cockroachdb/errors" 25 "github.com/stretchr/testify/require" 26 "github.com/zuoyebang/bitalosdb/internal/bindex" 27 "github.com/zuoyebang/bitalosdb/internal/cache/lrucache" 28 "github.com/zuoyebang/bitalosdb/internal/consts" 29 "github.com/zuoyebang/bitalosdb/internal/hash" 30 "github.com/zuoyebang/bitalosdb/internal/options" 31 "github.com/zuoyebang/bitalosdb/internal/sortedkv" 32 ) 33 34 func testNewBlockCache() *lrucache.LruCache { 35 cacheOpts := &options.CacheOptions{ 36 Size: consts.BitpageDefaultBlockCacheSize, 37 Shards: consts.BitpageBlockCacheShards, 38 HashSize: consts.BitpageBlockCacheHashSize, 39 } 40 cache := lrucache.NewLrucache(cacheOpts) 41 42 return cache 43 } 44 45 func testNewArrayTable(dir string, params []bool) (*arrayTable, *atOptions) { 46 atCacheOpts := &atCacheOptions{ 47 cache: testNewBlockCache(), 48 id: 1 << 10, 49 } 50 opts := &atOptions{ 51 useMapIndex: params[0], 52 usePrefixCompress: params[1], 53 useBlockCompress: params[2], 54 } 55 at, err := newArrayTable(dir, opts, atCacheOpts) 56 if err != nil { 57 panic(err) 58 } 59 return at, opts 60 } 61 62 func testOpenArrayTable(dir string) *arrayTable { 63 atCacheOpts := &atCacheOptions{ 64 cache: testNewBlockCache(), 65 id: 1 << 10, 66 } 67 at, err := openArrayTable(dir, atCacheOpts) 68 if err != nil { 69 panic(err) 70 } 71 return at 72 } 73 74 func TestArrayTable_Stmap(t *testing.T) { 75 os.Remove(testPath) 76 count := 100 77 var keys [][]byte 78 for i := 0; i < count; i++ { 79 keys = append(keys, []byte(fmt.Sprintf("test_at_key_%d", i))) 80 } 81 82 hindex := bindex.NewHashIndex(true) 83 hindex.InitWriter() 84 for i := range keys { 85 key := keys[i] 86 khash := hash.Crc32(key) 87 hindex.Add(khash, uint32(i+1)) 88 } 89 90 tbl := testNewTable() 91 defer func() { 92 require.NoError(t, testCloseTable(tbl)) 93 }() 94 95 fmt.Println("stmap.Size()", hindex.Size()) 96 mapOffset, err := tbl.alloc(hindex.Size()) 97 if err != nil { 98 t.Fatal(err) 99 } 100 101 hindex.SetWriter(tbl.data[mapOffset:]) 102 if !hindex.Serialize() { 103 t.Fatal(errors.New("hash_index Serialize Fail")) 104 } 105 106 hindex.Finish() 107 108 for i := range keys { 109 key := keys[i] 110 khash := hash.Crc32(key) 111 v, ok := hindex.Get32(khash) 112 if ok != true || v != uint32(i+1) { 113 t.Fatalf("Get---key:%s, ok:%#v, expact-val:%d, real-val:%d\n", string(key), ok, uint32(i+1), v) 114 } 115 } 116 } 117 118 func TestArrayTable_WriteRead(t *testing.T) { 119 testcase(func(index int, params []bool) { 120 dir := testPath 121 defer os.RemoveAll(dir) 122 os.RemoveAll(dir) 123 124 count := 10000 125 kvList := testMakeSortedKV(count, uint64(1), 100) 126 127 at, atOpts := testNewArrayTable(dir, params) 128 atVersion := getAtVersionByOpts(atOpts) 129 require.Equal(t, atVersion, at.header.version) 130 131 for i := 0; i < count; i++ { 132 _, err := at.writeItem(kvList[i].Key.UserKey, kvList[i].Value) 133 require.NoError(t, err) 134 } 135 require.NoError(t, at.writeFinish()) 136 require.Equal(t, at.tbl.fileStatSize(), int64(at.size)) 137 fmt.Println(index, atVersion, at.size) 138 139 seekFunc := func(a *arrayTable) { 140 iter := a.newIter(nil) 141 i := 0 142 for key, val := iter.First(); key != nil; key, val = iter.Next() { 143 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 144 require.Equal(t, kvList[i].Value, val) 145 i++ 146 } 147 require.NoError(t, iter.Close()) 148 require.Equal(t, count, i) 149 150 for j := 0; j < count; j++ { 151 skey := kvList[j].Key.UserKey 152 val, exist, _, closer := a.get(skey, hash.Crc32(skey)) 153 require.Equal(t, true, exist) 154 require.Equal(t, kvList[j].Value, val) 155 if closer != nil { 156 closer() 157 } 158 159 it1 := a.newIter(nil) 160 ik, v := it1.SeekGE(skey) 161 require.Equal(t, skey, ik.UserKey) 162 require.Equal(t, kvList[j].Value, v) 163 require.NoError(t, it1.Close()) 164 } 165 166 for _, n := range []int{99999, 90001} { 167 skey := sortedkv.MakeSortedKey(n) 168 _, exist, _, closer := a.get(skey, hash.Crc32(skey)) 169 require.Equal(t, false, exist) 170 if closer != nil { 171 closer() 172 } 173 } 174 } 175 176 seekFunc(at) 177 require.NoError(t, at.close()) 178 179 at1 := testOpenArrayTable(dir) 180 require.Equal(t, atVersion, at1.header.version) 181 seekFunc(at1) 182 require.NoError(t, at1.close()) 183 }) 184 } 185 186 func TestArrayTable_IterCompact(t *testing.T) { 187 for _, params := range [][]bool{ 188 {true, true, true}, 189 {true, false, true}, 190 } { 191 func(param []bool) { 192 dir := testPath 193 defer os.RemoveAll(dir) 194 os.RemoveAll(dir) 195 196 count := 10000 197 kvList := testMakeSortedKV(count, uint64(1), 10) 198 199 at, atOpts := testNewArrayTable(dir, param) 200 atVersion := getAtVersionByOpts(atOpts) 201 require.Equal(t, atVersion, at.header.version) 202 203 for i := 0; i < count; i++ { 204 _, err := at.writeItem(kvList[i].Key.UserKey, kvList[i].Value) 205 require.NoError(t, err) 206 } 207 require.NoError(t, at.writeFinish()) 208 209 require.Equal(t, at.tbl.fileStatSize(), int64(at.size)) 210 require.Equal(t, int64(0), at.blockCache.Size()) 211 212 seekFunc := func(a *arrayTable, opts *iterOptions) { 213 iter := a.newIter(opts) 214 i := 0 215 for key, val := iter.First(); key != nil; key, val = iter.Next() { 216 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 217 require.Equal(t, kvList[i].Value, val) 218 i++ 219 } 220 require.NoError(t, iter.Close()) 221 require.Equal(t, count, i) 222 223 for j := 0; j < count; j++ { 224 skey := kvList[j].Key.UserKey 225 it1 := a.newIter(opts) 226 ik, v := it1.SeekGE(skey) 227 require.Equal(t, skey, ik.UserKey) 228 require.Equal(t, kvList[j].Value, v) 229 require.NoError(t, it1.Close()) 230 } 231 232 for _, n := range []int{99999, 90001} { 233 skey := sortedkv.MakeSortedKey(n) 234 _, exist, _, closer := a.get(skey, hash.Crc32(skey)) 235 require.Equal(t, false, exist) 236 require.Equal(t, true, closer == nil) 237 } 238 } 239 240 seekFunc(at, &iterCompactOpts) 241 require.Equal(t, int64(1), at.blockCache.Metrics().Count) 242 seekFunc(at, nil) 243 require.Equal(t, int64(250), at.blockCache.Metrics().Count) 244 require.NoError(t, at.close()) 245 }(params) 246 } 247 } 248 249 func TestArrayTable_IterSeek(t *testing.T) { 250 testcase(func(index int, params []bool) { 251 dir := testPath 252 defer os.RemoveAll(dir) 253 os.RemoveAll(dir) 254 255 at, atOpts := testNewArrayTable(dir, params) 256 atVersion := getAtVersionByOpts(atOpts) 257 count := 120 258 kvList := testMakeSortedKV(count, uint64(1), 200) 259 260 for i := 0; i < 100; i++ { 261 _, err := at.writeItem(kvList[i].Key.UserKey, kvList[i].Value) 262 require.NoError(t, err) 263 } 264 require.NoError(t, at.writeFinish()) 265 266 checkKV := func(i int, ik *internalKey, iv []byte) { 267 if i == -1 { 268 require.Equal(t, nilInternalKey, ik) 269 } else { 270 require.Equal(t, kvList[i].Key.UserKey, ik.UserKey) 271 require.Equal(t, kvList[i].Value, iv) 272 } 273 } 274 275 seekFunc := func(a *arrayTable) { 276 iter := a.newIter(nil) 277 ik, iv := iter.First() 278 checkKV(0, ik, iv) 279 280 ik, iv = iter.Next() 281 checkKV(1, ik, iv) 282 283 ik, iv = iter.Prev() 284 checkKV(0, ik, iv) 285 286 ik, iv = iter.Last() 287 checkKV(99, ik, iv) 288 289 ik, iv = iter.SeekGE(kvList[15].Key.UserKey) 290 checkKV(15, ik, iv) 291 ik, iv = iter.SeekGE(kvList[51].Key.UserKey) 292 checkKV(51, ik, iv) 293 ik, iv = iter.SeekGE(sortedkv.MakeSortedKey(-1)) 294 checkKV(0, ik, iv) 295 ik, iv = iter.SeekGE(kvList[110].Key.UserKey) 296 checkKV(-1, ik, iv) 297 298 ik, iv = iter.SeekLT(kvList[15].Key.UserKey) 299 checkKV(14, ik, iv) 300 ik, iv = iter.SeekLT(kvList[51].Key.UserKey) 301 checkKV(50, ik, iv) 302 ik, iv = iter.Prev() 303 checkKV(49, ik, iv) 304 ik, iv = iter.SeekLT(kvList[1].Key.UserKey) 305 checkKV(0, ik, iv) 306 ik, iv = iter.SeekLT(kvList[110].Key.UserKey) 307 checkKV(99, ik, iv) 308 ik, iv = iter.SeekLT(kvList[0].Key.UserKey) 309 checkKV(-1, ik, iv) 310 ik, iv = iter.SeekLT(sortedkv.MakeSortedKey(-1)) 311 checkKV(-1, ik, iv) 312 313 require.NoError(t, iter.Close()) 314 } 315 316 seekFunc(at) 317 require.NoError(t, at.close()) 318 319 at1 := testOpenArrayTable(dir) 320 require.Equal(t, atVersion, at1.header.version) 321 seekFunc(at1) 322 require.NoError(t, at1.close()) 323 }) 324 } 325 326 func TestArrayTable_IterRange(t *testing.T) { 327 testcase(func(index int, params []bool) { 328 dir := testPath 329 defer os.RemoveAll(dir) 330 os.RemoveAll(dir) 331 332 at, atOpts := testNewArrayTable(dir, params) 333 atVersion := getAtVersionByOpts(atOpts) 334 count := 10000 335 kvList := testMakeSortedKV(count+1, uint64(1), 100) 336 337 for i := 0; i < count; i++ { 338 _, err := at.writeItem(kvList[i].Key.UserKey, kvList[i].Value) 339 require.NoError(t, err) 340 } 341 require.NoError(t, at.writeFinish()) 342 343 rangeIter := func(a *arrayTable) { 344 iter := a.newIter(nil) 345 i := 0 346 for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() { 347 require.Equal(t, kvList[i].Key.UserKey, ik.UserKey) 348 require.Equal(t, kvList[i].Value, iv) 349 i++ 350 } 351 require.Equal(t, i, count) 352 require.NoError(t, iter.Close()) 353 354 iter = a.newIter(nil) 355 for i = 0; i < count; i++ { 356 ik, iv := iter.SeekGE(kvList[i].Key.UserKey) 357 require.Equal(t, kvList[i].Key.UserKey, ik.UserKey) 358 require.Equal(t, kvList[i].Value, iv) 359 } 360 require.NoError(t, iter.Close()) 361 } 362 363 rangeReverseIter := func(a *arrayTable) { 364 iter := a.newIter(nil) 365 i := count - 1 366 for ik, iv := iter.Last(); ik != nil; ik, iv = iter.Prev() { 367 require.Equal(t, kvList[i].Key.UserKey, ik.UserKey) 368 require.Equal(t, kvList[i].Value, iv) 369 i-- 370 } 371 require.Equal(t, -1, i) 372 require.NoError(t, iter.Close()) 373 374 iter = a.newIter(nil) 375 for i = count; i >= 0; i-- { 376 ik, iv := iter.SeekLT(kvList[i].Key.UserKey) 377 if i == 0 { 378 require.Equal(t, nilInternalKey, ik) 379 require.Equal(t, []byte(nil), iv) 380 } else { 381 require.Equal(t, kvList[i-1].Key.UserKey, ik.UserKey) 382 require.Equal(t, kvList[i-1].Value, iv) 383 } 384 } 385 require.NoError(t, iter.Close()) 386 } 387 388 rangeIter(at) 389 rangeReverseIter(at) 390 require.NoError(t, at.close()) 391 392 at1 := testOpenArrayTable(dir) 393 require.Equal(t, atVersion, at1.header.version) 394 rangeIter(at1) 395 rangeReverseIter(at1) 396 require.NoError(t, at1.close()) 397 }) 398 } 399 400 func TestArrayTable_Empty(t *testing.T) { 401 testcase(func(index int, params []bool) { 402 dir := testPath 403 defer os.RemoveAll(dir) 404 os.RemoveAll(dir) 405 406 at, _ := testNewArrayTable(dir, params) 407 require.Equal(t, true, at.empty()) 408 409 count := 1 410 kvList := testMakeSortedKV(count, uint64(1), 10) 411 for i := 0; i < count; i++ { 412 _, err := at.writeItem(kvList[i].Key.UserKey, kvList[i].Value) 413 require.NoError(t, err) 414 } 415 require.NoError(t, at.writeFinish()) 416 require.Equal(t, false, at.empty()) 417 require.NoError(t, at.close()) 418 }) 419 } 420 421 func Test_SharedPage_Perf(t *testing.T) { 422 os.Remove(testPath) 423 424 count := 1 << 20 425 kvList := testMakeSortedKV(count, uint64(1), 16) 426 427 bt := time.Now() 428 for _, useMapIndex := range []bool{false, true} { 429 fmt.Printf("Test_SharedPage_Perf, useMapIndex=%#v\n", useMapIndex) 430 atCacheOpts := atCacheOptions{ 431 cache: testNewBlockCache(), 432 id: 1 << 10, 433 } 434 opts := &atOptions{ 435 useMapIndex: useMapIndex, 436 usePrefixCompress: false, 437 } 438 at, err := newArrayTable(testPath, opts, &atCacheOpts) 439 require.NoError(t, err) 440 441 bt1 := time.Now() 442 for i := 0; i < count; i++ { 443 key := kvList[i].Key.UserKey 444 if _, err = at.writeItem(key, kvList[i].Value); err != nil { 445 t.Fatalf("add err key:%s err:%v", string(key), err) 446 } 447 } 448 require.NoError(t, at.writeFinish()) 449 require.Equal(t, uint32(count), at.header.num) 450 et1 := time.Since(bt1) 451 fmt.Printf("Test_SharedPage_Perf writeArrayTable time cost = %v\n", et1) 452 453 fmt.Printf("useMapIndex=%#v; at.size=%dKB; at.tbl.fileStatSize=%dKB\n", useMapIndex, at.size/1024, at.tbl.fileStatSize()/1024) 454 455 seekFunc := func(a *arrayTable) { 456 iter := a.newIter(nil) 457 i := 0 458 for key, val := iter.First(); key != nil; key, val = iter.Next() { 459 expKey := kvList[i].Key.UserKey 460 require.Equal(t, expKey, key.UserKey) 461 require.Equal(t, kvList[i].Value, val) 462 i++ 463 } 464 465 require.NoError(t, iter.Close()) 466 467 getFunc := func(skey []byte) { 468 _, exist, _, closer := a.get(skey, hash.Crc32(skey)) 469 require.Equal(t, true, exist) 470 if closer != nil { 471 closer() 472 } 473 } 474 475 seekFunc := func(skey []byte) { 476 it1 := a.newIter(nil) 477 ik, _ := it1.SeekGE(skey) 478 if ik == nil { 479 t.Fatal("SeekGE fail", string(skey)) 480 } 481 require.Equal(t, skey, ik.UserKey) 482 require.NoError(t, it1.Close()) 483 } 484 485 seekNotExist := func(skey []byte) { 486 _, exist, _, closer := a.get(skey, hash.Crc32(skey)) 487 require.Equal(t, false, exist) 488 if closer != nil { 489 closer() 490 } 491 } 492 493 bt1_1 := time.Now() 494 for j := 0; j < count; j++ { 495 getFunc(kvList[j].Key.UserKey) 496 } 497 et1_1 := time.Since(bt1_1) 498 fmt.Printf("Test_SharedPage_Perf GET time cost = %v\n", et1_1) 499 500 bt1_2 := time.Now() 501 for j := 0; j < count; j++ { 502 seekFunc(kvList[j].Key.UserKey) 503 } 504 et1_2 := time.Since(bt1_2) 505 fmt.Printf("Test_SharedPage_Perf SeekGE time cost = %v\n", et1_2) 506 507 for _, n := range []int{count + 7, count + 71, count + 711} { 508 seekNotExist(sortedkv.MakeSortedKey(n)) 509 } 510 } 511 512 bt2 := time.Now() 513 seekFunc(at) 514 et2 := time.Since(bt2) 515 fmt.Printf("Test_SharedPage_Perf seekArrayTable time cost = %v\n", et2) 516 517 require.NoError(t, at.close()) 518 519 at1, err1 := openArrayTable(testPath, &atCacheOpts) 520 require.NoError(t, err1) 521 522 bt3 := time.Now() 523 seekFunc(at1) 524 et3 := time.Since(bt3) 525 fmt.Printf("Test_SharedPage_Perf reopen&seekArrayTable time cost = %v\n", et3) 526 527 require.NoError(t, at1.close()) 528 529 os.Remove(testPath) 530 } 531 et := time.Since(bt) 532 fmt.Printf("Test_SharedPage_Perf time cost = %v\n", et) 533 } 534 535 const item_count = 1<<20 - 1 536 537 func Test_PageBlock_Perf(t *testing.T) { 538 defer os.Remove(testPath) 539 os.Remove(testPath) 540 541 count := item_count 542 seqNum := uint64(1) 543 kvList := testMakeSortedKVForBitrie(count, seqNum, 10) 544 seqNum += uint64(count) 545 546 bt := time.Now() 547 for _, opts := range [][]bool{ 548 {false, false, false}, 549 //{false, true, false}, 550 {true, false, false}, 551 //{true, true, false}, 552 } { 553 bt0 := time.Now() 554 fmt.Printf("Start Test_PageBlock_Perf, opts(usePrefixCompress, useBlockCompress)=%#v\n", opts) 555 556 atCacheOpts := &atCacheOptions{ 557 cache: testNewBlockCache(), 558 id: 1 << 10, 559 } 560 option := &atOptions{ 561 useMapIndex: false, 562 usePrefixCompress: opts[0], 563 useBlockCompress: opts[1], 564 blockSize: 32 << 10, 565 } 566 at, err := newArrayTable(testPath, option, atCacheOpts) 567 require.NoError(t, err) 568 569 bt1 := time.Now() 570 for i := 0; i < count; i++ { 571 _, err = at.writeItem(kvList[i].Key.UserKey, kvList[i].Value) 572 require.NoError(t, err) 573 } 574 require.NoError(t, at.writeFinish()) 575 et1 := time.Since(bt1) 576 fmt.Printf("Test_PageBlock_Perf writeArrayTable time cost = %v; header=%v\n", et1, at.header.version) 577 578 fmt.Printf("opts(usePrefixCompress, useBlockCompress)=%#v; at.size=%dKB; tbl.size=%dKB, at.tbl.fileStatSize=%dKB; totalNum=%d\n", opts, at.size/1024, at.tbl.Size()/1024, at.tbl.fileStatSize()/1024, at.num) 579 580 seekFunc := func(a *arrayTable) { 581 bt10_0 := time.Now() 582 iter := a.newIter(nil) 583 i := 0 584 for key, val := iter.First(); key != nil; key, val = iter.Next() { 585 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 586 require.Equal(t, kvList[i].Value, val) 587 i++ 588 } 589 require.Equal(t, count, i) 590 require.NoError(t, iter.Close()) 591 et10_0 := time.Since(bt10_0) 592 fmt.Printf("Test_PageBlock_Perf FlushIter_Next_Ranges time cost = %v\n", et10_0) 593 594 getFunc := func(i int) { 595 skey := kvList[i].Key.UserKey 596 val, exist, _, closer := a.get(skey, hash.Crc32(skey)) 597 require.Equal(t, true, exist) 598 require.Equal(t, kvList[i].Value, val) 599 if closer != nil { 600 closer() 601 } 602 } 603 604 seekFunc := func(i int) { 605 it1 := a.newIter(nil) 606 skey := kvList[i].Key.UserKey 607 ik, v := it1.SeekGE(skey) 608 require.Equal(t, skey, ik.UserKey) 609 require.Equal(t, kvList[i].Value, v) 610 require.NoError(t, it1.Close()) 611 } 612 613 seekltFunc := func(seek, exp int) { 614 it1 := a.newIter(nil) 615 skey := kvList[i].Key.UserKey 616 ik, v := it1.SeekLT(skey) 617 if exp != -1 { 618 require.Equal(t, kvList[exp].Key.UserKey, ik.UserKey) 619 require.Equal(t, kvList[exp].Value, v) 620 } 621 require.NoError(t, it1.Close()) 622 } 623 624 seekNotExist := func(skey []byte) { 625 _, exist, _, closer := a.get(skey, hash.Crc32(skey)) 626 require.Equal(t, false, exist) 627 if closer != nil { 628 closer() 629 } 630 } 631 632 bt1_0 := time.Now() 633 iter = a.newIter(nil) 634 i = 0 635 for key, val := iter.First(); key != nil; key, val = iter.Next() { 636 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 637 require.Equal(t, kvList[i].Value, val) 638 i++ 639 } 640 require.Equal(t, count, i) 641 require.NoError(t, iter.Close()) 642 et1_0 := time.Since(bt1_0) 643 fmt.Printf("Test_PageBlock_Perf Next_Ranges time cost = %v\n", et1_0) 644 645 bt1_00 := time.Now() 646 iter = a.newIter(nil) 647 i = count - 1 648 for key, val := iter.Last(); key != nil; key, val = iter.Prev() { 649 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 650 require.Equal(t, kvList[i].Value, val) 651 i-- 652 } 653 require.Equal(t, -1, i) 654 require.NoError(t, iter.Close()) 655 et1_00 := time.Since(bt1_00) 656 fmt.Printf("Test_PageBlock_Perf Prev_Ranges time cost = %v\n", et1_00) 657 658 bt1_1 := time.Now() 659 for i = 0; i < count; i++ { 660 getFunc(i) 661 } 662 et1_1 := time.Since(bt1_1) 663 fmt.Printf("Test_PageBlock_Perf GET time cost = %v\n", et1_1) 664 665 bt1_2 := time.Now() 666 for i = 0; i < count; i++ { 667 if i == 0 { 668 seekltFunc(0, -1) 669 } else { 670 seekltFunc(i, i-1) 671 } 672 } 673 et1_2 := time.Since(bt1_2) 674 fmt.Printf("Test_PageBlock_Perf SeekLT time cost = %v\n", et1_2) 675 676 for _, j := range []int{100007 * 100, 100071 * 100, 100711 * 100} { 677 seekNotExist(sortedkv.MakeSortedKey(j)) 678 } 679 680 bt1_3 := time.Now() 681 for i = 0; i < count; i++ { 682 seekFunc(i) 683 } 684 et1_3 := time.Since(bt1_3) 685 fmt.Printf("Test_PageBlock_Perf SeekGE time cost = %v\n", et1_3) 686 } 687 688 bt2 := time.Now() 689 seekFunc(at) 690 et2 := time.Since(bt2) 691 fmt.Printf("Test_PageBlock_Perf seekArrayTable time cost = %v\n", et2) 692 693 require.NoError(t, at.close()) 694 695 et0 := time.Since(bt0) 696 fmt.Printf("Finish Test_PageBlock_Perf, opts(usePrefixCompress, useBlockCompress)=%#v, time cost = %v\n======================\n", opts, et0) 697 698 os.Remove(testPath) 699 } 700 et := time.Since(bt) 701 fmt.Printf("Test_PageBlock_Perf Total End, time cost = %v\n", et) 702 } 703 704 func Test_Bitrie_Perf(t *testing.T) { 705 defer os.Remove(testPath) 706 os.Remove(testPath) 707 708 count := item_count 709 seqNum := uint64(1) 710 kvList := testMakeSortedKVForBitrie(count, seqNum, 10) 711 seqNum += uint64(count) 712 713 if count <= 50 { 714 for i := 0; i < count; i++ { 715 fmt.Printf("%s\n", kvList[i].Key.UserKey) 716 } 717 } 718 719 bt := time.Now() 720 for _, opts := range [][]bool{ 721 {false, false, true}, 722 } { 723 bt0 := time.Now() 724 fmt.Printf("Start Test_Bitrie_Perf, opts(usePrefixCompress, useBlockCompress)=%#v\n", opts) 725 726 atCacheOpts := &atCacheOptions{ 727 cache: testNewBlockCache(), 728 id: 1 << 10, 729 } 730 option := &atOptions{ 731 useMapIndex: false, 732 usePrefixCompress: opts[0], 733 useBlockCompress: opts[1], 734 useBitrieCompress: opts[2], 735 blockSize: 32 << 10, 736 } 737 at, err := newArrayTable(testPath, option, atCacheOpts) 738 require.NoError(t, err) 739 740 bt1 := time.Now() 741 for i := 0; i < count; i++ { 742 _, err = at.writeItem(kvList[i].Key.UserKey, kvList[i].Value) 743 require.NoError(t, err) 744 } 745 746 require.NoError(t, at.writeFinish()) 747 et1 := time.Since(bt1) 748 fmt.Printf("Test_Bitrie_Perf writeArrayTable time cost = %v; header=%v\n", et1, at.header.version) 749 750 if count <= 50 { 751 fmt.Printf("Test_Bitrie_Perf BitrieToString:\n%s\n", at.bitrieIndex.AnalyzeBytes()) 752 } 753 754 fmt.Printf("opts(usePrefixCompress, useBlockCompress, useBitrieCompress)=%#v; at.size=%dKB; tbl.size=%dKB, at.tbl.fileStatSize=%dKB; totalNum=%d\n", opts, at.size/1024, at.tbl.Size()/1024, at.tbl.fileStatSize()/1024, at.num) 755 756 seekFunc := func(a *arrayTable) { 757 i := 0 758 /*bt10_0 := time.Now() 759 iter := a.newIter(nil) 760 for key, val := iter.First(); key != nil; key, val = iter.Next() { 761 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 762 require.Equal(t, kvList[i].Value, val) 763 i++ 764 } 765 require.Equal(t, count, i) 766 require.NoError(t, iter.Close()) 767 et10_0 := time.Since(bt10_0) 768 fmt.Printf("Test_PageBlock_Perf FlushIter_Next_Ranges time cost = %v\n", et10_0) 769 */ 770 771 getFunc := func(i int) { 772 skey := kvList[i].Key.UserKey 773 val, exist, _, closer := a.get(skey, 0 /*hash.Crc32(skey)*/) 774 require.Equal(t, true, exist) 775 require.Equal(t, kvList[i].Value, val) 776 if closer != nil { 777 closer() 778 } 779 } 780 781 /*seekFunc := func(i int) { 782 it1 := a.newIter(nil) 783 skey := kvList[i].Key.UserKey 784 ik, v := it1.SeekGE(skey) 785 require.Equal(t, skey, ik.UserKey) 786 require.Equal(t, kvList[i].Value, v) 787 require.NoError(t, it1.Close()) 788 } 789 790 seekltFunc := func(seek, exp int) { 791 it1 := a.newIter(nil) 792 skey := kvList[i].Key.UserKey 793 ik, v := it1.SeekLT(skey) 794 if exp != -1 { 795 require.Equal(t, kvList[exp].Key.UserKey, ik.UserKey) 796 require.Equal(t, kvList[exp].Value, v) 797 } 798 require.NoError(t, it1.Close()) 799 } 800 801 seekNotExist := func(skey []byte) { 802 _, exist, _, closer := a.get(skey, hash.Crc32(skey)) 803 require.Equal(t, false, exist) 804 if closer != nil { 805 closer() 806 } 807 } 808 809 bt1_0 := time.Now() 810 iter = a.newIter(nil) 811 i = 0 812 for key, val := iter.First(); key != nil; key, val = iter.Next() { 813 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 814 require.Equal(t, kvList[i].Value, val) 815 i++ 816 } 817 require.Equal(t, count, i) 818 require.NoError(t, iter.Close()) 819 et1_0 := time.Since(bt1_0) 820 fmt.Printf("Test_Bitrie_Perf Next_Ranges time cost = %v\n", et1_0) 821 822 bt1_00 := time.Now() 823 iter = a.newIter(nil) 824 i = count - 1 825 for key, val := iter.Last(); key != nil; key, val = iter.Prev() { 826 require.Equal(t, kvList[i].Key.UserKey, key.UserKey) 827 require.Equal(t, kvList[i].Value, val) 828 i-- 829 } 830 require.Equal(t, -1, i) 831 require.NoError(t, iter.Close()) 832 et1_00 := time.Since(bt1_00) 833 fmt.Printf("Test_Bitrie_Perf Prev_Ranges time cost = %v\n", et1_00) 834 */ 835 836 bt1_1 := time.Now() 837 for i = 0; i < count; i++ { 838 getFunc(i) 839 } 840 et1_1 := time.Since(bt1_1) 841 fmt.Printf("Test_Bitrie_Perf GET time cost = %v\n", et1_1) 842 843 /*bt1_2 := time.Now() 844 for i = 0; i < count; i++ { 845 if i == 0 { 846 seekltFunc(0, -1) 847 } else { 848 seekltFunc(i, i-1) 849 } 850 } 851 et1_2 := time.Since(bt1_2) 852 fmt.Printf("Test_Bitrie_Perf SeekLT time cost = %v\n", et1_2) 853 854 for _, j := range []int{100007, 100071, 100711} { 855 seekNotExist(utils.MakeSortedKey(j)) 856 } 857 858 bt1_3 := time.Now() 859 for i = 0; i < count; i++ { 860 seekFunc(i) 861 } 862 et1_3 := time.Since(bt1_3) 863 fmt.Printf("Test_Bitrie_Perf SeekGE time cost = %v\n", et1_3)*/ 864 } 865 866 bt2 := time.Now() 867 seekFunc(at) 868 et2 := time.Since(bt2) 869 fmt.Printf("Test_Bitrie_Perf seekArrayTable time cost = %v\n", et2) 870 871 require.NoError(t, at.close()) 872 873 et0 := time.Since(bt0) 874 fmt.Printf("Finish Test_Bitrie_Perf, opts(usePrefixCompress, useBlockCompress)=%#v, time cost = %v\n======================\n", opts, et0) 875 876 os.Remove(testPath) 877 } 878 et := time.Since(bt) 879 fmt.Printf("Test_Bitrie_Perf Total End, time cost = %v\n", et) 880 } 881 882 func Test_AtEqual(t *testing.T) { 883 key1 := []byte("asdfghjklpoiuytrewq") 884 key2 := []byte("asdfghjklpoiuytrewq") 885 sk1 := []byte("asdfghjkl") 886 sk2 := []byte("poiuytrewq") 887 888 totalNum := 2 << 20 889 startNum := 0 890 891 fmt.Println(bytes.Equal(key1, key2), atEqual(sk1, sk2, key1)) 892 893 bt := time.Now() 894 for i := startNum; i <= totalNum; i++ { 895 if !bytes.Equal(key1, key2) { 896 fmt.Printf("bytes.Equal error") 897 } 898 } 899 et := time.Since(bt) 900 fmt.Printf("bytes.Equal time cost = %v\n", et) 901 902 bt = time.Now() 903 for i := startNum; i <= totalNum; i++ { 904 if !atEqual(sk1, sk2, key2) { 905 fmt.Printf("atEqual error") 906 } 907 } 908 et = time.Since(bt) 909 fmt.Printf("atEqual time cost = %v\n", et) 910 911 bt = time.Now() 912 for i := startNum; i <= totalNum; i++ { 913 tmpk := make([]byte, 0, len(key1)) 914 tmpk = append(tmpk, sk1...) 915 tmpk = append(tmpk, sk2...) 916 if !bytes.Equal(tmpk, key2) { 917 fmt.Printf("atEqual error") 918 } 919 } 920 et = time.Since(bt) 921 fmt.Printf("make&bytes.Equal time cost = %v\n", et) 922 } 923 924 func Test_AtCompare(t *testing.T) { 925 key1 := []byte("asdfghjklpoiuytrewq") 926 key2 := []byte("asdfghjklpoiuytrewq") 927 sk1 := []byte("asdfghjkl") 928 sk2 := []byte("poiuytrewq") 929 930 totalNum := 1 << 20 931 startNum := 0 932 933 bt := time.Now() 934 for i := startNum; i <= totalNum; i++ { 935 if bytes.Compare(key1, key2) != 0 { 936 fmt.Printf("bytes.Compare error") 937 } 938 } 939 et := time.Since(bt) 940 fmt.Printf("bytes.Compare time cost = %v\n", et) 941 942 bt = time.Now() 943 for i := startNum; i <= totalNum; i++ { 944 if atCompare(sk1, sk2, key2) != 0 { 945 fmt.Printf("atCompare error") 946 } 947 } 948 et = time.Since(bt) 949 fmt.Printf("atCompare time cost = %v\n", et) 950 951 bt = time.Now() 952 for i := startNum; i <= totalNum; i++ { 953 tmpk := make([]byte, 0, len(key1)) 954 tmpk = append(tmpk, sk1...) 955 tmpk = append(tmpk, sk2...) 956 if bytes.Compare(tmpk, key2) != 0 { 957 fmt.Printf("bytes.Compare error") 958 } 959 } 960 et = time.Since(bt) 961 fmt.Printf("make&bytes.Compare time cost = %v\n", et) 962 } 963 964 func Test_AtCompare_Case(t *testing.T) { 965 type compareCase struct { 966 key []byte 967 sk1 []byte 968 sk2 []byte 969 ret int 970 } 971 972 caseList := make([]compareCase, 0, 2<<4) 973 974 caseList = append(caseList, compareCase{key: []byte("asdfghjklpoiuytrewq"), sk1: []byte("asdfghjkl"), sk2: []byte("poiuytrewq"), ret: 0}) 975 caseList = append(caseList, compareCase{key: []byte("asdfghjkl"), sk1: []byte("asdfghjkl"), sk2: []byte(""), ret: 0}) 976 caseList = append(caseList, compareCase{key: []byte("asdfghjkl"), sk1: []byte(""), sk2: []byte("asdfghjkl"), ret: 0}) 977 caseList = append(caseList, compareCase{key: []byte("qwer"), sk1: []byte("asdfghjklpoiuytrewq"), sk2: []byte("a"), ret: -1}) 978 caseList = append(caseList, compareCase{key: []byte("fdafa"), sk1: []byte("qsdfghjklpoiuytrewq"), sk2: []byte("a"), ret: 1}) 979 caseList = append(caseList, compareCase{key: []byte("qsdfghjklpoiuytrewqqqqqq"), sk1: []byte("qsdfghjklpoiuytrewq"), sk2: []byte("a"), ret: -1}) 980 caseList = append(caseList, compareCase{key: []byte("qsdfghjklpoiuytrewqqqqqq"), sk1: []byte("qsdfghjklpoiuytrewq"), sk2: []byte("zzzz"), ret: 1}) 981 caseList = append(caseList, compareCase{key: []byte("abcd"), sk1: []byte("a"), sk2: []byte("zzz"), ret: 1}) 982 caseList = append(caseList, compareCase{key: []byte("abcd"), sk1: []byte("a"), sk2: []byte("azzz"), ret: -1}) 983 984 for i := 0; i < len(caseList); i++ { 985 r := atCompare(caseList[i].sk1, caseList[i].sk2, caseList[i].key) 986 require.Equal(t, r, caseList[i].ret) 987 } 988 }