Skip to content

Commit 4030bb1

Browse files
nolouchgconnell
authored andcommitted
Improve the iterate seek to O(logN) (#25)
* improve the iterate seek to O(logN) * add benchmark
1 parent e89373f commit 4030bb1

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

Diff for: btree.go

+15-6
Original file line numberDiff line numberDiff line change
@@ -500,13 +500,14 @@ const (
500500
// thus creating a "greaterOrEqual" or "lessThanEqual" rather than just a
501501
// "greaterThan" or "lessThan" queries.
502502
func (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit bool, iter ItemIterator) (bool, bool) {
503-
var ok bool
503+
var ok, found bool
504+
var index int
504505
switch dir {
505506
case ascend:
506-
for i := 0; i < len(n.items); i++ {
507-
if start != nil && n.items[i].Less(start) {
508-
continue
509-
}
507+
if start != nil {
508+
index, _ = n.items.find(start)
509+
}
510+
for i := index; i < len(n.items); i++ {
510511
if len(n.children) > 0 {
511512
if hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok {
512513
return hit, false
@@ -530,7 +531,15 @@ func (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit b
530531
}
531532
}
532533
case descend:
533-
for i := len(n.items) - 1; i >= 0; i-- {
534+
if start != nil {
535+
index, found = n.items.find(start)
536+
if !found {
537+
index = index - 1
538+
}
539+
} else {
540+
index = len(n.items) - 1
541+
}
542+
for i := index; i >= 0; i-- {
534543
if start != nil && !n.items[i].Less(start) {
535544
if !includeStart || hit || start.Less(n.items[i]) {
536545
continue

Diff for: btree_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,21 @@ func BenchmarkInsert(b *testing.B) {
361361
}
362362
}
363363

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+
364379
func BenchmarkDeleteInsert(b *testing.B) {
365380
b.StopTimer()
366381
insertP := perm(benchmarkTreeSize)

0 commit comments

Comments
 (0)