github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/storage/badger/index.go (about)

     1  package badger
     2  
     3  import (
     4  	"github.com/dgraph-io/badger/v2"
     5  
     6  	"github.com/onflow/flow-go/model/flow"
     7  	"github.com/onflow/flow-go/module"
     8  	"github.com/onflow/flow-go/module/metrics"
     9  	"github.com/onflow/flow-go/storage/badger/operation"
    10  	"github.com/onflow/flow-go/storage/badger/procedure"
    11  	"github.com/onflow/flow-go/storage/badger/transaction"
    12  )
    13  
    14  // Index implements a simple read-only payload storage around a badger DB.
    15  type Index struct {
    16  	db    *badger.DB
    17  	cache *Cache[flow.Identifier, *flow.Index]
    18  }
    19  
    20  func NewIndex(collector module.CacheMetrics, db *badger.DB) *Index {
    21  
    22  	store := func(blockID flow.Identifier, index *flow.Index) func(*transaction.Tx) error {
    23  		return transaction.WithTx(procedure.InsertIndex(blockID, index))
    24  	}
    25  
    26  	retrieve := func(blockID flow.Identifier) func(tx *badger.Txn) (*flow.Index, error) {
    27  		var index flow.Index
    28  		return func(tx *badger.Txn) (*flow.Index, error) {
    29  			err := procedure.RetrieveIndex(blockID, &index)(tx)
    30  			return &index, err
    31  		}
    32  	}
    33  
    34  	p := &Index{
    35  		db: db,
    36  		cache: newCache[flow.Identifier, *flow.Index](collector, metrics.ResourceIndex,
    37  			withLimit[flow.Identifier, *flow.Index](flow.DefaultTransactionExpiry+100),
    38  			withStore(store),
    39  			withRetrieve(retrieve)),
    40  	}
    41  
    42  	return p
    43  }
    44  
    45  func (i *Index) storeTx(blockID flow.Identifier, index *flow.Index) func(*transaction.Tx) error {
    46  	return i.cache.PutTx(blockID, index)
    47  }
    48  
    49  func (i *Index) retrieveTx(blockID flow.Identifier) func(*badger.Txn) (*flow.Index, error) {
    50  	return func(tx *badger.Txn) (*flow.Index, error) {
    51  		val, err := i.cache.Get(blockID)(tx)
    52  		if err != nil {
    53  			return nil, err
    54  		}
    55  		return val, nil
    56  	}
    57  }
    58  
    59  func (i *Index) Store(blockID flow.Identifier, index *flow.Index) error {
    60  	return operation.RetryOnConflictTx(i.db, transaction.Update, i.storeTx(blockID, index))
    61  }
    62  
    63  func (i *Index) ByBlockID(blockID flow.Identifier) (*flow.Index, error) {
    64  	tx := i.db.NewTransaction(false)
    65  	defer tx.Discard()
    66  	return i.retrieveTx(blockID)(tx)
    67  }