erigon-pulse/trie/trie_transform.go
Alex Sharov daa359c363
Mgr schedule iterator (#566)
* db based version of PrefixByCumulativeWitnessSize

* db based version of PrefixByCumulativeWitnessSize

* retain all in Trie by default

* fix WitnessLen logic in calcTrie roots

* Rename IntermediateTrieWitnessLenBucket to IntermediateWitnessLenBucket

* handle corner cases in WL

* Use correct incarnation for IH bucket

* use name WitnessSize

* save progress towards db-only witness estimation

* results from trie and from db are still different

* less recursion

* correct incarnation in CumulativeSearch

* reuse results from previous Tick, separate concepts of parent and startKey

* experiment: if not including trie structure to WitnessSize will reduce cumulative error

* tool to generate all IH and tool to calculate assessment of cumulative error

* tool to generate all IH

* Calculate totalWitnessSize based on DB data - then schedule will not overrun state during MGR cycle

* better stats

* Calculate totalWitnessSize based on DB data - then schedule will not overrun state during MGR cycle

* Calculate totalWitnessSize based on DB data - then schedule will not overrun state during MGR cycle

* calculate ticks size distribution

* estimate cumulative error

* fix linter

* resetIH from scratch if needed

* cleanup

* fix test

* fix test
2020-05-28 12:33:05 +01:00

60 lines
1.7 KiB
Go

package trie
import (
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/core/types/accounts"
)
type keyTransformFunc func([]byte) []byte
func transformSubTrie(nd node, hex []byte, newTrie *Trie, transformFunc keyTransformFunc) {
switch n := nd.(type) {
case nil:
return
case valueNode:
nCopy := make(valueNode, len(n))
copy(nCopy, n)
_, newTrie.root = newTrie.insert(newTrie.root, transformFunc(hex), nCopy)
return
case *accountNode:
accountCopy := accounts.NewAccount()
accountCopy.Copy(&n.Account)
var code []byte = nil
if n.code != nil {
code = make([]byte, len(n.code))
copy(code, n.code)
}
_, newTrie.root = newTrie.insert(newTrie.root, transformFunc(hex), &accountNode{accountCopy, nil, true, codeNode(code), n.codeSize})
aHex := hex
if aHex[len(aHex)-1] == 16 {
aHex = aHex[:len(aHex)-1]
}
transformSubTrie(n.storage, aHex, newTrie, transformFunc)
case hashNode:
_, newTrie.root = newTrie.insert(newTrie.root, transformFunc(hex), hashNode{hash: common.CopyBytes(n.hash), iws: n.iws})
return
case *shortNode:
var hexVal []byte
hexVal = concat(hex, n.Key...)
transformSubTrie(n.Val, hexVal, newTrie, transformFunc)
case *duoNode:
i1, i2 := n.childrenIdx()
hex1 := make([]byte, len(hex)+1)
copy(hex1, hex)
hex1[len(hex)] = i1
hex2 := make([]byte, len(hex)+1)
copy(hex2, hex)
hex2[len(hex)] = i2
transformSubTrie(n.child1, hex1, newTrie, transformFunc)
transformSubTrie(n.child2, hex2, newTrie, transformFunc)
case *fullNode:
for i, child := range n.Children {
if child != nil {
transformSubTrie(child, concat(hex, byte(i)), newTrie, transformFunc)
}
}
default:
panic("")
}
}