Skip to content

Commit 84dbafb

Browse files
rjl493456442holiman
authored andcommitted
trie: remove hasvalue notion
According to the benchmarks, type assertion between the pointer and interface is extremely fast. BenchmarkIntmethod-12 1000000000 1.91 ns/op BenchmarkInterface-12 1000000000 2.13 ns/op BenchmarkTypeSwitch-12 1000000000 1.81 ns/op BenchmarkTypeAssertion-12 2000000000 1.78 ns/op So the overhead for asserting whether the shortnode has "valuenode" child is super tiny. No necessary to have another field.
1 parent 2275c7e commit 84dbafb

File tree

1 file changed

+19
-24
lines changed

1 file changed

+19
-24
lines changed

trie/committer.go

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ const leafChanSize = 200
3232

3333
// leaf represents a trie leaf value
3434
type leaf struct {
35-
size int // size of the rlp data (estimate)
36-
hash common.Hash // hash of rlp data
37-
node node // the node to commit
38-
vnodes bool // set to true if the node (possibly) contains a valueNode
35+
size int // size of the rlp data (estimate)
36+
hash common.Hash // hash of rlp data
37+
node node // the node to commit
3938
}
4039

4140
// committer is a type used for the trie Commit operation. A committer has some
@@ -109,20 +108,20 @@ func (c *committer) commit(n node, db *Database) (node, error) {
109108
}
110109
// The key needs to be copied, since we're delivering it to database
111110
collapsed.Key = hexToCompact(cn.Key)
112-
hashedNode := c.store(collapsed, db, true)
111+
hashedNode := c.store(collapsed, db)
113112
if hn, ok := hashedNode.(hashNode); ok {
114113
return hn, nil
115114
}
116115
return collapsed, nil
117116
case *fullNode:
118-
hashedKids, hasVnodes, err := c.commitChildren(cn, db)
117+
hashedKids, err := c.commitChildren(cn, db)
119118
if err != nil {
120119
return nil, err
121120
}
122121
collapsed := cn.copy()
123122
collapsed.Children = hashedKids
124123

125-
hashedNode := c.store(collapsed, db, hasVnodes)
124+
hashedNode := c.store(collapsed, db)
126125
if hn, ok := hashedNode.(hashNode); ok {
127126
return hn, nil
128127
}
@@ -137,7 +136,7 @@ func (c *committer) commit(n node, db *Database) (node, error) {
137136
}
138137

139138
// commitChildren commits the children of the given fullnode
140-
func (c *committer) commitChildren(n *fullNode, db *Database) ([17]node, bool, error) {
139+
func (c *committer) commitChildren(n *fullNode, db *Database) ([17]node, error) {
141140
var children [17]node
142141
for i := 0; i < 16; i++ {
143142
child := n.Children[i]
@@ -156,23 +155,21 @@ func (c *committer) commitChildren(n *fullNode, db *Database) ([17]node, bool, e
156155
// possible the type is not hashnode.
157156
hashed, err := c.commit(child, db)
158157
if err != nil {
159-
return children, false, err
158+
return children, err
160159
}
161160
children[i] = hashed
162161
}
163162
// For the 17th child, it's possible the type is valuenode.
164-
var hasValue bool
165163
if n.Children[16] != nil {
166-
hasValue = true
167164
children[16] = n.Children[16]
168165
}
169-
return children, hasValue, nil
166+
return children, nil
170167
}
171168

172169
// store hashes the node n and if we have a storage layer specified, it writes
173170
// the key/value pair to it and tracks any node->child references as well as any
174171
// node->external trie references.
175-
func (c *committer) store(n node, db *Database, hasVnodeChildren bool) node {
172+
func (c *committer) store(n node, db *Database) node {
176173
// Larger nodes are replaced by their hash and stored in the database.
177174
var (
178175
hash, _ = n.cache()
@@ -193,10 +190,9 @@ func (c *committer) store(n node, db *Database, hasVnodeChildren bool) node {
193190
// The leaf channel will be active only when there an active leaf-callback
194191
if c.leafCh != nil {
195192
c.leafCh <- &leaf{
196-
size: size,
197-
hash: common.BytesToHash(hash),
198-
node: n,
199-
vnodes: hasVnodeChildren,
193+
size: size,
194+
hash: common.BytesToHash(hash),
195+
node: n,
200196
}
201197
} else if db != nil {
202198
// No leaf-callback used, but there's still a database. Do serial
@@ -212,17 +208,16 @@ func (c *committer) store(n node, db *Database, hasVnodeChildren bool) node {
212208
func (c *committer) commitLoop(db *Database) {
213209
for item := range c.leafCh {
214210
var (
215-
hash = item.hash
216-
size = item.size
217-
n = item.node
218-
hasVnodes = item.vnodes
211+
hash = item.hash
212+
size = item.size
213+
n = item.node
219214
)
220215
// We are pooling the trie nodes into an intermediate memory cache
221216
db.lock.Lock()
222217
db.insert(hash, size, n)
223218
db.lock.Unlock()
224219

225-
if c.onleaf != nil && hasVnodes {
220+
if c.onleaf != nil {
226221
switch n := n.(type) {
227222
case *shortNode:
228223
if child, ok := n.Val.(valueNode); ok {
@@ -231,8 +226,8 @@ func (c *committer) commitLoop(db *Database) {
231226
case *fullNode:
232227
// For children in range [0, 15], it's impossible
233228
// to contain valuenode. Only check the 17th child.
234-
if child, ok := n.Children[16].(valueNode); ok {
235-
c.onleaf(nil, child, hash)
229+
if n.Children[16] != nil {
230+
c.onleaf(nil, n.Children[16].(valueNode), hash)
236231
}
237232
}
238233
}

0 commit comments

Comments
 (0)