trie: optimize compactToHex and cleanup encoding logic

This commit is contained in:
therainisme 2025-12-06 15:29:13 +08:00
parent 73a2df2b0a
commit 35f702cdaf
2 changed files with 34 additions and 13 deletions

View file

@ -83,22 +83,39 @@ func compactToHex(compact []byte) []byte {
if len(compact) == 0 {
return compact
}
base := keybytesToHex(compact)
// delete terminator flag
if base[0] < 2 {
base = base[:len(base)-1]
baseLen := len(compact) * 2
first := compact[0]
// Add terminator length if it's a leaf (flag >= 2)
if first>>4 >= 2 {
baseLen += 1
}
// apply odd flag
chop := 2 - base[0]&1
return base[chop:]
// Calculate chop: 2 if even (flag&1 == 0), 1 if odd (flag&1 == 1)
chop := 2 - int(first>>4&1)
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 {
l := len(str)*2 + 1
var nibbles = make([]byte, l)
for i, b := range str {
nibbles[i*2] = b / 16
nibbles[i*2+1] = b % 16
nibbles[i*2] = b >> 4
nibbles[i*2+1] = b & 0x0f
}
nibbles[l-1] = 16
return nibbles
@ -110,8 +127,8 @@ func keybytesToHex(str []byte) []byte {
func writeHexKey(dst []byte, key []byte) []byte {
_ = dst[2*len(key)-1]
for i, b := range key {
dst[i*2] = b / 16
dst[i*2+1] = b % 16
dst[i*2] = b >> 4
dst[i*2+1] = b & 0x0f
}
return dst[:2*len(key)]
}

View file

@ -31,6 +31,10 @@ import (
"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
// 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
@ -760,7 +764,7 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) {
nodes.AddNode(path, trienode.NewDeletedWithPrev(t.prevalueTracer.Get(path)))
}
// 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
return rootHash, nodes
}
@ -771,7 +775,7 @@ func (t *Trie) hashRoot() []byte {
return types.EmptyRootHash.Bytes()
}
// 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() {
returnHasherToPool(h)
t.unhashed = 0