1 // Copyright 2014 Google Inc. 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 btree 16 17 import ( 18 "flag" 19 "fmt" 20 "math/rand" 21 "reflect" 22 "sort" 23 "sync" 24 "testing" 25 "time" 26 ) 27 28 func init() { 29 seed := time.Now().Unix() 30 fmt.Println(seed) 31 rand.Seed(seed) 32 } 33 34 // perm returns a random permutation of n Int items in the range [0, n). 35 func perm(n int) (out []Item) { 36 for _, v := range rand.Perm(n) { 37 out = append(out, Int(v)) 38 } 39 return 40 } 41 42 // rang returns an ordered list of Int items in the range [0, n). 43 func rang(n int) (out []Item) { 44 for i := 0; i < n; i++ { 45 out = append(out, Int(i)) 46 } 47 return 48 } 49 50 // all extracts all items from a tree in order as a slice. 51 func all(t *BTree) (out []Item) { 52 t.Ascend(func(a Item) bool { 53 out = append(out, a) 54 return true 55 }) 56 return 57 } 58 59 // rangerev returns a reversed ordered list of Int items in the range [0, n). 60 func rangrev(n int) (out []Item) { 61 for i := n - 1; i >= 0; i-- { 62 out = append(out, Int(i)) 63 } 64 return 65 } 66 67 // allrev extracts all items from a tree in reverse order as a slice. 68 func allrev(t *BTree) (out []Item) { 69 t.Descend(func(a Item) bool { 70 out = append(out, a) 71 return true 72 }) 73 return 74 } 75 76 var btreeDegree = flag.Int("degree", 32, "B-Tree degree") 77 78 func TestBTree(t *testing.T) { 79 tr := New(*btreeDegree) 80 const treeSize = 10000 81 for i := 0; i < 10; i++ { 82 if min := tr.Min(); min != nil { 83 t.Fatalf("empty min, got %+v", min) 84 } 85 if max := tr.Max(); max != nil { 86 t.Fatalf("empty max, got %+v", max) 87 } 88 for _, item := range perm(treeSize) { 89 if x := tr.ReplaceOrInsert(item); x != nil { 90 t.Fatal("insert found item", item) 91 } 92 } 93 for _, item := range perm(treeSize) { 94 if x := tr.ReplaceOrInsert(item); x == nil { 95 t.Fatal("insert didn't find item", item) 96 } 97 } 98 if min, want := tr.Min(), Item(Int(0)); min != want { 99 t.Fatalf("min: want %+v, got %+v", want, min) 100 } 101 if max, want := tr.Max(), Item(Int(treeSize-1)); max != want { 102 t.Fatalf("max: want %+v, got %+v", want, max) 103 } 104 got := all(tr) 105 want := rang(treeSize) 106 if !reflect.DeepEqual(got, want) { 107 t.Fatalf("mismatch:\n got: %v\nwant: %v", got, want) 108 } 109 110 gotrev := allrev(tr) 111 wantrev := rangrev(treeSize) 112 if !reflect.DeepEqual(gotrev, wantrev) { 113 t.Fatalf("mismatch:\n got: %v\nwant: %v", got, want) 114 } 115 116 for _, item := range perm(treeSize) { 117 if x := tr.Delete(item); x == nil { 118 t.Fatalf("didn't find %v", item) 119 } 120 } 121 if got = all(tr); len(got) > 0 { 122 t.Fatalf("some left!: %v", got) 123 } 124 } 125 } 126 127 func ExampleBTree() { 128 tr := New(*btreeDegree) 129 for i := Int(0); i < 10; i++ { 130 tr.ReplaceOrInsert(i) 131 } 132 fmt.Println("len: ", tr.Len()) 133 fmt.Println("get3: ", tr.Get(Int(3))) 134 fmt.Println("get100: ", tr.Get(Int(100))) 135 fmt.Println("del4: ", tr.Delete(Int(4))) 136 fmt.Println("del100: ", tr.Delete(Int(100))) 137 fmt.Println("replace5: ", tr.ReplaceOrInsert(Int(5))) 138 fmt.Println("replace100:", tr.ReplaceOrInsert(Int(100))) 139 fmt.Println("min: ", tr.Min()) 140 fmt.Println("delmin: ", tr.DeleteMin()) 141 fmt.Println("max: ", tr.Max()) 142 fmt.Println("delmax: ", tr.DeleteMax()) 143 fmt.Println("len: ", tr.Len()) 144 // Output: 145 // len: 10 146 // get3: 3 147 // get100: <nil> 148 // del4: 4 149 // del100: <nil> 150 // replace5: 5 151 // replace100: <nil> 152 // min: 0 153 // delmin: 0 154 // max: 100 155 // delmax: 100 156 // len: 8 157 } 158 159 func TestDeleteMin(t *testing.T) { 160 tr := New(3) 161 for _, v := range perm(100) { 162 tr.ReplaceOrInsert(v) 163 } 164 var got []Item 165 for v := tr.DeleteMin(); v != nil; v = tr.DeleteMin() { 166 got = append(got, v) 167 } 168 if want := rang(100); !reflect.DeepEqual(got, want) { 169 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 170 } 171 } 172 173 func TestDeleteMax(t *testing.T) { 174 tr := New(3) 175 for _, v := range perm(100) { 176 tr.ReplaceOrInsert(v) 177 } 178 var got []Item 179 for v := tr.DeleteMax(); v != nil; v = tr.DeleteMax() { 180 got = append(got, v) 181 } 182 // Reverse our list. 183 for i := 0; i < len(got)/2; i++ { 184 got[i], got[len(got)-i-1] = got[len(got)-i-1], got[i] 185 } 186 if want := rang(100); !reflect.DeepEqual(got, want) { 187 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 188 } 189 } 190 191 func TestAscendRange(t *testing.T) { 192 tr := New(2) 193 for _, v := range perm(100) { 194 tr.ReplaceOrInsert(v) 195 } 196 var got []Item 197 tr.AscendRange(Int(40), Int(60), func(a Item) bool { 198 got = append(got, a) 199 return true 200 }) 201 if want := rang(100)[40:60]; !reflect.DeepEqual(got, want) { 202 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 203 } 204 got = got[:0] 205 tr.AscendRange(Int(40), Int(60), func(a Item) bool { 206 if a.(Int) > 50 { 207 return false 208 } 209 got = append(got, a) 210 return true 211 }) 212 if want := rang(100)[40:51]; !reflect.DeepEqual(got, want) { 213 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 214 } 215 } 216 217 func TestDescendRange(t *testing.T) { 218 tr := New(2) 219 for _, v := range perm(100) { 220 tr.ReplaceOrInsert(v) 221 } 222 var got []Item 223 tr.DescendRange(Int(60), Int(40), func(a Item) bool { 224 got = append(got, a) 225 return true 226 }) 227 if want := rangrev(100)[39:59]; !reflect.DeepEqual(got, want) { 228 t.Fatalf("descendrange:\n got: %v\nwant: %v", got, want) 229 } 230 got = got[:0] 231 tr.DescendRange(Int(60), Int(40), func(a Item) bool { 232 if a.(Int) < 50 { 233 return false 234 } 235 got = append(got, a) 236 return true 237 }) 238 if want := rangrev(100)[39:50]; !reflect.DeepEqual(got, want) { 239 t.Fatalf("descendrange:\n got: %v\nwant: %v", got, want) 240 } 241 } 242 func TestAscendLessThan(t *testing.T) { 243 tr := New(*btreeDegree) 244 for _, v := range perm(100) { 245 tr.ReplaceOrInsert(v) 246 } 247 var got []Item 248 tr.AscendLessThan(Int(60), func(a Item) bool { 249 got = append(got, a) 250 return true 251 }) 252 if want := rang(100)[:60]; !reflect.DeepEqual(got, want) { 253 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 254 } 255 got = got[:0] 256 tr.AscendLessThan(Int(60), func(a Item) bool { 257 if a.(Int) > 50 { 258 return false 259 } 260 got = append(got, a) 261 return true 262 }) 263 if want := rang(100)[:51]; !reflect.DeepEqual(got, want) { 264 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 265 } 266 } 267 268 func TestDescendLessOrEqual(t *testing.T) { 269 tr := New(*btreeDegree) 270 for _, v := range perm(100) { 271 tr.ReplaceOrInsert(v) 272 } 273 var got []Item 274 tr.DescendLessOrEqual(Int(40), func(a Item) bool { 275 got = append(got, a) 276 return true 277 }) 278 if want := rangrev(100)[59:]; !reflect.DeepEqual(got, want) { 279 t.Fatalf("descendlessorequal:\n got: %v\nwant: %v", got, want) 280 } 281 got = got[:0] 282 tr.DescendLessOrEqual(Int(60), func(a Item) bool { 283 if a.(Int) < 50 { 284 return false 285 } 286 got = append(got, a) 287 return true 288 }) 289 if want := rangrev(100)[39:50]; !reflect.DeepEqual(got, want) { 290 t.Fatalf("descendlessorequal:\n got: %v\nwant: %v", got, want) 291 } 292 } 293 func TestAscendGreaterOrEqual(t *testing.T) { 294 tr := New(*btreeDegree) 295 for _, v := range perm(100) { 296 tr.ReplaceOrInsert(v) 297 } 298 var got []Item 299 tr.AscendGreaterOrEqual(Int(40), func(a Item) bool { 300 got = append(got, a) 301 return true 302 }) 303 if want := rang(100)[40:]; !reflect.DeepEqual(got, want) { 304 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 305 } 306 got = got[:0] 307 tr.AscendGreaterOrEqual(Int(40), func(a Item) bool { 308 if a.(Int) > 50 { 309 return false 310 } 311 got = append(got, a) 312 return true 313 }) 314 if want := rang(100)[40:51]; !reflect.DeepEqual(got, want) { 315 t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want) 316 } 317 } 318 319 func TestDescendGreaterThan(t *testing.T) { 320 tr := New(*btreeDegree) 321 for _, v := range perm(100) { 322 tr.ReplaceOrInsert(v) 323 } 324 var got []Item 325 tr.DescendGreaterThan(Int(40), func(a Item) bool { 326 got = append(got, a) 327 return true 328 }) 329 if want := rangrev(100)[:59]; !reflect.DeepEqual(got, want) { 330 t.Fatalf("descendgreaterthan:\n got: %v\nwant: %v", got, want) 331 } 332 got = got[:0] 333 tr.DescendGreaterThan(Int(40), func(a Item) bool { 334 if a.(Int) < 50 { 335 return false 336 } 337 got = append(got, a) 338 return true 339 }) 340 if want := rangrev(100)[:50]; !reflect.DeepEqual(got, want) { 341 t.Fatalf("descendgreaterthan:\n got: %v\nwant: %v", got, want) 342 } 343 } 344 345 const benchmarkTreeSize = 10000 346 347 func BenchmarkInsert(b *testing.B) { 348 b.StopTimer() 349 insertP := perm(benchmarkTreeSize) 350 b.StartTimer() 351 i := 0 352 for i < b.N { 353 tr := New(*btreeDegree) 354 for _, item := range insertP { 355 tr.ReplaceOrInsert(item) 356 i++ 357 if i >= b.N { 358 return 359 } 360 } 361 } 362 } 363 364 func BenchmarkSeek(b *testing.B) { 365 b.StopTimer() 366 size := 100000 367 insertP := perm(size) 368 tr := New(*btreeDegree) 369 for _, item := range insertP { 370 tr.ReplaceOrInsert(item) 371 } 372 b.StartTimer() 373 374 for i := 0; i < b.N; i++ { 375 tr.AscendGreaterOrEqual(Int(i%size), func(i Item) bool { return false }) 376 } 377 } 378 379 func BenchmarkDeleteInsert(b *testing.B) { 380 b.StopTimer() 381 insertP := perm(benchmarkTreeSize) 382 tr := New(*btreeDegree) 383 for _, item := range insertP { 384 tr.ReplaceOrInsert(item) 385 } 386 b.StartTimer() 387 for i := 0; i < b.N; i++ { 388 tr.Delete(insertP[i%benchmarkTreeSize]) 389 tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize]) 390 } 391 } 392 393 func BenchmarkDeleteInsertCloneOnce(b *testing.B) { 394 b.StopTimer() 395 insertP := perm(benchmarkTreeSize) 396 tr := New(*btreeDegree) 397 for _, item := range insertP { 398 tr.ReplaceOrInsert(item) 399 } 400 tr = tr.Clone() 401 b.StartTimer() 402 for i := 0; i < b.N; i++ { 403 tr.Delete(insertP[i%benchmarkTreeSize]) 404 tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize]) 405 } 406 } 407 408 func BenchmarkDeleteInsertCloneEachTime(b *testing.B) { 409 b.StopTimer() 410 insertP := perm(benchmarkTreeSize) 411 tr := New(*btreeDegree) 412 for _, item := range insertP { 413 tr.ReplaceOrInsert(item) 414 } 415 b.StartTimer() 416 for i := 0; i < b.N; i++ { 417 tr = tr.Clone() 418 tr.Delete(insertP[i%benchmarkTreeSize]) 419 tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize]) 420 } 421 } 422 423 func BenchmarkDelete(b *testing.B) { 424 b.StopTimer() 425 insertP := perm(benchmarkTreeSize) 426 removeP := perm(benchmarkTreeSize) 427 b.StartTimer() 428 i := 0 429 for i < b.N { 430 b.StopTimer() 431 tr := New(*btreeDegree) 432 for _, v := range insertP { 433 tr.ReplaceOrInsert(v) 434 } 435 b.StartTimer() 436 for _, item := range removeP { 437 tr.Delete(item) 438 i++ 439 if i >= b.N { 440 return 441 } 442 } 443 if tr.Len() > 0 { 444 panic(tr.Len()) 445 } 446 } 447 } 448 449 func BenchmarkGet(b *testing.B) { 450 b.StopTimer() 451 insertP := perm(benchmarkTreeSize) 452 removeP := perm(benchmarkTreeSize) 453 b.StartTimer() 454 i := 0 455 for i < b.N { 456 b.StopTimer() 457 tr := New(*btreeDegree) 458 for _, v := range insertP { 459 tr.ReplaceOrInsert(v) 460 } 461 b.StartTimer() 462 for _, item := range removeP { 463 tr.Get(item) 464 i++ 465 if i >= b.N { 466 return 467 } 468 } 469 } 470 } 471 472 func BenchmarkGetCloneEachTime(b *testing.B) { 473 b.StopTimer() 474 insertP := perm(benchmarkTreeSize) 475 removeP := perm(benchmarkTreeSize) 476 b.StartTimer() 477 i := 0 478 for i < b.N { 479 b.StopTimer() 480 tr := New(*btreeDegree) 481 for _, v := range insertP { 482 tr.ReplaceOrInsert(v) 483 } 484 b.StartTimer() 485 for _, item := range removeP { 486 tr = tr.Clone() 487 tr.Get(item) 488 i++ 489 if i >= b.N { 490 return 491 } 492 } 493 } 494 } 495 496 type byInts []Item 497 498 func (a byInts) Len() int { 499 return len(a) 500 } 501 502 func (a byInts) Less(i, j int) bool { 503 return a[i].(Int) < a[j].(Int) 504 } 505 506 func (a byInts) Swap(i, j int) { 507 a[i], a[j] = a[j], a[i] 508 } 509 510 func BenchmarkAscend(b *testing.B) { 511 arr := perm(benchmarkTreeSize) 512 tr := New(*btreeDegree) 513 for _, v := range arr { 514 tr.ReplaceOrInsert(v) 515 } 516 sort.Sort(byInts(arr)) 517 b.ResetTimer() 518 for i := 0; i < b.N; i++ { 519 j := 0 520 tr.Ascend(func(item Item) bool { 521 if item.(Int) != arr[j].(Int) { 522 b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int)) 523 } 524 j++ 525 return true 526 }) 527 } 528 } 529 530 func BenchmarkDescend(b *testing.B) { 531 arr := perm(benchmarkTreeSize) 532 tr := New(*btreeDegree) 533 for _, v := range arr { 534 tr.ReplaceOrInsert(v) 535 } 536 sort.Sort(byInts(arr)) 537 b.ResetTimer() 538 for i := 0; i < b.N; i++ { 539 j := len(arr) - 1 540 tr.Descend(func(item Item) bool { 541 if item.(Int) != arr[j].(Int) { 542 b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int)) 543 } 544 j-- 545 return true 546 }) 547 } 548 } 549 func BenchmarkAscendRange(b *testing.B) { 550 arr := perm(benchmarkTreeSize) 551 tr := New(*btreeDegree) 552 for _, v := range arr { 553 tr.ReplaceOrInsert(v) 554 } 555 sort.Sort(byInts(arr)) 556 b.ResetTimer() 557 for i := 0; i < b.N; i++ { 558 j := 100 559 tr.AscendRange(Int(100), arr[len(arr)-100], func(item Item) bool { 560 if item.(Int) != arr[j].(Int) { 561 b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int)) 562 } 563 j++ 564 return true 565 }) 566 if j != len(arr)-100 { 567 b.Fatalf("expected: %v, got %v", len(arr)-100, j) 568 } 569 } 570 } 571 572 func BenchmarkDescendRange(b *testing.B) { 573 arr := perm(benchmarkTreeSize) 574 tr := New(*btreeDegree) 575 for _, v := range arr { 576 tr.ReplaceOrInsert(v) 577 } 578 sort.Sort(byInts(arr)) 579 b.ResetTimer() 580 for i := 0; i < b.N; i++ { 581 j := len(arr) - 100 582 tr.DescendRange(arr[len(arr)-100], Int(100), func(item Item) bool { 583 if item.(Int) != arr[j].(Int) { 584 b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int)) 585 } 586 j-- 587 return true 588 }) 589 if j != 100 { 590 b.Fatalf("expected: %v, got %v", len(arr)-100, j) 591 } 592 } 593 } 594 func BenchmarkAscendGreaterOrEqual(b *testing.B) { 595 arr := perm(benchmarkTreeSize) 596 tr := New(*btreeDegree) 597 for _, v := range arr { 598 tr.ReplaceOrInsert(v) 599 } 600 sort.Sort(byInts(arr)) 601 b.ResetTimer() 602 for i := 0; i < b.N; i++ { 603 j := 100 604 k := 0 605 tr.AscendGreaterOrEqual(Int(100), func(item Item) bool { 606 if item.(Int) != arr[j].(Int) { 607 b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int)) 608 } 609 j++ 610 k++ 611 return true 612 }) 613 if j != len(arr) { 614 b.Fatalf("expected: %v, got %v", len(arr), j) 615 } 616 if k != len(arr)-100 { 617 b.Fatalf("expected: %v, got %v", len(arr)-100, k) 618 } 619 } 620 } 621 func BenchmarkDescendLessOrEqual(b *testing.B) { 622 arr := perm(benchmarkTreeSize) 623 tr := New(*btreeDegree) 624 for _, v := range arr { 625 tr.ReplaceOrInsert(v) 626 } 627 sort.Sort(byInts(arr)) 628 b.ResetTimer() 629 for i := 0; i < b.N; i++ { 630 j := len(arr) - 100 631 k := len(arr) 632 tr.DescendLessOrEqual(arr[len(arr)-100], func(item Item) bool { 633 if item.(Int) != arr[j].(Int) { 634 b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int)) 635 } 636 j-- 637 k-- 638 return true 639 }) 640 if j != -1 { 641 b.Fatalf("expected: %v, got %v", -1, j) 642 } 643 if k != 99 { 644 b.Fatalf("expected: %v, got %v", 99, k) 645 } 646 } 647 } 648 649 const cloneTestSize = 10000 650 651 func cloneTest(t *testing.T, b *BTree, start int, p []Item, wg *sync.WaitGroup, trees *[]*BTree) { 652 t.Logf("Starting new clone at %v", start) 653 *trees = append(*trees, b) 654 for i := start; i < cloneTestSize; i++ { 655 b.ReplaceOrInsert(p[i]) 656 if i%(cloneTestSize/5) == 0 { 657 wg.Add(1) 658 go cloneTest(t, b.Clone(), i+1, p, wg, trees) 659 } 660 } 661 wg.Done() 662 } 663 664 func TestCloneConcurrentOperations(t *testing.T) { 665 b := New(*btreeDegree) 666 trees := []*BTree{} 667 p := perm(cloneTestSize) 668 var wg sync.WaitGroup 669 wg.Add(1) 670 go cloneTest(t, b, 0, p, &wg, &trees) 671 wg.Wait() 672 want := rang(cloneTestSize) 673 t.Logf("Starting equality checks on %d trees", len(trees)) 674 for i, tree := range trees { 675 if !reflect.DeepEqual(want, all(tree)) { 676 t.Errorf("tree %v mismatch", i) 677 } 678 } 679 t.Log("Removing half from first half") 680 toRemove := rang(cloneTestSize)[cloneTestSize/2:] 681 for i := 0; i < len(trees)/2; i++ { 682 tree := trees[i] 683 wg.Add(1) 684 go func() { 685 for _, item := range toRemove { 686 tree.Delete(item) 687 } 688 wg.Done() 689 }() 690 } 691 wg.Wait() 692 t.Log("Checking all values again") 693 for i, tree := range trees { 694 var wantpart []Item 695 if i < len(trees)/2 { 696 wantpart = want[:cloneTestSize/2] 697 } else { 698 wantpart = want 699 } 700 if got := all(tree); !reflect.DeepEqual(wantpart, got) { 701 t.Errorf("tree %v mismatch, want %v got %v", i, len(want), len(got)) 702 } 703 } 704 } 705 706 func BenchmarkDeleteAndRestore(b *testing.B) { 707 items := perm(16392) 708 b.ResetTimer() 709 b.Run(`CopyBigFreeList`, func(b *testing.B) { 710 fl := NewFreeList(16392) 711 tr := NewWithFreeList(*btreeDegree, fl) 712 for _, v := range items { 713 tr.ReplaceOrInsert(v) 714 } 715 b.ReportAllocs() 716 b.ResetTimer() 717 for i := 0; i < b.N; i++ { 718 dels := make([]Item, 0, tr.Len()) 719 tr.Ascend(ItemIterator(func(b Item) bool { 720 dels = append(dels, b) 721 return true 722 })) 723 for _, del := range dels { 724 tr.Delete(del) 725 } 726 // tr is now empty, we make a new empty copy of it. 727 tr = NewWithFreeList(*btreeDegree, fl) 728 for _, v := range items { 729 tr.ReplaceOrInsert(v) 730 } 731 } 732 }) 733 b.Run(`Copy`, func(b *testing.B) { 734 tr := New(*btreeDegree) 735 for _, v := range items { 736 tr.ReplaceOrInsert(v) 737 } 738 b.ReportAllocs() 739 b.ResetTimer() 740 for i := 0; i < b.N; i++ { 741 dels := make([]Item, 0, tr.Len()) 742 tr.Ascend(ItemIterator(func(b Item) bool { 743 dels = append(dels, b) 744 return true 745 })) 746 for _, del := range dels { 747 tr.Delete(del) 748 } 749 // tr is now empty, we make a new empty copy of it. 750 tr = New(*btreeDegree) 751 for _, v := range items { 752 tr.ReplaceOrInsert(v) 753 } 754 } 755 }) 756 b.Run(`ClearBigFreelist`, func(b *testing.B) { 757 fl := NewFreeList(16392) 758 tr := NewWithFreeList(*btreeDegree, fl) 759 for _, v := range items { 760 tr.ReplaceOrInsert(v) 761 } 762 b.ReportAllocs() 763 b.ResetTimer() 764 for i := 0; i < b.N; i++ { 765 tr.Clear(true) 766 for _, v := range items { 767 tr.ReplaceOrInsert(v) 768 } 769 } 770 }) 771 b.Run(`Clear`, func(b *testing.B) { 772 tr := New(*btreeDegree) 773 for _, v := range items { 774 tr.ReplaceOrInsert(v) 775 } 776 b.ReportAllocs() 777 b.ResetTimer() 778 for i := 0; i < b.N; i++ { 779 tr.Clear(true) 780 for _, v := range items { 781 tr.ReplaceOrInsert(v) 782 } 783 } 784 }) 785 }
相关文章: