Skip to content

Commit 1441e72

Browse files
committed
fix the reverse iteration bug in this PR
Signed-off-by: you06 <you1474600@gmail.com>
1 parent 078831f commit 1441e72

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

tree_traversal.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (ctx *traverse48Context) ascTraversal() (int, bool) {
118118

119119
// descTraversal traverses the children in descending order.
120120
func (ctx *traverse48Context) descTraversal() (int, bool) {
121-
for ; ctx.curKeyIdx > 0; ctx.curKeyIdx-- {
121+
for ; ctx.curKeyIdx >= 0; ctx.curKeyIdx-- {
122122
if ctx.n48.hasChild(ctx.curKeyIdx) {
123123
ctx.curKeyCh = ctx.n48.keys[ctx.curKeyIdx]
124124
ctx.curKeyIdx--

tree_traversal_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,3 +589,80 @@ func TestIteratorEmptyTreeBehavior(t *testing.T) {
589589
assert.Nil(t, n)
590590
assert.Equal(t, ErrNoMoreNodes, err)
591591
}
592+
593+
func TestIteratorStatsWithReverse(t *testing.T) {
594+
t.Parallel()
595+
596+
// node4Max + 1, node16Max + 1, node48Max + 1 grow the tree to the next node kind.
597+
testCases := map[int]Kind{
598+
node4Max: Node4,
599+
node4Max + 1: Node16,
600+
node16Max + 1: Node48,
601+
node48Max + 1: Node256,
602+
}
603+
for leafCount, expectedKind := range testCases {
604+
tree := New()
605+
for i := 0; i < leafCount; i++ {
606+
key := Key{byte(i)}
607+
tree.Insert(key, key)
608+
}
609+
610+
expectedStats := treeStats{
611+
leafCount: leafCount,
612+
}
613+
switch expectedKind {
614+
case Node4:
615+
expectedStats.node4Count = 1
616+
case Node16:
617+
expectedStats.node16Count = 1
618+
case Node48:
619+
expectedStats.node48Count = 1
620+
case Node256:
621+
expectedStats.node256Count = 1
622+
default:
623+
t.Fatalf("unexpected expectedKind: %v", expectedKind)
624+
}
625+
626+
stats := collectStats(tree.Iterator(TraverseAll))
627+
assert.Equal(t, expectedStats, stats)
628+
629+
stats = collectStats(tree.Iterator(TraverseAll, TraverseReverse))
630+
assert.Equal(t, expectedStats, stats)
631+
}
632+
}
633+
634+
func TestNode48ReverseIteratorMissingIndexZero(t *testing.T) {
635+
t.Parallel()
636+
637+
tree := New()
638+
639+
// Insert 17 keys (0..16) to force the tree to grow to a Node48.
640+
// Node16 holds up to 16 items; the 17th item forces a grow to Node48.
641+
var expected []int
642+
for i := 0; i < 17; i++ {
643+
tree.Insert(Key{byte(i)}, i)
644+
// Pre-build the expected reverse sequence: [16, 15, ..., 0]
645+
expected = append([]int{i}, expected...)
646+
}
647+
648+
// Collect values from the reverse iterator
649+
var actual []int
650+
tree.ForEach(func(node Node) bool {
651+
val, _ := node.Value().(int)
652+
actual = append(actual, val)
653+
return true
654+
}, TraverseReverse)
655+
656+
// This catches the bug (missing 0) AND ensures the sort order is correct.
657+
assert.Lenf(t, actual, len(expected), "Length mismatch. Expected %d items, got %d", len(expected), len(actual))
658+
659+
for i := range expected {
660+
if i >= len(actual) {
661+
break
662+
}
663+
if actual[i] != expected[i] {
664+
assert.Equal(t, expected[i], actual[i], "Mismatch at index %d. Expected value %d, got %d. \nFull Actual: %v", i, expected[i], actual[i], actual)
665+
break // stop after first error
666+
}
667+
}
668+
}

0 commit comments

Comments
 (0)