@@ -142,12 +142,10 @@ func (c *committer) store(path []byte, n node) node {
142
142
// We have the hash already, estimate the RLP encoding-size of the node.
143
143
// The size is used for mem tracking, does not need to be exact
144
144
var (
145
- size = estimateSize (n )
146
145
nhash = common .BytesToHash (hash )
147
146
mnode = & memoryNode {
148
147
hash : nhash ,
149
- node : simplifyNode (n ),
150
- size : uint16 (size ),
148
+ node : nodeToBytes (n ),
151
149
}
152
150
)
153
151
// Collect the dirty node to nodeset for return.
@@ -166,31 +164,29 @@ func (c *committer) store(path []byte, n node) node {
166
164
return hash
167
165
}
168
166
169
- // estimateSize estimates the size of an rlp-encoded node, without actually
170
- // rlp-encoding it (zero allocs). This method has been experimentally tried, and with a trie
171
- // with 1000 leaves, the only errors above 1% are on small shortnodes, where this
172
- // method overestimates by 2 or 3 bytes (e.g. 37 instead of 35)
173
- func estimateSize (n node ) int {
167
+ // mptResolver the children resolver in merkle-patricia-tree.
168
+ type mptResolver struct {}
169
+
170
+ // ForEach implements childResolver, decodes the provided node and
171
+ // traverses the children inside.
172
+ func (resolver mptResolver ) forEach (node []byte , onChild func (common.Hash )) {
173
+ forGatherChildren (mustDecodeNodeUnsafe (nil , node ), onChild )
174
+ }
175
+
176
+ // forGatherChildren traverses the node hierarchy and invokes the callback
177
+ // for all the hashnode children.
178
+ func forGatherChildren (n node , onChild func (hash common.Hash )) {
174
179
switch n := n .(type ) {
175
180
case * shortNode :
176
- // A short node contains a compacted key, and a value.
177
- return 3 + len (n .Key ) + estimateSize (n .Val )
181
+ forGatherChildren (n .Val , onChild )
178
182
case * fullNode :
179
- // A full node contains up to 16 hashes (some nils), and a key
180
- s := 3
181
183
for i := 0 ; i < 16 ; i ++ {
182
- if child := n .Children [i ]; child != nil {
183
- s += estimateSize (child )
184
- } else {
185
- s ++
186
- }
184
+ forGatherChildren (n .Children [i ], onChild )
187
185
}
188
- return s
189
- case valueNode :
190
- return 1 + len (n )
191
186
case hashNode :
192
- return 1 + len (n )
187
+ onChild (common .BytesToHash (n ))
188
+ case valueNode , nil :
193
189
default :
194
- panic (fmt .Sprintf ("node type %T" , n ))
190
+ panic (fmt .Sprintf ("unknown node type: %T" , n ))
195
191
}
196
192
}
0 commit comments