mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
trie: make db insert use size instead of full data, update tests
This commit is contained in:
parent
2a9d1e7067
commit
7cc9b10ed6
3 changed files with 30 additions and 10 deletions
|
|
@ -314,24 +314,24 @@ func (db *Database) InsertBlob(hash common.Hash, blob []byte) {
|
|||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
|
||||
db.insert(hash, blob, rawNode(blob))
|
||||
db.insert(hash, len(blob), rawNode(blob))
|
||||
}
|
||||
|
||||
// insert inserts a collapsed trie node into the memory database. This method is
|
||||
// a more generic version of InsertBlob, supporting both raw blob insertions as
|
||||
// well ex trie node insertions. The blob must always be specified to allow proper
|
||||
// well ex trie node insertions. The blob size must be specified to allow proper
|
||||
// size tracking.
|
||||
func (db *Database) insert(hash common.Hash, blob []byte, node node) {
|
||||
func (db *Database) insert(hash common.Hash, size int, node node) {
|
||||
// If the node's already cached, skip
|
||||
if _, ok := db.dirties[hash]; ok {
|
||||
return
|
||||
}
|
||||
memcacheDirtyWriteMeter.Mark(int64(len(blob)))
|
||||
memcacheDirtyWriteMeter.Mark(int64(size))
|
||||
|
||||
// Create the cached entry for this node
|
||||
entry := &cachedNode{
|
||||
node: simplifyNode(node),
|
||||
size: uint16(len(blob)),
|
||||
size: uint16(size),
|
||||
flushPrev: db.newest,
|
||||
}
|
||||
for _, child := range entry.childs() {
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ func (h *hasher) store(n node, db *Database, force bool) (node, error) {
|
|||
hash := common.BytesToHash(hash)
|
||||
|
||||
db.lock.Lock()
|
||||
db.insert(hash, h.tmp, n)
|
||||
db.insert(hash, len(h.tmp), n)
|
||||
db.lock.Unlock()
|
||||
|
||||
// Track external references from account->storage trie
|
||||
|
|
|
|||
|
|
@ -512,14 +512,34 @@ func BenchmarkHash(b *testing.B) {
|
|||
trie.Hash()
|
||||
}
|
||||
|
||||
type account struct {
|
||||
Nonce uint64
|
||||
Balance *big.Int
|
||||
Root common.Hash
|
||||
Code []byte
|
||||
}
|
||||
|
||||
// Benchmarks the trie Commit following a Hash. Since the trie caches the result of any operation,
|
||||
// we cannot use b.N as the number of hashing rouns, since all rounds apart from
|
||||
// the first one will be NOOP. As such, we'll use b.N as the number of account to
|
||||
// insert into the trie before measuring the hashing.
|
||||
func BenchmarkCommitAfterHash(b *testing.B) {
|
||||
b.Run("no-onleaf", func(b *testing.B) {
|
||||
benchmarkCommitAfterHash(b, nil)
|
||||
})
|
||||
onleaf := func(leaf []byte, parent common.Hash) error {
|
||||
var a account
|
||||
rlp.DecodeBytes(leaf, &a)
|
||||
return nil
|
||||
}
|
||||
b.Run("with-onleaf", func(b *testing.B) {
|
||||
benchmarkCommitAfterHash(b, onleaf)
|
||||
})
|
||||
}
|
||||
|
||||
func benchmarkCommitAfterHash(b *testing.B, onleaf LeafCallback) {
|
||||
// Make the random benchmark deterministic
|
||||
random := rand.New(rand.NewSource(0))
|
||||
|
||||
// Create a realistic account trie to hash
|
||||
addresses := make([][20]byte, b.N)
|
||||
for i := 0; i < len(addresses); i++ {
|
||||
|
|
@ -535,17 +555,17 @@ func BenchmarkCommitAfterHash(b *testing.B) {
|
|||
root = emptyRoot
|
||||
code = crypto.Keccak256(nil)
|
||||
)
|
||||
accounts[i], _ = rlp.EncodeToBytes([]interface{}{nonce, balance, root, code})
|
||||
accounts[i], _ = rlp.EncodeToBytes(&account{nonce, balance, root, code})
|
||||
}
|
||||
// Insert the accounts into the trie and hash it
|
||||
trie := newEmpty()
|
||||
for i := 0; i < len(addresses); i++ {
|
||||
trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
|
||||
}
|
||||
// Insert the accounts into the trie and hash it
|
||||
trie.Hash()
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
trie.Commit(nil)
|
||||
trie.Commit(onleaf)
|
||||
}
|
||||
|
||||
func tempDB() (string, *Database) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue