mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
wip: ignore this, and squash it
This commit is contained in:
parent
c28a51e465
commit
5524fcb63a
2 changed files with 55 additions and 1 deletions
|
|
@ -17,6 +17,7 @@
|
||||||
package trie
|
package trie
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
|
@ -169,6 +170,37 @@ func (h *hasher) hashChildren(original node, db *Database) (node, node, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// estimateSize estimates the size of an rlp-encoded node, without actually
|
||||||
|
// rlp-encoding it (zero allocs). This method has been experimentally tried, and with a trie
|
||||||
|
// with 1000 leafs, the only errors above 1% are on small shortnodes, where this
|
||||||
|
// method overestimates by 2 or 3 bytes (e.g. 37 instead of 35)
|
||||||
|
func estimateSize(n node) int {
|
||||||
|
switch n := n.(type) {
|
||||||
|
case *shortNode:
|
||||||
|
// A short node contains a compacted key, and a value.
|
||||||
|
return 3 + len(n.Key) + estimateSize(n.Val)
|
||||||
|
case *fullNode:
|
||||||
|
// A full node contains up to 16 hashes (some nils), and a key
|
||||||
|
s := 3
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
if child := n.Children[i]; child != nil {
|
||||||
|
s += estimateSize(child)
|
||||||
|
} else {
|
||||||
|
s += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
case valueNode:
|
||||||
|
return 1 + len(n)
|
||||||
|
case hashNode:
|
||||||
|
return 1 + len(n)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("node type %T", n))
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// store hashes the node n and if we have a storage layer specified, it writes
|
// store hashes the node n and if we have a storage layer specified, it writes
|
||||||
// the key/value pair to it and tracks any node->child references as well as any
|
// the key/value pair to it and tracks any node->child references as well as any
|
||||||
// node->external trie references.
|
// node->external trie references.
|
||||||
|
|
@ -190,6 +222,16 @@ 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)
|
||||||
}
|
}
|
||||||
|
// DEBUG todo remove me
|
||||||
|
// When we already have a cached hash, there's no need to rlp-encode the
|
||||||
|
// blob -- however, we stil need to use report the size to the database.
|
||||||
|
//actual := len(h.tmp)
|
||||||
|
//got := estimateSize(n)
|
||||||
|
//diff := math.Abs(1.0-float64(got)/float64(actual)) * 100
|
||||||
|
//if diff > 1.0 {
|
||||||
|
// fmt.Printf("actual: %d, got %d, diff : %02f%% (%T)\n", actual, got, diff, n)
|
||||||
|
//}
|
||||||
|
|
||||||
// If we're using channel-based leaf-reporting, send to channel.
|
// If we're using channel-based leaf-reporting, send to channel.
|
||||||
// The leaf channel will be active only when there an active leaf-callback
|
// The leaf channel will be active only when there an active leaf-callback
|
||||||
if h.leafCh != nil {
|
if h.leafCh != nil {
|
||||||
|
|
|
||||||
|
|
@ -568,6 +568,18 @@ func benchmarkCommitAfterHash(b *testing.B, onleaf LeafCallback) {
|
||||||
trie.Commit(onleaf)
|
trie.Commit(onleaf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCommitAfterHash(t *testing.T) {
|
||||||
|
// Create a realistic account trie to hash
|
||||||
|
addresses, accounts := makeAccounts(1000)
|
||||||
|
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()
|
||||||
|
trie.Commit(nil)
|
||||||
|
}
|
||||||
|
|
||||||
func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
|
func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
|
||||||
// Make the random benchmark deterministic
|
// Make the random benchmark deterministic
|
||||||
random := rand.New(rand.NewSource(0))
|
random := rand.New(rand.NewSource(0))
|
||||||
|
|
@ -637,7 +649,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()
|
trie.Commit(nil)
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue