mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
core: exploit the use of cache in txSortedMap
This commit is contained in:
parent
62e94895da
commit
804c9c8f76
1 changed files with 31 additions and 26 deletions
|
|
@ -18,7 +18,6 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"math"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
|
@ -97,28 +96,44 @@ func (m *txSortedMap) Forward(threshold uint64) types.Transactions {
|
||||||
return removed
|
return removed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort tries to sort all transactions from the map and writes them to cache
|
||||||
|
func (m *txSortedMap) sort() {
|
||||||
|
// If the sorting was not cached yet, create and cache it
|
||||||
|
if m.cache == nil {
|
||||||
|
m.cache = make(types.Transactions, 0, len(m.items))
|
||||||
|
for _, tx := range m.items {
|
||||||
|
m.cache = append(m.cache, tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(types.TxByNonce(m.cache))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Filter iterates over the list of transactions and removes all of them for which
|
// Filter iterates over the list of transactions and removes all of them for which
|
||||||
// the specified function evaluates to true.
|
// the specified function evaluates to true.
|
||||||
func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
|
func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
|
||||||
var removed types.Transactions
|
var removed types.Transactions
|
||||||
|
|
||||||
|
m.sort()
|
||||||
|
|
||||||
|
// slices that share the same memory backing
|
||||||
|
*m.index = (*m.index)[:0]
|
||||||
|
newCache := m.cache[:0]
|
||||||
|
|
||||||
// Collect all the transactions to filter out
|
// Collect all the transactions to filter out
|
||||||
for nonce, tx := range m.items {
|
for _, tx := range m.cache {
|
||||||
if filter(tx) {
|
if filter(tx) {
|
||||||
removed = append(removed, tx)
|
removed = append(removed, tx)
|
||||||
delete(m.items, nonce)
|
delete(m.items, tx.Nonce())
|
||||||
|
} else {
|
||||||
|
*m.index = append(*m.index, tx.Nonce())
|
||||||
|
newCache = append(newCache, tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If transactions were removed, the heap and cache are ruined
|
|
||||||
if len(removed) > 0 {
|
|
||||||
*m.index = make([]uint64, 0, len(m.items))
|
|
||||||
for nonce := range m.items {
|
|
||||||
*m.index = append(*m.index, nonce)
|
|
||||||
}
|
|
||||||
heap.Init(m.index)
|
|
||||||
|
|
||||||
m.cache = nil
|
heap.Init(m.index)
|
||||||
}
|
m.cache = newCache
|
||||||
|
|
||||||
return removed
|
return removed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,14 +216,8 @@ func (m *txSortedMap) Len() int {
|
||||||
// sorted internal representation. The result of the sorting is cached in case
|
// sorted internal representation. The result of the sorting is cached in case
|
||||||
// it's requested again before any modifications are made to the contents.
|
// it's requested again before any modifications are made to the contents.
|
||||||
func (m *txSortedMap) Flatten() types.Transactions {
|
func (m *txSortedMap) Flatten() types.Transactions {
|
||||||
// If the sorting was not cached yet, create and cache it
|
m.sort()
|
||||||
if m.cache == nil {
|
|
||||||
m.cache = make(types.Transactions, 0, len(m.items))
|
|
||||||
for _, tx := range m.items {
|
|
||||||
m.cache = append(m.cache, tx)
|
|
||||||
}
|
|
||||||
sort.Sort(types.TxByNonce(m.cache))
|
|
||||||
}
|
|
||||||
// Copy the cache to prevent accidental modifications
|
// Copy the cache to prevent accidental modifications
|
||||||
txs := make(types.Transactions, len(m.cache))
|
txs := make(types.Transactions, len(m.cache))
|
||||||
copy(txs, m.cache)
|
copy(txs, m.cache)
|
||||||
|
|
@ -302,12 +311,8 @@ func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions
|
||||||
var invalids types.Transactions
|
var invalids types.Transactions
|
||||||
|
|
||||||
if l.strict && len(removed) > 0 {
|
if l.strict && len(removed) > 0 {
|
||||||
lowest := uint64(math.MaxUint64)
|
lowest := removed[0].Nonce()
|
||||||
for _, tx := range removed {
|
|
||||||
if nonce := tx.Nonce(); lowest > nonce {
|
|
||||||
lowest = nonce
|
|
||||||
}
|
|
||||||
}
|
|
||||||
invalids = l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest })
|
invalids = l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest })
|
||||||
}
|
}
|
||||||
return removed, invalids
|
return removed, invalids
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue