github.com/onflow/flow-go@v0.33.17/storage/badger/index.go (about)

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