@@ -54,12 +54,11 @@ func returnToPool(st *StackTrie) {
5454// in order. Once it determines that a subtree will no longer be inserted
5555// into, it will hash it and free up the memory it uses.
5656type 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
6362}
6463
6564// NewStackTrie allocates and initializes an empty trie.
@@ -90,15 +89,13 @@ func (st *StackTrie) MarshalBinary() (data []byte, err error) {
9089 w = bufio .NewWriter (& b )
9190 )
9291 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
9795 }{
9896 st .nodeType ,
9997 st .val ,
10098 st .key ,
101- uint8 (st .keyOffset ),
10299 }); err != nil {
103100 return nil , err
104101 }
@@ -126,16 +123,14 @@ func (st *StackTrie) UnmarshalBinary(data []byte) error {
126123
127124func (st * StackTrie ) unmarshalBinary (r io.Reader ) error {
128125 var dec struct {
129- Nodetype uint8
130- Val []byte
131- Key []byte
132- KeyOffset uint8
126+ Nodetype uint8
127+ Val []byte
128+ Key []byte
133129 }
134130 gob .NewDecoder (r ).Decode (& dec )
135131 st .nodeType = dec .Nodetype
136132 st .val = dec .Val
137133 st .key = dec .Key
138- st .keyOffset = int (dec .KeyOffset )
139134
140135 var hasChild = make ([]byte , 1 )
141136 for i := range st .children {
@@ -160,20 +155,18 @@ func (st *StackTrie) setDb(db ethdb.KeyValueWriter) {
160155 }
161156}
162157
163- func newLeaf (ko int , key , val []byte , db ethdb.KeyValueWriter ) * StackTrie {
158+ func newLeaf (key , val []byte , db ethdb.KeyValueWriter ) * StackTrie {
164159 st := stackTrieFromPool (db )
165160 st .nodeType = leafNode
166- st .keyOffset = ko
167- st .key = append (st .key , key [ko :]... )
161+ st .key = append (st .key , key ... )
168162 st .val = val
169163 return st
170164}
171165
172- func newExt (ko int , key []byte , child * StackTrie , db ethdb.KeyValueWriter ) * StackTrie {
166+ func newExt (key []byte , child * StackTrie , db ethdb.KeyValueWriter ) * StackTrie {
173167 st := stackTrieFromPool (db )
174168 st .nodeType = extNode
175- st .keyOffset = ko
176- st .key = append (st .key , key [ko :]... )
169+ st .key = append (st .key , key ... )
177170 st .children [0 ] = child
178171 return st
179172}
@@ -211,25 +204,26 @@ func (st *StackTrie) Reset() {
211204 st .children [i ] = nil
212205 }
213206 st .nodeType = emptyNode
214- st .keyOffset = 0
215207}
216208
217209// Helper function that, given a full key, determines the index
218210// at which the chunk pointed by st.keyOffset is different from
219211// the same chunk in the full key.
220212func (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+ }
223217 }
224- return diffindex
218+ return len ( st . key )
225219}
226220
227221// Helper function to that inserts a (key, value) pair into
228222// the trie.
229223func (st * StackTrie ) insert (key , value []byte ) {
230224 switch st .nodeType {
231225 case branchNode : /* Branch */
232- idx := int (key [st . keyOffset ])
226+ idx := int (key [0 ])
233227 // Unresolve elder siblings
234228 for i := idx - 1 ; i >= 0 ; i -- {
235229 if st .children [i ] != nil {
@@ -241,10 +235,10 @@ func (st *StackTrie) insert(key, value []byte) {
241235 }
242236 // Add new child
243237 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 )
246241 }
247- st .children [idx ].insert (key , value )
248242 case extNode : /* Ext */
249243 // Compare both key chunks and see where they differ
250244 diffidx := st .getDiffIndex (key )
@@ -257,7 +251,7 @@ func (st *StackTrie) insert(key, value []byte) {
257251 if diffidx == len (st .key ) {
258252 // Ext key and key segment are identical, recurse into
259253 // the child node.
260- st .children [0 ].insert (key , value )
254+ st .children [0 ].insert (key [ diffidx :] , value )
261255 return
262256 }
263257 // Save the original part. Depending if the break is
@@ -266,7 +260,7 @@ func (st *StackTrie) insert(key, value []byte) {
266260 // node directly.
267261 var n * StackTrie
268262 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 )
270264 } else {
271265 // Break on the last byte, no need to insert
272266 // an extension node: reuse the current node
@@ -288,15 +282,14 @@ func (st *StackTrie) insert(key, value []byte) {
288282 // node.
289283 st .children [0 ] = stackTrieFromPool (st .db )
290284 st .children [0 ].nodeType = branchNode
291- st .children [0 ].keyOffset = st .keyOffset + diffidx
292285 p = st .children [0 ]
293286 }
294287 // 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 )
296289
297290 // Insert both child leaves where they belong:
298291 origIdx := st .key [diffidx ]
299- newIdx := key [diffidx + st . keyOffset ]
292+ newIdx := key [diffidx ]
300293 p .children [origIdx ] = n
301294 p .children [newIdx ] = o
302295 st .key = st .key [:diffidx ]
@@ -330,7 +323,6 @@ func (st *StackTrie) insert(key, value []byte) {
330323 st .nodeType = extNode
331324 st .children [0 ] = NewStackTrie (st .db )
332325 st .children [0 ].nodeType = branchNode
333- st .children [0 ].keyOffset = st .keyOffset + diffidx
334326 p = st .children [0 ]
335327 }
336328
@@ -339,19 +331,19 @@ func (st *StackTrie) insert(key, value []byte) {
339331 // The child leave will be hashed directly in order to
340332 // free up some memory.
341333 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 )
343335 p .children [origIdx ].hash ()
344336
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 )
347339
348340 // Finally, cut off the key part that has been passed
349341 // over to the children.
350342 st .key = st .key [:diffidx ]
351343 st .val = nil
352344 case emptyNode : /* Empty */
353345 st .nodeType = leafNode
354- st .key = key [ st . keyOffset :]
346+ st .key = key
355347 st .val = value
356348 case hashedNode :
357349 panic ("trying to insert into hash" )
0 commit comments