@@ -142,12 +142,10 @@ func (c *committer) store(path []byte, n node) node {
142142 // We have the hash already, estimate the RLP encoding-size of the node.
143143 // The size is used for mem tracking, does not need to be exact
144144 var (
145- size = estimateSize (n )
146145 nhash = common .BytesToHash (hash )
147146 mnode = & memoryNode {
148147 hash : nhash ,
149- node : simplifyNode (n ),
150- size : uint16 (size ),
148+ node : nodeToBytes (n ),
151149 }
152150 )
153151 // Collect the dirty node to nodeset for return.
@@ -166,31 +164,29 @@ func (c *committer) store(path []byte, n node) node {
166164 return hash
167165}
168166
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 )) {
174179 switch n := n .(type ) {
175180 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 )
178182 case * fullNode :
179- // A full node contains up to 16 hashes (some nils), and a key
180- s := 3
181183 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 )
187185 }
188- return s
189- case valueNode :
190- return 1 + len (n )
191186 case hashNode :
192- return 1 + len (n )
187+ onChild (common .BytesToHash (n ))
188+ case valueNode , nil :
193189 default :
194- panic (fmt .Sprintf ("node type %T" , n ))
190+ panic (fmt .Sprintf ("unknown node type: %T" , n ))
195191 }
196192}
0 commit comments