mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
trie: utilize callbacks instead of amassing lists of hashes in database ref/unref
This commit is contained in:
parent
c2c17966a4
commit
7c891c4f85
1 changed files with 34 additions and 4 deletions
|
|
@ -214,6 +214,36 @@ func gatherChildren(n node, children *[]common.Hash) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// forChilds invokes the callback for all the tracked children of this node,
|
||||||
|
// both the implicit ones from inside the node as well as the explicit ones
|
||||||
|
//from outside the node.
|
||||||
|
func (n *cachedNode) forChilds(onChild func(hash common.Hash)) {
|
||||||
|
for child := range n.children {
|
||||||
|
onChild(child)
|
||||||
|
}
|
||||||
|
if _, ok := n.node.(rawNode); !ok {
|
||||||
|
forGatherChildren(n.node, onChild)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// forGatherChildren traverses the node hierarchy of a collapsed storage node and
|
||||||
|
// invokes the callback for all the hashnode children.
|
||||||
|
func forGatherChildren(n node, onChild func(hash common.Hash)) {
|
||||||
|
switch n := n.(type) {
|
||||||
|
case *rawShortNode:
|
||||||
|
forGatherChildren(n.Val, onChild)
|
||||||
|
case rawFullNode:
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
forGatherChildren(n[i], onChild)
|
||||||
|
}
|
||||||
|
case hashNode:
|
||||||
|
onChild(common.BytesToHash(n))
|
||||||
|
case valueNode, nil:
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unknown node type: %T", n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// simplifyNode traverses the hierarchy of an expanded memory node and discards
|
// simplifyNode traverses the hierarchy of an expanded memory node and discards
|
||||||
// all the internal caches, returning a node that only contains the raw data.
|
// all the internal caches, returning a node that only contains the raw data.
|
||||||
func simplifyNode(n node) node {
|
func simplifyNode(n node) node {
|
||||||
|
|
@ -334,11 +364,11 @@ func (db *Database) insert(hash common.Hash, size int, node node) {
|
||||||
size: uint16(size),
|
size: uint16(size),
|
||||||
flushPrev: db.newest,
|
flushPrev: db.newest,
|
||||||
}
|
}
|
||||||
for _, child := range entry.childs() {
|
entry.forChilds(func(child common.Hash) {
|
||||||
if c := db.dirties[child]; c != nil {
|
if c := db.dirties[child]; c != nil {
|
||||||
c.parents++
|
c.parents++
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
db.dirties[hash] = entry
|
db.dirties[hash] = entry
|
||||||
|
|
||||||
// Update the flush-list endpoints
|
// Update the flush-list endpoints
|
||||||
|
|
@ -570,9 +600,9 @@ func (db *Database) dereference(child common.Hash, parent common.Hash) {
|
||||||
db.dirties[node.flushNext].flushPrev = node.flushPrev
|
db.dirties[node.flushNext].flushPrev = node.flushPrev
|
||||||
}
|
}
|
||||||
// Dereference all children and delete the node
|
// Dereference all children and delete the node
|
||||||
for _, hash := range node.childs() {
|
node.forChilds(func(hash common.Hash) {
|
||||||
db.dereference(hash, child)
|
db.dereference(hash, child)
|
||||||
}
|
})
|
||||||
delete(db.dirties, child)
|
delete(db.dirties, child)
|
||||||
db.dirtiesSize -= common.StorageSize(common.HashLength + int(node.size))
|
db.dirtiesSize -= common.StorageSize(common.HashLength + int(node.size))
|
||||||
if node.children != nil {
|
if node.children != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue