[BENCHMARK] trie: prioritize trie sync nodes by depth and lexigraphic key ordering

This commit is contained in:
Matthew Halpern 2019-03-28 09:23:28 -07:00
parent 67fc0377e1
commit a92dae21d6

View file

@ -17,8 +17,10 @@
package trie
import (
"encoding/binary"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/prque"
@ -46,6 +48,23 @@ type request struct {
callback LeafCallback // Callback to invoke if a leaf node it reached on this branch
}
// priority returns the request priority in the trie scheduler.
func (r *request) priority() int64 {
// Priority is meant to sort requests according to their depth and
// lexigraphic ordering within LevelDB, so that they can be retrieved
// from peers more efficiently and also stored more efficiently.
prefix := binary.BigEndian.Uint64(r.hash[:8])
// The prefix is inverted so that keys with a lower lexigraphic ordering
// have a larger number than keys with a higher lexigraphic ordering.
invertedPrefix := uint64(math.MaxUint64) - prefix
// Priority format: depth[:8] || invertedPrefix[:7]
// Note: the maximum number of nodes from the account state trie root to any
// account storage trie leaf is 128, which fits into a signed byte
// (with zero indexing)
priority := uint64(r.depth) << 56 | invertedPrefix >> 8
return int64(priority)
}
// SyncResult is a simple list to return missing nodes along with their request
// hashes.
type SyncResult struct {
@ -242,7 +261,7 @@ func (s *Sync) schedule(req *request) {
return
}
// Schedule the request for future retrieval
s.queue.Push(req.hash, int64(req.depth))
s.queue.Push(req.hash, req.priority())
s.requests[req.hash] = req
}