Skip to content

Commit

Permalink
fix: handle leaf encoding correctly (#11)
Browse files Browse the repository at this point in the history
Leaf nodes should not be encoded with children
  • Loading branch information
kevmo314 authored Dec 31, 2023
1 parent 6fa3ab0 commit 226a914
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 15 deletions.
22 changes: 13 additions & 9 deletions pkg/btree/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ func (n *Node) WriteTo(w io.Writer) (int64, error) {
return 0, err
}
}
for _, child := range n.Children {
if err := encoding.WriteUint64(w, child); err != nil {
return 0, err
if !n.Leaf {
for _, child := range n.Children {
if err := encoding.WriteUint64(w, child); err != nil {
return 0, err
}
}
}
return int64(1 + 16*len(n.Keys) + 8*len(n.Children)), nil
Expand All @@ -68,7 +70,6 @@ func (n *Node) ReadFrom(r io.Reader) (int64, error) {
n.Leaf = size&(1<<7) != 0
size = size & (1<<7 - 1)
n.Keys = make([]DataPointer, size)
n.Children = make([]uint64, size+1)
for i := 0; i < int(size); i++ {
recordOffset, err := encoding.ReadUint64(r)
if err != nil {
Expand All @@ -88,12 +89,15 @@ func (n *Node) ReadFrom(r io.Reader) (int64, error) {
Length: length,
}
}
for i := 0; i <= int(size); i++ {
child, err := encoding.ReadUint64(r)
if err != nil {
return 0, err
if !n.Leaf {
n.Children = make([]uint64, size+1)
for i := 0; i <= int(size); i++ {
child, err := encoding.ReadUint64(r)
if err != nil {
return 0, err
}
n.Children[i] = child
}
n.Children[i] = child
}
return 1 + 16*int64(size) + 8*int64(size+1), nil
}
Expand Down
92 changes: 86 additions & 6 deletions pkg/btree/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,32 @@ import (
)

func TestNode(t *testing.T) {
t.Run("encode", func(t *testing.T) {
t.Run("encode leaf", func(t *testing.T) {
n := &Node{
Keys: []DataPointer{
{
RecordOffset: 0,
FieldOffset: 0,
Length: 5,
},
{
RecordOffset: 0,
FieldOffset: 5,
Length: 5,
},
},
Leaf: true,
}
buf := &bytes.Buffer{}
if _, err := n.WriteTo(buf); err != nil {
t.Fatal(err)
}
if buf.Len() != 1+16*2 {
t.Fatalf("expected buffer length to be 1+16*2+8*3, got %d", buf.Len())
}
})

t.Run("encode leaf ignores children", func(t *testing.T) {
n := &Node{
Keys: []DataPointer{
{
Expand All @@ -21,8 +46,34 @@ func TestNode(t *testing.T) {
Length: 5,
},
},
Children: []uint64{0, 1, 2},
Leaf: true,
Children: []uint64{1, 2, 3},
}
buf := &bytes.Buffer{}
if _, err := n.WriteTo(buf); err != nil {
t.Fatal(err)
}
if buf.Len() != 1+16*2 {
t.Fatalf("expected buffer length to be 1+16*2+8*3, got %d", buf.Len())
}
})

t.Run("encode non-leaf", func(t *testing.T) {
n := &Node{
Keys: []DataPointer{
{
RecordOffset: 0,
FieldOffset: 0,
Length: 5,
},
{
RecordOffset: 0,
FieldOffset: 5,
Length: 5,
},
},
Leaf: false,
Children: []uint64{1, 2, 3},
}
buf := &bytes.Buffer{}
if _, err := n.WriteTo(buf); err != nil {
Expand All @@ -33,7 +84,7 @@ func TestNode(t *testing.T) {
}
})

t.Run("decode", func(t *testing.T) {
t.Run("decode leaf", func(t *testing.T) {
n := &Node{
Keys: []DataPointer{
{
Expand All @@ -47,8 +98,37 @@ func TestNode(t *testing.T) {
Length: 5,
},
},
Children: []uint64{0, 1, 2},
Leaf: true,
Leaf: true,
}
buf := &bytes.Buffer{}
if _, err := n.WriteTo(buf); err != nil {
t.Fatal(err)
}
m := &Node{}
if _, err := m.ReadFrom(buf); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(n, m) {
t.Fatalf("expected decoded node to be equal to original node, got %#v want %#v", m, n)
}
})

t.Run("decode non-leaf", func(t *testing.T) {
n := &Node{
Keys: []DataPointer{
{
RecordOffset: 0,
FieldOffset: 0,
Length: 5,
},
{
RecordOffset: 0,
FieldOffset: 5,
Length: 5,
},
},
Leaf: false,
Children: []uint64{1, 2, 3},
}
buf := &bytes.Buffer{}
if _, err := n.WriteTo(buf); err != nil {
Expand All @@ -59,7 +139,7 @@ func TestNode(t *testing.T) {
t.Fatal(err)
}
if !reflect.DeepEqual(n, m) {
t.Fatalf("expected decoded node to be equal to original node")
t.Fatalf("expected decoded node to be equal to original node, got %#v want %#v", m, n)
}
})
}
Expand Down

0 comments on commit 226a914

Please sign in to comment.