Skip to content

Commit bdbea33

Browse files
plaryou06
andauthored
Fix signed commits (#53)
* optimize iterate over loose N48 node Signed-off-by: you06 <you1474600@gmail.com> * Revert "optimize iterate over loose N48 node" This reverts commit b782292. * fix the reverse iteration bug in this PR Signed-off-by: you06 <you1474600@gmail.com> * Fix node48 reverse bug Signed-off-by: Pavel Larkin <laxkin@gmail.com> --------- Signed-off-by: you06 <you1474600@gmail.com> Signed-off-by: Pavel Larkin <laxkin@gmail.com> Co-authored-by: you06 <you1474600@gmail.com>
1 parent 2cd0118 commit bdbea33

2 files changed

Lines changed: 84 additions & 1 deletion

File tree

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: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,3 +589,86 @@ 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+
606+
for i := 0; i < leafCount; i++ {
607+
key := Key{byte(i)}
608+
tree.Insert(key, key)
609+
}
610+
611+
expectedStats := treeStats{
612+
leafCount: leafCount,
613+
}
614+
615+
switch expectedKind {
616+
case Node4:
617+
expectedStats.node4Count = 1
618+
case Node16:
619+
expectedStats.node16Count = 1
620+
case Node48:
621+
expectedStats.node48Count = 1
622+
case Node256:
623+
expectedStats.node256Count = 1
624+
default:
625+
t.Fatalf("unexpected expectedKind: %v", expectedKind)
626+
}
627+
628+
stats := collectStats(tree.Iterator(TraverseAll))
629+
assert.Equal(t, expectedStats, stats)
630+
631+
stats = collectStats(tree.Iterator(TraverseAll, TraverseReverse))
632+
assert.Equal(t, expectedStats, stats)
633+
}
634+
}
635+
636+
func TestNode48ReverseIteratorMissingIndexZero(t *testing.T) {
637+
t.Parallel()
638+
639+
tree := New()
640+
641+
// Insert 17 keys (0..16) to force the tree to grow to a Node48.
642+
// Node16 holds up to 16 items; the 17th item forces a grow to Node48.
643+
var expected []int
644+
645+
for i := 0; i < 17; i++ {
646+
tree.Insert(Key{byte(i)}, i)
647+
// Pre-build the expected reverse sequence: [16, 15, ..., 0]
648+
expected = append([]int{i}, expected...)
649+
}
650+
651+
// Collect values from the reverse iterator
652+
var actual []int
653+
654+
tree.ForEach(func(node Node) bool {
655+
val, _ := node.Value().(int)
656+
actual = append(actual, val)
657+
658+
return true
659+
}, TraverseReverse)
660+
661+
// This catches the bug (missing 0) AND ensures the sort order is correct.
662+
assert.Lenf(t, actual, len(expected), "Length mismatch. Expected %d items, got %d", len(expected), len(actual))
663+
664+
for i := range expected {
665+
if i >= len(actual) {
666+
break
667+
}
668+
669+
if actual[i] != expected[i] {
670+
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)
671+
break // stop after first error
672+
}
673+
}
674+
}

0 commit comments

Comments
 (0)