Skip to content

Commit 56069ef

Browse files
committed
Merge leaf and branch header encoding
1 parent c2af35d commit 56069ef

File tree

3 files changed

+63
-134
lines changed

3 files changed

+63
-134
lines changed

internal/trie/node/decode.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ func Decode(reader io.Reader) (n *Node, err error) {
3636

3737
nodeTypeHeaderByte := header >> 6
3838
switch nodeTypeHeaderByte {
39-
case leafHeaderByte:
39+
case leafHeader:
4040
n, err = decodeLeaf(reader, header)
4141
if err != nil {
4242
return nil, fmt.Errorf("cannot decode leaf: %w", err)
4343
}
4444
return n, nil
45-
case branchHeaderByte, branchWithValueHeaderByte:
45+
case branchHeader, branchWithValueHeader:
4646
n, err = decodeBranch(reader, header)
4747
if err != nil {
4848
return nil, fmt.Errorf("cannot decode branch: %w", err)
@@ -78,7 +78,7 @@ func decodeBranch(reader io.Reader, header byte) (node *Node, err error) {
7878
sd := scale.NewDecoder(reader)
7979

8080
nodeType := header >> 6
81-
if nodeType == branchWithValueHeaderByte {
81+
if nodeType == branchWithValueHeader {
8282
var value []byte
8383
// branch w/ value
8484
err := sd.Decode(&value)
@@ -103,7 +103,7 @@ func decodeBranch(reader io.Reader, header byte) (node *Node, err error) {
103103
// Handle inlined leaf nodes.
104104
const hashLength = 32
105105
nodeTypeHeaderByte := hash[0] >> 6
106-
if nodeTypeHeaderByte == leafHeaderByte && len(hash) < hashLength {
106+
if nodeTypeHeaderByte == leafHeader && len(hash) < hashLength {
107107
leaf, err := decodeLeaf(bytes.NewReader(hash[1:]), hash[0])
108108
if err != nil {
109109
return nil, fmt.Errorf("%w: at index %d: %s",

internal/trie/node/header.go

Lines changed: 22 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,75 +8,42 @@ import (
88
)
99

1010
const (
11-
leafHeaderByte byte = 0x1
12-
branchHeaderByte byte = 2
13-
branchWithValueHeaderByte byte = 3
14-
keyLenOffset = 0x3f
15-
nodeHeaderShift = 6
11+
leafHeader byte = 1 // 01
12+
branchHeader byte = 2 // 10
13+
branchWithValueHeader byte = 3 // 11
1614
)
1715

18-
func encodeHeader(node *Node, writer io.Writer) (err error) {
19-
switch node.Type() {
20-
case Leaf:
21-
return encodeLeafHeader(node, writer)
22-
case Branch:
23-
return encodeBranchHeader(node, writer)
24-
default:
25-
panic("header encoding not implemented")
26-
}
27-
}
16+
const (
17+
keyLenOffset = 0x3f
18+
nodeHeaderShift = 6
19+
)
2820

29-
// encodeBranchHeader writes the encoded header for the branch.
30-
func encodeBranchHeader(branch *Node, writer io.Writer) (err error) {
21+
// encodeHeader writes the encoded header for the node.
22+
func encodeHeader(node *Node, writer io.Writer) (err error) {
3123
var header byte
32-
if branch.Value == nil {
33-
header = branchHeaderByte << nodeHeaderShift
34-
} else {
35-
header = branchWithValueHeaderByte << nodeHeaderShift
36-
}
37-
38-
if len(branch.Key) >= keyLenOffset {
39-
header = header | keyLenOffset
40-
_, err = writer.Write([]byte{header})
41-
if err != nil {
42-
return err
43-
}
44-
45-
err = encodeKeyLength(len(branch.Key), writer)
46-
if err != nil {
47-
return err
48-
}
49-
} else {
50-
header = header | byte(len(branch.Key))
51-
_, err = writer.Write([]byte{header})
52-
if err != nil {
53-
return err
24+
if node.Type() == Leaf {
25+
header = leafHeader
26+
} else { // branch
27+
if node.Value == nil {
28+
header = branchHeader
29+
} else {
30+
header = branchWithValueHeader
5431
}
5532
}
33+
header <<= nodeHeaderShift
5634

57-
return nil
58-
}
59-
60-
// encodeLeafHeader writes the encoded header for the leaf.
61-
func encodeLeafHeader(leaf *Node, writer io.Writer) (err error) {
62-
header := leafHeaderByte << nodeHeaderShift
63-
64-
if len(leaf.Key) < 63 {
65-
header |= byte(len(leaf.Key))
35+
if len(node.Key) < keyLenOffset {
36+
header |= byte(len(node.Key))
6637
_, err = writer.Write([]byte{header})
6738
return err
6839
}
6940

70-
header |= keyLenOffset
41+
header = header | keyLenOffset
7142
_, err = writer.Write([]byte{header})
7243
if err != nil {
7344
return err
7445
}
7546

76-
err = encodeKeyLength(len(leaf.Key), writer)
77-
if err != nil {
78-
return err
79-
}
80-
81-
return nil
47+
err = encodeKeyLength(len(node.Key), writer)
48+
return err
8249
}

internal/trie/node/header_test.go

Lines changed: 37 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10,50 +10,50 @@ import (
1010
"github.com/stretchr/testify/assert"
1111
)
1212

13-
func Test_encodeBranchHeader(t *testing.T) {
13+
func Test_encodeHeader(t *testing.T) {
1414
testCases := map[string]struct {
15-
branch *Node
15+
node *Node
1616
writes []writeCall
1717
errWrapped error
1818
errMessage string
1919
}{
20-
"no key": {
21-
branch: &Node{
20+
"branch with no key": {
21+
node: &Node{
2222
Children: make([]*Node, ChildrenCapacity),
2323
},
2424
writes: []writeCall{
2525
{written: []byte{0x80}},
2626
},
2727
},
28-
"with value": {
29-
branch: &Node{
28+
"branch with value": {
29+
node: &Node{
3030
Value: []byte{},
3131
Children: make([]*Node, ChildrenCapacity),
3232
},
3333
writes: []writeCall{
3434
{written: []byte{0xc0}},
3535
},
3636
},
37-
"key of length 30": {
38-
branch: &Node{
37+
"branch with key of length 30": {
38+
node: &Node{
3939
Key: make([]byte, 30),
4040
Children: make([]*Node, ChildrenCapacity),
4141
},
4242
writes: []writeCall{
4343
{written: []byte{0x9e}},
4444
},
4545
},
46-
"key of length 62": {
47-
branch: &Node{
46+
"branch with key of length 62": {
47+
node: &Node{
4848
Key: make([]byte, 62),
4949
Children: make([]*Node, ChildrenCapacity),
5050
},
5151
writes: []writeCall{
5252
{written: []byte{0xbe}},
5353
},
5454
},
55-
"key of length 63": {
56-
branch: &Node{
55+
"branch with key of length 63": {
56+
node: &Node{
5757
Key: make([]byte, 63),
5858
Children: make([]*Node, ChildrenCapacity),
5959
},
@@ -62,8 +62,8 @@ func Test_encodeBranchHeader(t *testing.T) {
6262
{written: []byte{0x0}},
6363
},
6464
},
65-
"key of length 64": {
66-
branch: &Node{
65+
"branch with key of length 64": {
66+
node: &Node{
6767
Key: make([]byte, 64),
6868
Children: make([]*Node, ChildrenCapacity),
6969
},
@@ -72,8 +72,8 @@ func Test_encodeBranchHeader(t *testing.T) {
7272
{written: []byte{0x1}},
7373
},
7474
},
75-
"key too big": {
76-
branch: &Node{
75+
"branch with key too big": {
76+
node: &Node{
7777
Key: make([]byte, 65535+63),
7878
Children: make([]*Node, ChildrenCapacity),
7979
},
@@ -83,8 +83,8 @@ func Test_encodeBranchHeader(t *testing.T) {
8383
errWrapped: ErrPartialKeyTooBig,
8484
errMessage: "partial key length cannot be larger than or equal to 2^16: 65535",
8585
},
86-
"small key length write error": {
87-
branch: &Node{
86+
"branch with small key length write error": {
87+
node: &Node{
8888
Children: make([]*Node, ChildrenCapacity),
8989
},
9090
writes: []writeCall{
@@ -96,8 +96,8 @@ func Test_encodeBranchHeader(t *testing.T) {
9696
errWrapped: errTest,
9797
errMessage: "test error",
9898
},
99-
"long key length write error": {
100-
branch: &Node{
99+
"branch with long key length write error": {
100+
node: &Node{
101101
Key: make([]byte, 64),
102102
Children: make([]*Node, ChildrenCapacity),
103103
},
@@ -110,60 +110,22 @@ func Test_encodeBranchHeader(t *testing.T) {
110110
errWrapped: errTest,
111111
errMessage: "test error",
112112
},
113-
}
114-
115-
for name, testCase := range testCases {
116-
testCase := testCase
117-
t.Run(name, func(t *testing.T) {
118-
t.Parallel()
119-
ctrl := gomock.NewController(t)
120-
121-
writer := NewMockWriter(ctrl)
122-
var previousCall *gomock.Call
123-
for _, write := range testCase.writes {
124-
call := writer.EXPECT().
125-
Write(write.written).
126-
Return(write.n, write.err)
127-
128-
if previousCall != nil {
129-
call.After(previousCall)
130-
}
131-
previousCall = call
132-
}
133-
134-
err := encodeBranchHeader(testCase.branch, writer)
135-
136-
assert.ErrorIs(t, err, testCase.errWrapped)
137-
if testCase.errWrapped != nil {
138-
assert.EqualError(t, err, testCase.errMessage)
139-
}
140-
})
141-
}
142-
}
143-
144-
func Test_encodeLeafHeader(t *testing.T) {
145-
testCases := map[string]struct {
146-
leaf *Node
147-
writes []writeCall
148-
errWrapped error
149-
errMessage string
150-
}{
151-
"no key": {
152-
leaf: &Node{},
113+
"leaf with no key": {
114+
node: &Node{},
153115
writes: []writeCall{
154116
{written: []byte{0x40}},
155117
},
156118
},
157-
"key of length 30": {
158-
leaf: &Node{
119+
"leaf with key of length 30": {
120+
node: &Node{
159121
Key: make([]byte, 30),
160122
},
161123
writes: []writeCall{
162124
{written: []byte{0x5e}},
163125
},
164126
},
165-
"short key write error": {
166-
leaf: &Node{
127+
"leaf with short key write error": {
128+
node: &Node{
167129
Key: make([]byte, 30),
168130
},
169131
writes: []writeCall{
@@ -175,34 +137,34 @@ func Test_encodeLeafHeader(t *testing.T) {
175137
errWrapped: errTest,
176138
errMessage: errTest.Error(),
177139
},
178-
"key of length 62": {
179-
leaf: &Node{
140+
"leaf with key of length 62": {
141+
node: &Node{
180142
Key: make([]byte, 62),
181143
},
182144
writes: []writeCall{
183145
{written: []byte{0x7e}},
184146
},
185147
},
186-
"key of length 63": {
187-
leaf: &Node{
148+
"leaf with key of length 63": {
149+
node: &Node{
188150
Key: make([]byte, 63),
189151
},
190152
writes: []writeCall{
191153
{written: []byte{0x7f}},
192154
{written: []byte{0x0}},
193155
},
194156
},
195-
"key of length 64": {
196-
leaf: &Node{
157+
"leaf with key of length 64": {
158+
node: &Node{
197159
Key: make([]byte, 64),
198160
},
199161
writes: []writeCall{
200162
{written: []byte{0x7f}},
201163
{written: []byte{0x1}},
202164
},
203165
},
204-
"long key first byte write error": {
205-
leaf: &Node{
166+
"leaf with long key first byte write error": {
167+
node: &Node{
206168
Key: make([]byte, 63),
207169
},
208170
writes: []writeCall{
@@ -214,8 +176,8 @@ func Test_encodeLeafHeader(t *testing.T) {
214176
errWrapped: errTest,
215177
errMessage: errTest.Error(),
216178
},
217-
"key too big": {
218-
leaf: &Node{
179+
"leaf with key too big": {
180+
node: &Node{
219181
Key: make([]byte, 65535+63),
220182
},
221183
writes: []writeCall{
@@ -245,7 +207,7 @@ func Test_encodeLeafHeader(t *testing.T) {
245207
previousCall = call
246208
}
247209

248-
err := encodeLeafHeader(testCase.leaf, writer)
210+
err := encodeHeader(testCase.node, writer)
249211

250212
assert.ErrorIs(t, err, testCase.errWrapped)
251213
if testCase.errWrapped != nil {

0 commit comments

Comments
 (0)