@@ -58,13 +58,12 @@ func returnToPool(st *StackTrie) {
58
58
// in order. Once it determines that a subtree will no longer be inserted
59
59
// into, it will hash it and free up the memory it uses.
60
60
type StackTrie struct {
61
- owner common.Hash // the owner of the trie
62
- nodeType uint8 // node type (as in branch, ext, leaf)
63
- val []byte // value contained by this node if it's a leaf
64
- key []byte // key chunk covered by this (full|ext) node
65
- keyOffset int // offset of the key chunk inside a full key
66
- children [16 ]* StackTrie // list of children (for fullnodes and exts)
67
- writeFn NodeWriteFunc // function for commiting nodes, can be nil
61
+ owner common.Hash // the owner of the trie
62
+ nodeType uint8 // node type (as in branch, ext, leaf)
63
+ val []byte // value contained by this node if it's a leaf
64
+ key []byte // key chunk covered by this (full|ext) node
65
+ children [16 ]* StackTrie // list of children (for fullnodes and exts)
66
+ writeFn NodeWriteFunc // function for commiting nodes, can be nil
68
67
}
69
68
70
69
// NewStackTrie allocates and initializes an empty trie.
@@ -105,17 +104,15 @@ func (st *StackTrie) MarshalBinary() (data []byte, err error) {
105
104
w = bufio .NewWriter (& b )
106
105
)
107
106
if err := gob .NewEncoder (w ).Encode (struct {
108
- Owner common.Hash
109
- NodeType uint8
110
- Val []byte
111
- Key []byte
112
- KeyOffset uint8
107
+ Owner common.Hash
108
+ NodeType uint8
109
+ Val []byte
110
+ Key []byte
113
111
}{
114
112
st .owner ,
115
113
st .nodeType ,
116
114
st .val ,
117
115
st .key ,
118
- uint8 (st .keyOffset ),
119
116
}); err != nil {
120
117
return nil , err
121
118
}
@@ -143,18 +140,16 @@ func (st *StackTrie) UnmarshalBinary(data []byte) error {
143
140
144
141
func (st * StackTrie ) unmarshalBinary (r io.Reader ) error {
145
142
var dec struct {
146
- Owner common.Hash
147
- NodeType uint8
148
- Val []byte
149
- Key []byte
150
- KeyOffset uint8
143
+ Owner common.Hash
144
+ NodeType uint8
145
+ Val []byte
146
+ Key []byte
151
147
}
152
148
gob .NewDecoder (r ).Decode (& dec )
153
149
st .owner = dec .Owner
154
150
st .nodeType = dec .NodeType
155
151
st .val = dec .Val
156
152
st .key = dec .Key
157
- st .keyOffset = int (dec .KeyOffset )
158
153
159
154
var hasChild = make ([]byte , 1 )
160
155
for i := range st .children {
@@ -179,20 +174,18 @@ func (st *StackTrie) setWriteFunc(writeFn NodeWriteFunc) {
179
174
}
180
175
}
181
176
182
- func newLeaf (owner common.Hash , ko int , key , val []byte , writeFn NodeWriteFunc ) * StackTrie {
177
+ func newLeaf (owner common.Hash , key , val []byte , writeFn NodeWriteFunc ) * StackTrie {
183
178
st := stackTrieFromPool (writeFn , owner )
184
179
st .nodeType = leafNode
185
- st .keyOffset = ko
186
- st .key = append (st .key , key [ko :]... )
180
+ st .key = append (st .key , key ... )
187
181
st .val = val
188
182
return st
189
183
}
190
184
191
- func newExt (owner common.Hash , ko int , key []byte , child * StackTrie , writeFn NodeWriteFunc ) * StackTrie {
185
+ func newExt (owner common.Hash , key []byte , child * StackTrie , writeFn NodeWriteFunc ) * StackTrie {
192
186
st := stackTrieFromPool (writeFn , owner )
193
187
st .nodeType = extNode
194
- st .keyOffset = ko
195
- st .key = append (st .key , key [ko :]... )
188
+ st .key = append (st .key , key ... )
196
189
st .children [0 ] = child
197
190
return st
198
191
}
@@ -231,25 +224,26 @@ func (st *StackTrie) Reset() {
231
224
st .children [i ] = nil
232
225
}
233
226
st .nodeType = emptyNode
234
- st .keyOffset = 0
235
227
}
236
228
237
229
// Helper function that, given a full key, determines the index
238
230
// at which the chunk pointed by st.keyOffset is different from
239
231
// the same chunk in the full key.
240
232
func (st * StackTrie ) getDiffIndex (key []byte ) int {
241
- diffindex := 0
242
- for ; diffindex < len (st .key ) && st .key [diffindex ] == key [st .keyOffset + diffindex ]; diffindex ++ {
233
+ for idx , nibble := range st .key {
234
+ if nibble != key [idx ] {
235
+ return idx
236
+ }
243
237
}
244
- return diffindex
238
+ return len ( st . key )
245
239
}
246
240
247
241
// Helper function to that inserts a (key, value) pair into
248
242
// the trie. Adding the prefix when inserting too.
249
- func (st * StackTrie ) insert (key , value [] byte , prefix []byte ) {
243
+ func (st * StackTrie ) insert (key , value , prefix []byte ) {
250
244
switch st .nodeType {
251
245
case branchNode : /* Branch */
252
- idx := int (key [st . keyOffset ])
246
+ idx := int (key [0 ])
253
247
// Unresolve elder siblings
254
248
for i := idx - 1 ; i >= 0 ; i -- {
255
249
if st .children [i ] != nil {
@@ -261,10 +255,11 @@ func (st *StackTrie) insert(key, value []byte, prefix []byte) {
261
255
}
262
256
// Add new child
263
257
if st .children [idx ] == nil {
264
- st .children [idx ] = stackTrieFromPool (st .writeFn , st .owner )
265
- st .children [idx ].keyOffset = st .keyOffset + 1
258
+ st .children [idx ] = newLeaf (st .owner , key [1 :], value , st .writeFn )
259
+ } else {
260
+ st .children [idx ].insert (key [1 :], value , append (prefix , key [0 ]))
266
261
}
267
- st . children [ idx ]. insert ( key , value , append ( prefix , key [ st . keyOffset ]))
262
+
268
263
case extNode : /* Ext */
269
264
// Compare both key chunks and see where they differ
270
265
diffidx := st .getDiffIndex (key )
@@ -277,7 +272,7 @@ func (st *StackTrie) insert(key, value []byte, prefix []byte) {
277
272
if diffidx == len (st .key ) {
278
273
// Ext key and key segment are identical, recurse into
279
274
// the child node.
280
- st .children [0 ].insert (key , value , append (prefix , key [:diffidx ]... ))
275
+ st .children [0 ].insert (key [ diffidx :] , value , append (prefix , key [:diffidx ]... ))
281
276
return
282
277
}
283
278
// Save the original part. Depending if the break is
@@ -289,7 +284,7 @@ func (st *StackTrie) insert(key, value []byte, prefix []byte) {
289
284
// Break on the non-last byte, insert an intermediate
290
285
// extension. The path prefix of the newly-inserted
291
286
// extension should also contain the different byte.
292
- n = newExt (st .owner , diffidx + 1 , st .key , st .children [0 ], st .writeFn )
287
+ n = newExt (st .owner , st .key [ diffidx + 1 :] , st .children [0 ], st .writeFn )
293
288
n .hash (append (prefix , st .key [:diffidx + 1 ]... ))
294
289
} else {
295
290
// an extension node: reuse the current node.
@@ -313,15 +308,14 @@ func (st *StackTrie) insert(key, value []byte, prefix []byte) {
313
308
// node.
314
309
st .children [0 ] = stackTrieFromPool (st .writeFn , st .owner )
315
310
st .children [0 ].nodeType = branchNode
316
- st .children [0 ].keyOffset = st .keyOffset + diffidx
317
311
p = st .children [0 ]
318
312
}
319
313
// Create a leaf for the inserted part
320
- o := newLeaf (st .owner , st . keyOffset + diffidx + 1 , key , value , st .writeFn )
314
+ o := newLeaf (st .owner , key [ diffidx + 1 :] , value , st .writeFn )
321
315
322
316
// Insert both child leaves where they belong:
323
317
origIdx := st .key [diffidx ]
324
- newIdx := key [diffidx + st . keyOffset ]
318
+ newIdx := key [diffidx ]
325
319
p .children [origIdx ] = n
326
320
p .children [newIdx ] = o
327
321
st .key = st .key [:diffidx ]
@@ -355,7 +349,6 @@ func (st *StackTrie) insert(key, value []byte, prefix []byte) {
355
349
st .nodeType = extNode
356
350
st .children [0 ] = NewStackTrieWithOwner (st .writeFn , st .owner )
357
351
st .children [0 ].nodeType = branchNode
358
- st .children [0 ].keyOffset = st .keyOffset + diffidx
359
352
p = st .children [0 ]
360
353
}
361
354
@@ -364,19 +357,19 @@ func (st *StackTrie) insert(key, value []byte, prefix []byte) {
364
357
// The child leave will be hashed directly in order to
365
358
// free up some memory.
366
359
origIdx := st .key [diffidx ]
367
- p .children [origIdx ] = newLeaf (st .owner , diffidx + 1 , st .key , st .val , st .writeFn )
360
+ p .children [origIdx ] = newLeaf (st .owner , st .key [ diffidx + 1 :] , st .val , st .writeFn )
368
361
p .children [origIdx ].hash (append (prefix , st .key [:diffidx + 1 ]... ))
369
362
370
- newIdx := key [diffidx + st . keyOffset ]
371
- p .children [newIdx ] = newLeaf (st .owner , p . keyOffset + 1 , key , value , st .writeFn )
363
+ newIdx := key [diffidx ]
364
+ p .children [newIdx ] = newLeaf (st .owner , key [ diffidx + 1 :] , value , st .writeFn )
372
365
373
366
// Finally, cut off the key part that has been passed
374
367
// over to the children.
375
368
st .key = st .key [:diffidx ]
376
369
st .val = nil
377
370
case emptyNode : /* Empty */
378
371
st .nodeType = leafNode
379
- st .key = key [ st . keyOffset :]
372
+ st .key = key
380
373
st .val = value
381
374
case hashedNode :
382
375
panic ("trying to insert into hash" )
0 commit comments