mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
trie: use chan-based commit only when leaf-callback is present
This commit is contained in:
parent
3c8ec1b569
commit
c28a51e465
3 changed files with 25 additions and 9 deletions
|
|
@ -70,10 +70,15 @@ var hasherPool = sync.Pool{
|
||||||
func newHasher(onleaf LeafCallback) *hasher {
|
func newHasher(onleaf LeafCallback) *hasher {
|
||||||
h := hasherPool.Get().(*hasher)
|
h := hasherPool.Get().(*hasher)
|
||||||
h.onleaf = onleaf
|
h.onleaf = onleaf
|
||||||
|
if onleaf != nil {
|
||||||
|
h.leafCh = make(chan *Leaf, 200) // arbitrary number
|
||||||
|
}
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func returnHasherToPool(h *hasher) {
|
func returnHasherToPool(h *hasher) {
|
||||||
|
h.onleaf = nil
|
||||||
|
h.leafCh = nil
|
||||||
hasherPool.Put(h)
|
hasherPool.Put(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,12 +190,21 @@ func (h *hasher) store(n node, db *Database, force bool) (node, error) {
|
||||||
if hash == nil {
|
if hash == nil {
|
||||||
hash = h.makeHashNode(h.tmp)
|
hash = h.makeHashNode(h.tmp)
|
||||||
}
|
}
|
||||||
if db != nil {
|
// If we're using channel-based leaf-reporting, send to channel.
|
||||||
|
// The leaf channel will be active only when there an active leaf-callback
|
||||||
|
if h.leafCh != nil {
|
||||||
h.leafCh <- &Leaf{
|
h.leafCh <- &Leaf{
|
||||||
size: len(h.tmp),
|
size: len(h.tmp),
|
||||||
hash: common.BytesToHash(hash),
|
hash: common.BytesToHash(hash),
|
||||||
node: n,
|
node: n,
|
||||||
}
|
}
|
||||||
|
} else if db != nil {
|
||||||
|
// No leaf-callback used, but there's still a database. Do serial
|
||||||
|
// insertion
|
||||||
|
db.lock.Lock()
|
||||||
|
db.insert(common.BytesToHash(hash), len(h.tmp), n)
|
||||||
|
db.lock.Unlock()
|
||||||
|
|
||||||
}
|
}
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
trie/trie.go
16
trie/trie.go
|
|
@ -420,14 +420,17 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
|
||||||
return emptyRoot, nil
|
return emptyRoot, nil
|
||||||
}
|
}
|
||||||
h := newHasher(onleaf)
|
h := newHasher(onleaf)
|
||||||
h.leafCh = make(chan *Leaf, 200) // arbitrary number
|
|
||||||
defer returnHasherToPool(h)
|
defer returnHasherToPool(h)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(1)
|
if onleaf != nil {
|
||||||
go h.commitLoop(t.db, &wg)
|
wg.Add(1)
|
||||||
hash, cached, err := h.hash(t.root, t.db, true)
|
go h.commitLoop(t.db, &wg)
|
||||||
close(h.leafCh)
|
}
|
||||||
wg.Wait()
|
hash, cached, err := h.hash(t.root, t.db, true)
|
||||||
|
if onleaf != nil {
|
||||||
|
close(h.leafCh)
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -443,4 +446,3 @@ func (t *Trie) hashRoot(db *Database, onleaf LeafCallback) (node, node, error) {
|
||||||
defer returnHasherToPool(h)
|
defer returnHasherToPool(h)
|
||||||
return h.hash(t.root, db, true)
|
return h.hash(t.root, db, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -637,7 +637,7 @@ func benchmarkCommitAfterHashFixedSize(b *testing.B, addresses [][20]byte, accou
|
||||||
// Insert the accounts into the trie and hash it
|
// Insert the accounts into the trie and hash it
|
||||||
trie.Hash()
|
trie.Hash()
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
trie.Commit(nil)
|
trie.Commit()
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue