mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 04:36:42 +00:00
trie: optimize compactToHex and cleanup encoding logic
This commit is contained in:
parent
73a2df2b0a
commit
35f702cdaf
2 changed files with 34 additions and 13 deletions
|
|
@ -83,22 +83,39 @@ func compactToHex(compact []byte) []byte {
|
||||||
if len(compact) == 0 {
|
if len(compact) == 0 {
|
||||||
return compact
|
return compact
|
||||||
}
|
}
|
||||||
base := keybytesToHex(compact)
|
baseLen := len(compact) * 2
|
||||||
// delete terminator flag
|
first := compact[0]
|
||||||
if base[0] < 2 {
|
// Add terminator length if it's a leaf (flag >= 2)
|
||||||
base = base[:len(base)-1]
|
if first>>4 >= 2 {
|
||||||
|
baseLen += 1
|
||||||
}
|
}
|
||||||
// apply odd flag
|
// Calculate chop: 2 if even (flag&1 == 0), 1 if odd (flag&1 == 1)
|
||||||
chop := 2 - base[0]&1
|
chop := 2 - int(first>>4&1)
|
||||||
return base[chop:]
|
|
||||||
|
hex := make([]byte, baseLen-chop)
|
||||||
|
|
||||||
|
idx := 0
|
||||||
|
if chop == 1 {
|
||||||
|
hex[0] = first & 0x0f
|
||||||
|
idx = 1
|
||||||
|
}
|
||||||
|
for i := 1; i < len(compact); i++ {
|
||||||
|
hex[idx] = compact[i] >> 4
|
||||||
|
hex[idx+1] = compact[i] & 0x0f
|
||||||
|
idx += 2
|
||||||
|
}
|
||||||
|
if first>>4 >= 2 {
|
||||||
|
hex[len(hex)-1] = 16
|
||||||
|
}
|
||||||
|
return hex
|
||||||
}
|
}
|
||||||
|
|
||||||
func keybytesToHex(str []byte) []byte {
|
func keybytesToHex(str []byte) []byte {
|
||||||
l := len(str)*2 + 1
|
l := len(str)*2 + 1
|
||||||
var nibbles = make([]byte, l)
|
var nibbles = make([]byte, l)
|
||||||
for i, b := range str {
|
for i, b := range str {
|
||||||
nibbles[i*2] = b / 16
|
nibbles[i*2] = b >> 4
|
||||||
nibbles[i*2+1] = b % 16
|
nibbles[i*2+1] = b & 0x0f
|
||||||
}
|
}
|
||||||
nibbles[l-1] = 16
|
nibbles[l-1] = 16
|
||||||
return nibbles
|
return nibbles
|
||||||
|
|
@ -110,8 +127,8 @@ func keybytesToHex(str []byte) []byte {
|
||||||
func writeHexKey(dst []byte, key []byte) []byte {
|
func writeHexKey(dst []byte, key []byte) []byte {
|
||||||
_ = dst[2*len(key)-1]
|
_ = dst[2*len(key)-1]
|
||||||
for i, b := range key {
|
for i, b := range key {
|
||||||
dst[i*2] = b / 16
|
dst[i*2] = b >> 4
|
||||||
dst[i*2+1] = b % 16
|
dst[i*2+1] = b & 0x0f
|
||||||
}
|
}
|
||||||
return dst[:2*len(key)]
|
return dst[:2*len(key)]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ import (
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// maxUnhashedNodesForSingleThread is the threshold of unhashed nodes to trigger
|
||||||
|
// parallel hashing or committing.
|
||||||
|
const maxUnhashedNodesForSingleThread = 100
|
||||||
|
|
||||||
// Trie represents a Merkle Patricia Trie. Use New to create a trie that operates
|
// Trie represents a Merkle Patricia Trie. Use New to create a trie that operates
|
||||||
// on top of a node database. During a commit operation, the trie collects all
|
// on top of a node database. During a commit operation, the trie collects all
|
||||||
// modified nodes into a set for return. After committing, the trie becomes
|
// modified nodes into a set for return. After committing, the trie becomes
|
||||||
|
|
@ -760,7 +764,7 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) {
|
||||||
nodes.AddNode(path, trienode.NewDeletedWithPrev(t.prevalueTracer.Get(path)))
|
nodes.AddNode(path, trienode.NewDeletedWithPrev(t.prevalueTracer.Get(path)))
|
||||||
}
|
}
|
||||||
// If the number of changes is below 100, we let one thread handle it
|
// If the number of changes is below 100, we let one thread handle it
|
||||||
t.root = newCommitter(nodes, t.prevalueTracer, collectLeaf).Commit(t.root, t.uncommitted > 100)
|
t.root = newCommitter(nodes, t.prevalueTracer, collectLeaf).Commit(t.root, t.uncommitted > maxUnhashedNodesForSingleThread)
|
||||||
t.uncommitted = 0
|
t.uncommitted = 0
|
||||||
return rootHash, nodes
|
return rootHash, nodes
|
||||||
}
|
}
|
||||||
|
|
@ -771,7 +775,7 @@ func (t *Trie) hashRoot() []byte {
|
||||||
return types.EmptyRootHash.Bytes()
|
return types.EmptyRootHash.Bytes()
|
||||||
}
|
}
|
||||||
// If the number of changes is below 100, we let one thread handle it
|
// If the number of changes is below 100, we let one thread handle it
|
||||||
h := newHasher(t.unhashed >= 100)
|
h := newHasher(t.unhashed >= maxUnhashedNodesForSingleThread)
|
||||||
defer func() {
|
defer func() {
|
||||||
returnHasherToPool(h)
|
returnHasherToPool(h)
|
||||||
t.unhashed = 0
|
t.unhashed = 0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue