github.com/koko1123/flow-go-1@v0.29.6/storage/badger/commits.go (about) 1 package badger 2 3 import ( 4 "github.com/dgraph-io/badger/v3" 5 6 "github.com/koko1123/flow-go-1/model/flow" 7 "github.com/koko1123/flow-go-1/module" 8 "github.com/koko1123/flow-go-1/module/metrics" 9 "github.com/koko1123/flow-go-1/storage" 10 "github.com/koko1123/flow-go-1/storage/badger/operation" 11 "github.com/koko1123/flow-go-1/storage/badger/transaction" 12 ) 13 14 type Commits struct { 15 db *badger.DB 16 cache *Cache 17 } 18 19 func NewCommits(collector module.CacheMetrics, db *badger.DB) *Commits { 20 21 store := func(key interface{}, val interface{}) func(*transaction.Tx) error { 22 blockID := key.(flow.Identifier) 23 commit := val.(flow.StateCommitment) 24 return transaction.WithTx(operation.SkipDuplicates(operation.IndexStateCommitment(blockID, commit))) 25 } 26 27 retrieve := func(key interface{}) func(tx *badger.Txn) (interface{}, error) { 28 blockID := key.(flow.Identifier) 29 var commit flow.StateCommitment 30 return func(tx *badger.Txn) (interface{}, error) { 31 err := operation.LookupStateCommitment(blockID, &commit)(tx) 32 return commit, err 33 } 34 } 35 36 c := &Commits{ 37 db: db, 38 cache: newCache(collector, metrics.ResourceCommit, 39 withLimit(1000), 40 withStore(store), 41 withRetrieve(retrieve), 42 ), 43 } 44 45 return c 46 } 47 48 func (c *Commits) storeTx(blockID flow.Identifier, commit flow.StateCommitment) func(*transaction.Tx) error { 49 return c.cache.PutTx(blockID, commit) 50 } 51 52 func (c *Commits) retrieveTx(blockID flow.Identifier) func(tx *badger.Txn) (flow.StateCommitment, error) { 53 return func(tx *badger.Txn) (flow.StateCommitment, error) { 54 val, err := c.cache.Get(blockID)(tx) 55 if err != nil { 56 return flow.DummyStateCommitment, err 57 } 58 return val.(flow.StateCommitment), nil 59 } 60 } 61 62 func (c *Commits) Store(blockID flow.Identifier, commit flow.StateCommitment) error { 63 return operation.RetryOnConflictTx(c.db, transaction.Update, c.storeTx(blockID, commit)) 64 } 65 66 // BatchStore stores Commit keyed by blockID in provided batch 67 // No errors are expected during normal operation, even if no entries are matched. 68 // If Badger unexpectedly fails to process the request, the error is wrapped in a generic error and returned. 69 func (c *Commits) BatchStore(blockID flow.Identifier, commit flow.StateCommitment, batch storage.BatchStorage) error { 70 // we can't cache while using batches, as it's unknown at this point when, and if 71 // the batch will be committed. Cache will be populated on read however. 72 writeBatch := batch.GetWriter() 73 return operation.BatchIndexStateCommitment(blockID, commit)(writeBatch) 74 } 75 76 func (c *Commits) ByBlockID(blockID flow.Identifier) (flow.StateCommitment, error) { 77 tx := c.db.NewTransaction(false) 78 defer tx.Discard() 79 return c.retrieveTx(blockID)(tx) 80 } 81 82 func (c *Commits) RemoveByBlockID(blockID flow.Identifier) error { 83 return c.db.Update(operation.SkipNonExist(operation.RemoveStateCommitment(blockID))) 84 } 85 86 // BatchRemoveByBlockID removes Commit keyed by blockID in provided batch 87 // No errors are expected during normal operation, even if no entries are matched. 88 // If Badger unexpectedly fails to process the request, the error is wrapped in a generic error and returned. 89 func (c *Commits) BatchRemoveByBlockID(blockID flow.Identifier, batch storage.BatchStorage) error { 90 writeBatch := batch.GetWriter() 91 return operation.BatchRemoveStateCommitment(blockID)(writeBatch) 92 }