mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
triedb/pathdb: remove sync pool
This commit is contained in:
parent
350a82c582
commit
c02137bc6f
2 changed files with 46 additions and 38 deletions
|
|
@ -33,6 +33,15 @@ import (
|
||||||
type layerTree struct {
|
type layerTree struct {
|
||||||
base *diskLayer
|
base *diskLayer
|
||||||
layers map[common.Hash]layer
|
layers map[common.Hash]layer
|
||||||
|
|
||||||
|
// descendants is a two-dimensional map where the keys represent
|
||||||
|
// an ancestor state root, and the values are the state roots of
|
||||||
|
// all its descendants.
|
||||||
|
//
|
||||||
|
// For example: r -> [c1, c2, ..., cn], where c1 through cn are
|
||||||
|
// the descendants of state r.
|
||||||
|
//
|
||||||
|
// This map includes all the existing diff layers and the disk layer.
|
||||||
descendants map[common.Hash]map[common.Hash]struct{}
|
descendants map[common.Hash]map[common.Hash]struct{}
|
||||||
lookup *lookup
|
lookup *lookup
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
|
@ -152,8 +161,13 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6
|
||||||
tree.lock.Lock()
|
tree.lock.Lock()
|
||||||
defer tree.lock.Unlock()
|
defer tree.lock.Unlock()
|
||||||
|
|
||||||
|
// Link the given layer into the layer set
|
||||||
tree.layers[l.rootHash()] = l
|
tree.layers[l.rootHash()] = l
|
||||||
|
|
||||||
|
// Link the given layer into its ancestors (up to the current disk layer)
|
||||||
tree.fillAncestors(l)
|
tree.fillAncestors(l)
|
||||||
|
|
||||||
|
// Link the given layer into the state mutation history
|
||||||
tree.lookup.addLayer(l)
|
tree.lookup.addLayer(l)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -185,6 +199,8 @@ func (tree *layerTree) cap(root common.Hash, layers int) error {
|
||||||
tree.layers = map[common.Hash]layer{
|
tree.layers = map[common.Hash]layer{
|
||||||
base.rootHash(): base,
|
base.rootHash(): base,
|
||||||
}
|
}
|
||||||
|
// Resets the descendants map, since there's only a single disk layer
|
||||||
|
// with no descendants.
|
||||||
tree.descendants = make(map[common.Hash]map[common.Hash]struct{})
|
tree.descendants = make(map[common.Hash]map[common.Hash]struct{})
|
||||||
tree.lookup = newLookup(base, tree.isDescendant)
|
tree.lookup = newLookup(base, tree.isDescendant)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -291,6 +307,7 @@ func (tree *layerTree) bottom() *diskLayer {
|
||||||
// lookupAccount returns the layer that is confirmed to contain the account data
|
// lookupAccount returns the layer that is confirmed to contain the account data
|
||||||
// being searched for.
|
// being searched for.
|
||||||
func (tree *layerTree) lookupAccount(accountHash common.Hash, state common.Hash) (layer, error) {
|
func (tree *layerTree) lookupAccount(accountHash common.Hash, state common.Hash) (layer, error) {
|
||||||
|
// Hold the read lock to prevent the unexpected layer changes
|
||||||
tree.lock.RLock()
|
tree.lock.RLock()
|
||||||
defer tree.lock.RUnlock()
|
defer tree.lock.RUnlock()
|
||||||
|
|
||||||
|
|
@ -308,6 +325,7 @@ func (tree *layerTree) lookupAccount(accountHash common.Hash, state common.Hash)
|
||||||
// lookupStorage returns the layer that is confirmed to contain the storage slot
|
// lookupStorage returns the layer that is confirmed to contain the storage slot
|
||||||
// data being searched for.
|
// data being searched for.
|
||||||
func (tree *layerTree) lookupStorage(accountHash common.Hash, slotHash common.Hash, state common.Hash) (layer, error) {
|
func (tree *layerTree) lookupStorage(accountHash common.Hash, slotHash common.Hash, state common.Hash) (layer, error) {
|
||||||
|
// Hold the read lock to prevent the unexpected layer changes
|
||||||
tree.lock.RLock()
|
tree.lock.RLock()
|
||||||
defer tree.lock.RUnlock()
|
defer tree.lock.RUnlock()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,31 +25,23 @@ import (
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
// slicePool is a shared pool of hash slice, for reducing the GC pressure.
|
|
||||||
var slicePool = sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
slice := make([]common.Hash, 0, 16) // Pre-allocate a slice with a reasonable capacity.
|
|
||||||
return &slice
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSlice obtains the hash slice from the shared pool.
|
|
||||||
func getSlice() []common.Hash {
|
|
||||||
slice := *slicePool.Get().(*[]common.Hash)
|
|
||||||
slice = slice[:0]
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
// returnSlice returns the hash slice back to the shared pool for following usage.
|
|
||||||
func returnSlice(slice []common.Hash) {
|
|
||||||
slicePool.Put(&slice)
|
|
||||||
}
|
|
||||||
|
|
||||||
// lookup is an internal structure used to efficiently determine the layer in
|
// lookup is an internal structure used to efficiently determine the layer in
|
||||||
// which a state entry resides.
|
// which a state entry resides.
|
||||||
type lookup struct {
|
type lookup struct {
|
||||||
|
// accounts represents the mutation history for specific accounts.
|
||||||
|
// The key is the account address hash, and the value is a slice
|
||||||
|
// of **diff layer** IDs indicating where the account was modified,
|
||||||
|
// with the order from oldest to newest.
|
||||||
accounts map[common.Hash][]common.Hash
|
accounts map[common.Hash][]common.Hash
|
||||||
|
|
||||||
|
// storages represents the mutation history for specific storage
|
||||||
|
// slot. The key is the account address hash and the storage key
|
||||||
|
// hash, the value is a slice of **diff layer** IDs indicating
|
||||||
|
// where the slot was modified, with the order from oldest to newest.
|
||||||
storages map[common.Hash]map[common.Hash][]common.Hash
|
storages map[common.Hash]map[common.Hash][]common.Hash
|
||||||
|
|
||||||
|
// descendant is the callback indicating whether the layer with
|
||||||
|
// given root is a descendant of the one specified by `ancestor`.
|
||||||
descendant func(state common.Hash, ancestor common.Hash) bool
|
descendant func(state common.Hash, ancestor common.Hash) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,9 +79,9 @@ func newLookup(head layer, descendant func(state common.Hash, ancestor common.Ha
|
||||||
// If found, the account data corresponding to the supplied stateID resides
|
// If found, the account data corresponding to the supplied stateID resides
|
||||||
// in that layer. Otherwise, two scenarios are possible:
|
// in that layer. Otherwise, two scenarios are possible:
|
||||||
//
|
//
|
||||||
// The account remains unmodified from the current disk layer up to the state
|
// (a) the account remains unmodified from the current disk layer up to the state
|
||||||
// layer specified by the stateID: fallback to the disk layer for data retrieval.
|
// layer specified by the stateID: fallback to the disk layer for data retrieval,
|
||||||
// Or the layer specified by the stateID is stale: reject the data retrieval.
|
// (b) or the layer specified by the stateID is stale: reject the data retrieval.
|
||||||
func (l *lookup) accountTip(accountHash common.Hash, stateID common.Hash, base common.Hash) common.Hash {
|
func (l *lookup) accountTip(accountHash common.Hash, stateID common.Hash, base common.Hash) common.Hash {
|
||||||
list := l.accounts[accountHash]
|
list := l.accounts[accountHash]
|
||||||
for i := len(list) - 1; i >= 0; i-- {
|
for i := len(list) - 1; i >= 0; i-- {
|
||||||
|
|
@ -114,10 +106,10 @@ func (l *lookup) accountTip(accountHash common.Hash, stateID common.Hash, base c
|
||||||
// If found, the storage data corresponding to the supplied stateID resides
|
// If found, the storage data corresponding to the supplied stateID resides
|
||||||
// in that layer. Otherwise, two scenarios are possible:
|
// in that layer. Otherwise, two scenarios are possible:
|
||||||
//
|
//
|
||||||
// The storage slot remains unmodified from the current disk layer up to the
|
// (a) the storage slot remains unmodified from the current disk layer up to
|
||||||
// state layer specified by the stateID: fallback to the disk layer for data
|
// the state layer specified by the stateID: fallback to the disk layer for
|
||||||
// retrieval. Or the layer specified by the stateID is stale: reject the data
|
// data retrieval, (b) or the layer specified by the stateID is stale: reject
|
||||||
// retrieval.
|
// the data retrieval.
|
||||||
func (l *lookup) storageTip(accountHash common.Hash, slotHash common.Hash, stateID common.Hash, base common.Hash) common.Hash {
|
func (l *lookup) storageTip(accountHash common.Hash, slotHash common.Hash, stateID common.Hash, base common.Hash) common.Hash {
|
||||||
subset, exists := l.storages[accountHash]
|
subset, exists := l.storages[accountHash]
|
||||||
if exists {
|
if exists {
|
||||||
|
|
@ -159,7 +151,7 @@ func (l *lookup) addLayer(diff *diffLayer) {
|
||||||
for accountHash := range diff.states.accountData {
|
for accountHash := range diff.states.accountData {
|
||||||
list, exists := l.accounts[accountHash]
|
list, exists := l.accounts[accountHash]
|
||||||
if !exists {
|
if !exists {
|
||||||
list = getSlice()
|
list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool
|
||||||
}
|
}
|
||||||
list = append(list, state)
|
list = append(list, state)
|
||||||
l.accounts[accountHash] = list
|
l.accounts[accountHash] = list
|
||||||
|
|
@ -178,7 +170,7 @@ func (l *lookup) addLayer(diff *diffLayer) {
|
||||||
for slotHash := range slots {
|
for slotHash := range slots {
|
||||||
list, exists := subset[slotHash]
|
list, exists := subset[slotHash]
|
||||||
if !exists {
|
if !exists {
|
||||||
list = getSlice()
|
list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool
|
||||||
}
|
}
|
||||||
list = append(list, state)
|
list = append(list, state)
|
||||||
subset[slotHash] = list
|
subset[slotHash] = list
|
||||||
|
|
@ -212,7 +204,7 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
list = list[1:]
|
list = list[1:]
|
||||||
if cap(list) > 1024 {
|
if cap(list) > 1024 {
|
||||||
list = append(getSlice(), list...)
|
list = append(make([]common.Hash, 0, len(list)), list...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
list = append(list[:i], list[i+1:]...)
|
list = append(list[:i], list[i+1:]...)
|
||||||
|
|
@ -227,7 +219,6 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
||||||
if len(list) != 0 {
|
if len(list) != 0 {
|
||||||
l.accounts[accountHash] = list
|
l.accounts[accountHash] = list
|
||||||
} else {
|
} else {
|
||||||
returnSlice(list)
|
|
||||||
delete(l.accounts, accountHash)
|
delete(l.accounts, accountHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -252,7 +243,7 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
list = list[1:]
|
list = list[1:]
|
||||||
if cap(list) > 1024 {
|
if cap(list) > 1024 {
|
||||||
list = append(getSlice(), list...)
|
list = append(make([]common.Hash, 0, len(list)), list...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
list = append(list[:i], list[i+1:]...)
|
list = append(list[:i], list[i+1:]...)
|
||||||
|
|
@ -267,7 +258,6 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
||||||
if len(list) != 0 {
|
if len(list) != 0 {
|
||||||
subset[slotHash] = list
|
subset[slotHash] = list
|
||||||
} else {
|
} else {
|
||||||
returnSlice(subset[slotHash])
|
|
||||||
delete(subset, slotHash)
|
delete(subset, slotHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue