@@ -54,12 +54,11 @@ func returnToPool(st *StackTrie) {
54
54
// in order. Once it determines that a subtree will no longer be inserted
55
55
// into, it will hash it and free up the memory it uses.
56
56
type StackTrie struct {
57
- nodeType uint8 // node type (as in branch, ext, leaf)
58
- val []byte // value contained by this node if it's a leaf
59
- key []byte // key chunk covered by this (full|ext) node
60
- keyOffset int // offset of the key chunk inside a full key
61
- children [16 ]* StackTrie // list of children (for fullnodes and exts)
62
- db ethdb.KeyValueWriter // Pointer to the commit db, can be nil
57
+ nodeType uint8 // node type (as in branch, ext, leaf)
58
+ val []byte // value contained by this node if it's a leaf
59
+ key []byte // key chunk covered by this (leaf|ext) node
60
+ children [16 ]* StackTrie // list of children (for branch and exts)
61
+ db ethdb.KeyValueWriter // Pointer to the commit db, can be nil
63
62
}
64
63
65
64
// NewStackTrie allocates and initializes an empty trie.
@@ -90,15 +89,13 @@ func (st *StackTrie) MarshalBinary() (data []byte, err error) {
90
89
w = bufio .NewWriter (& b )
91
90
)
92
91
if err := gob .NewEncoder (w ).Encode (struct {
93
- Nodetype uint8
94
- Val []byte
95
- Key []byte
96
- KeyOffset uint8
92
+ Nodetype uint8
93
+ Val []byte
94
+ Key []byte
97
95
}{
98
96
st .nodeType ,
99
97
st .val ,
100
98
st .key ,
101
- uint8 (st .keyOffset ),
102
99
}); err != nil {
103
100
return nil , err
104
101
}
@@ -126,16 +123,14 @@ func (st *StackTrie) UnmarshalBinary(data []byte) error {
126
123
127
124
func (st * StackTrie ) unmarshalBinary (r io.Reader ) error {
128
125
var dec struct {
129
- Nodetype uint8
130
- Val []byte
131
- Key []byte
132
- KeyOffset uint8
126
+ Nodetype uint8
127
+ Val []byte
128
+ Key []byte
133
129
}
134
130
gob .NewDecoder (r ).Decode (& dec )
135
131
st .nodeType = dec .Nodetype
136
132
st .val = dec .Val
137
133
st .key = dec .Key
138
- st .keyOffset = int (dec .KeyOffset )
139
134
140
135
var hasChild = make ([]byte , 1 )
141
136
for i := range st .children {
@@ -160,20 +155,18 @@ func (st *StackTrie) setDb(db ethdb.KeyValueWriter) {
160
155
}
161
156
}
162
157
163
- func newLeaf (ko int , key , val []byte , db ethdb.KeyValueWriter ) * StackTrie {
158
+ func newLeaf (key , val []byte , db ethdb.KeyValueWriter ) * StackTrie {
164
159
st := stackTrieFromPool (db )
165
160
st .nodeType = leafNode
166
- st .keyOffset = ko
167
- st .key = append (st .key , key [ko :]... )
161
+ st .key = append (st .key , key ... )
168
162
st .val = val
169
163
return st
170
164
}
171
165
172
- func newExt (ko int , key []byte , child * StackTrie , db ethdb.KeyValueWriter ) * StackTrie {
166
+ func newExt (key []byte , child * StackTrie , db ethdb.KeyValueWriter ) * StackTrie {
173
167
st := stackTrieFromPool (db )
174
168
st .nodeType = extNode
175
- st .keyOffset = ko
176
- st .key = append (st .key , key [ko :]... )
169
+ st .key = append (st .key , key ... )
177
170
st .children [0 ] = child
178
171
return st
179
172
}
@@ -211,25 +204,26 @@ func (st *StackTrie) Reset() {
211
204
st .children [i ] = nil
212
205
}
213
206
st .nodeType = emptyNode
214
- st .keyOffset = 0
215
207
}
216
208
217
209
// Helper function that, given a full key, determines the index
218
210
// at which the chunk pointed by st.keyOffset is different from
219
211
// the same chunk in the full key.
220
212
func (st * StackTrie ) getDiffIndex (key []byte ) int {
221
- diffindex := 0
222
- for ; diffindex < len (st .key ) && st .key [diffindex ] == key [st .keyOffset + diffindex ]; diffindex ++ {
213
+ for idx , nibble := range st .key {
214
+ if nibble != key [idx ] {
215
+ return idx
216
+ }
223
217
}
224
- return diffindex
218
+ return len ( st . key )
225
219
}
226
220
227
221
// Helper function to that inserts a (key, value) pair into
228
222
// the trie.
229
223
func (st * StackTrie ) insert (key , value []byte ) {
230
224
switch st .nodeType {
231
225
case branchNode : /* Branch */
232
- idx := int (key [st . keyOffset ])
226
+ idx := int (key [0 ])
233
227
// Unresolve elder siblings
234
228
for i := idx - 1 ; i >= 0 ; i -- {
235
229
if st .children [i ] != nil {
@@ -241,10 +235,10 @@ func (st *StackTrie) insert(key, value []byte) {
241
235
}
242
236
// Add new child
243
237
if st .children [idx ] == nil {
244
- st .children [idx ] = stackTrieFromPool (st .db )
245
- st .children [idx ].keyOffset = st .keyOffset + 1
238
+ st .children [idx ] = newLeaf (key [1 :], value , st .db )
239
+ } else {
240
+ st .children [idx ].insert (key [1 :], value )
246
241
}
247
- st .children [idx ].insert (key , value )
248
242
case extNode : /* Ext */
249
243
// Compare both key chunks and see where they differ
250
244
diffidx := st .getDiffIndex (key )
@@ -257,7 +251,7 @@ func (st *StackTrie) insert(key, value []byte) {
257
251
if diffidx == len (st .key ) {
258
252
// Ext key and key segment are identical, recurse into
259
253
// the child node.
260
- st .children [0 ].insert (key , value )
254
+ st .children [0 ].insert (key [ diffidx :] , value )
261
255
return
262
256
}
263
257
// Save the original part. Depending if the break is
@@ -266,7 +260,7 @@ func (st *StackTrie) insert(key, value []byte) {
266
260
// node directly.
267
261
var n * StackTrie
268
262
if diffidx < len (st .key )- 1 {
269
- n = newExt (diffidx + 1 , st .key , st .children [0 ], st .db )
263
+ n = newExt (st .key [ diffidx + 1 :] , st .children [0 ], st .db )
270
264
} else {
271
265
// Break on the last byte, no need to insert
272
266
// an extension node: reuse the current node
@@ -288,15 +282,14 @@ func (st *StackTrie) insert(key, value []byte) {
288
282
// node.
289
283
st .children [0 ] = stackTrieFromPool (st .db )
290
284
st .children [0 ].nodeType = branchNode
291
- st .children [0 ].keyOffset = st .keyOffset + diffidx
292
285
p = st .children [0 ]
293
286
}
294
287
// Create a leaf for the inserted part
295
- o := newLeaf (st . keyOffset + diffidx + 1 , key , value , st .db )
288
+ o := newLeaf (key [ diffidx + 1 :] , value , st .db )
296
289
297
290
// Insert both child leaves where they belong:
298
291
origIdx := st .key [diffidx ]
299
- newIdx := key [diffidx + st . keyOffset ]
292
+ newIdx := key [diffidx ]
300
293
p .children [origIdx ] = n
301
294
p .children [newIdx ] = o
302
295
st .key = st .key [:diffidx ]
@@ -330,7 +323,6 @@ func (st *StackTrie) insert(key, value []byte) {
330
323
st .nodeType = extNode
331
324
st .children [0 ] = NewStackTrie (st .db )
332
325
st .children [0 ].nodeType = branchNode
333
- st .children [0 ].keyOffset = st .keyOffset + diffidx
334
326
p = st .children [0 ]
335
327
}
336
328
@@ -339,19 +331,19 @@ func (st *StackTrie) insert(key, value []byte) {
339
331
// The child leave will be hashed directly in order to
340
332
// free up some memory.
341
333
origIdx := st .key [diffidx ]
342
- p .children [origIdx ] = newLeaf (diffidx + 1 , st .key , st .val , st .db )
334
+ p .children [origIdx ] = newLeaf (st .key [ diffidx + 1 :] , st .val , st .db )
343
335
p .children [origIdx ].hash ()
344
336
345
- newIdx := key [diffidx + st . keyOffset ]
346
- p .children [newIdx ] = newLeaf (p . keyOffset + 1 , key , value , st .db )
337
+ newIdx := key [diffidx ]
338
+ p .children [newIdx ] = newLeaf (key [ diffidx + 1 :] , value , st .db )
347
339
348
340
// Finally, cut off the key part that has been passed
349
341
// over to the children.
350
342
st .key = st .key [:diffidx ]
351
343
st .val = nil
352
344
case emptyNode : /* Empty */
353
345
st .nodeType = leafNode
354
- st .key = key [ st . keyOffset :]
346
+ st .key = key
355
347
st .val = value
356
348
case hashedNode :
357
349
panic ("trying to insert into hash" )
0 commit comments