|
|
- package mempool
-
- import (
- "container/list"
-
- tmsync "github.com/tendermint/tendermint/internal/libs/sync"
- "github.com/tendermint/tendermint/types"
- )
-
- // TxCache defines an interface for raw transaction caching in a mempool.
- // Currently, a TxCache does not allow direct reading or getting of transaction
- // values. A TxCache is used primarily to push transactions and removing
- // transactions. Pushing via Push returns a boolean telling the caller if the
- // transaction already exists in the cache or not.
- type TxCache interface {
- // Reset resets the cache to an empty state.
- Reset()
-
- // Push adds the given raw transaction to the cache and returns true if it was
- // newly added. Otherwise, it returns false.
- Push(tx types.Tx) bool
-
- // Remove removes the given raw transaction from the cache.
- Remove(tx types.Tx)
- }
-
- var _ TxCache = (*LRUTxCache)(nil)
-
- // LRUTxCache maintains a thread-safe LRU cache of raw transactions. The cache
- // only stores the hash of the raw transaction.
- type LRUTxCache struct {
- mtx tmsync.Mutex
- size int
- cacheMap map[[TxKeySize]byte]*list.Element
- list *list.List
- }
-
- func NewLRUTxCache(cacheSize int) *LRUTxCache {
- return &LRUTxCache{
- size: cacheSize,
- cacheMap: make(map[[TxKeySize]byte]*list.Element, cacheSize),
- list: list.New(),
- }
- }
-
- // GetList returns the underlying linked-list that backs the LRU cache. Note,
- // this should be used for testing purposes only!
- func (c *LRUTxCache) GetList() *list.List {
- return c.list
- }
-
- func (c *LRUTxCache) Reset() {
- c.mtx.Lock()
- defer c.mtx.Unlock()
-
- c.cacheMap = make(map[[TxKeySize]byte]*list.Element, c.size)
- c.list.Init()
- }
-
- func (c *LRUTxCache) Push(tx types.Tx) bool {
- c.mtx.Lock()
- defer c.mtx.Unlock()
-
- key := TxKey(tx)
-
- moved, ok := c.cacheMap[key]
- if ok {
- c.list.MoveToBack(moved)
- return false
- }
-
- if c.list.Len() >= c.size {
- front := c.list.Front()
- if front != nil {
- frontKey := front.Value.([TxKeySize]byte)
- delete(c.cacheMap, frontKey)
- c.list.Remove(front)
- }
- }
-
- e := c.list.PushBack(key)
- c.cacheMap[key] = e
-
- return true
- }
-
- func (c *LRUTxCache) Remove(tx types.Tx) {
- c.mtx.Lock()
- defer c.mtx.Unlock()
-
- key := TxKey(tx)
- e := c.cacheMap[key]
- delete(c.cacheMap, key)
-
- if e != nil {
- c.list.Remove(e)
- }
- }
-
- // NopTxCache defines a no-op raw transaction cache.
- type NopTxCache struct{}
-
- var _ TxCache = (*NopTxCache)(nil)
-
- func (NopTxCache) Reset() {}
- func (NopTxCache) Push(types.Tx) bool { return true }
- func (NopTxCache) Remove(types.Tx) {}
|