github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/mempool/herocache/execution_data.go (about) 1 package herocache 2 3 import ( 4 "fmt" 5 6 "github.com/rs/zerolog" 7 8 "github.com/onflow/flow-go/model/flow" 9 "github.com/onflow/flow-go/module" 10 "github.com/onflow/flow-go/module/executiondatasync/execution_data" 11 herocache "github.com/onflow/flow-go/module/mempool/herocache/backdata" 12 "github.com/onflow/flow-go/module/mempool/herocache/backdata/heropool" 13 "github.com/onflow/flow-go/module/mempool/herocache/internal" 14 "github.com/onflow/flow-go/module/mempool/stdmap" 15 ) 16 17 type BlockExecutionData struct { 18 c *stdmap.Backend 19 } 20 21 // NewBlockExecutionData implements a block execution data mempool based on hero cache. 22 func NewBlockExecutionData(limit uint32, logger zerolog.Logger, collector module.HeroCacheMetrics) *BlockExecutionData { 23 return &BlockExecutionData{ 24 c: stdmap.NewBackend( 25 stdmap.WithBackData( 26 herocache.NewCache(limit, 27 herocache.DefaultOversizeFactor, 28 heropool.LRUEjection, 29 logger.With().Str("mempool", "block_execution_data").Logger(), 30 collector))), 31 } 32 } 33 34 // Has checks whether the block execution data for the given block ID is currently in 35 // the memory pool. 36 func (t *BlockExecutionData) Has(blockID flow.Identifier) bool { 37 return t.c.Has(blockID) 38 } 39 40 // Add adds a block execution data to the mempool, keyed by block ID. 41 // It returns false if the execution data was already in the mempool. 42 func (t *BlockExecutionData) Add(ed *execution_data.BlockExecutionDataEntity) bool { 43 entity := internal.NewWrappedEntity(ed.BlockID, ed) 44 return t.c.Add(*entity) 45 } 46 47 // ByID returns the block execution data for the given block ID from the mempool. 48 // It returns false if the execution data was not found in the mempool. 49 func (t *BlockExecutionData) ByID(blockID flow.Identifier) (*execution_data.BlockExecutionDataEntity, bool) { 50 entity, exists := t.c.ByID(blockID) 51 if !exists { 52 return nil, false 53 } 54 55 return unwrap(entity), true 56 } 57 58 // All returns all block execution data from the mempool. Since it is using the HeroCache, All guarantees returning 59 // all block execution data in the same order as they are added. 60 func (t *BlockExecutionData) All() []*execution_data.BlockExecutionDataEntity { 61 entities := t.c.All() 62 eds := make([]*execution_data.BlockExecutionDataEntity, 0, len(entities)) 63 for _, entity := range entities { 64 eds = append(eds, unwrap(entity)) 65 } 66 return eds 67 } 68 69 // Clear removes all block execution data stored in this mempool. 70 func (t *BlockExecutionData) Clear() { 71 t.c.Clear() 72 } 73 74 // Size returns total number of stored block execution data. 75 func (t *BlockExecutionData) Size() uint { 76 return t.c.Size() 77 } 78 79 // Remove removes block execution data from mempool by block ID. 80 // It returns true if the execution data was known and removed. 81 func (t *BlockExecutionData) Remove(blockID flow.Identifier) bool { 82 return t.c.Remove(blockID) 83 } 84 85 // unwrap converts an internal.WrappedEntity to a BlockExecutionDataEntity. 86 func unwrap(entity flow.Entity) *execution_data.BlockExecutionDataEntity { 87 wrappedEntity, ok := entity.(internal.WrappedEntity) 88 if !ok { 89 panic(fmt.Sprintf("invalid wrapped entity in block execution data pool (%T)", entity)) 90 } 91 92 ed, ok := wrappedEntity.Entity.(*execution_data.BlockExecutionDataEntity) 93 if !ok { 94 panic(fmt.Sprintf("invalid entity in block execution data pool (%T)", wrappedEntity.Entity)) 95 } 96 97 return ed 98 }