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 }
btree_test.go

相关文章:

  • 2021-09-29
  • 2021-10-17
  • 2021-11-22
  • 2022-12-23
  • 2021-12-29
  • 2022-12-23
  • 2021-11-02
  • 2021-12-24
猜你喜欢
  • 2021-04-29
  • 2022-12-23
  • 2022-12-23
  • 2021-11-29
  • 2021-11-03
  • 2021-12-08
  • 2021-12-12
相关资源
相似解决方案