github.com/MetalBlockchain/metalgo@v1.11.9/database/batch.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 // For ease of implementation, our database's interface matches Ethereum's 5 // database implementation. This was to allow us to use Geth code as is for the 6 // EVM chain. 7 8 package database 9 10 import "slices" 11 12 // Batch is a write-only database that commits changes to its host database 13 // when Write is called. A batch cannot be used concurrently. 14 type Batch interface { 15 KeyValueWriterDeleter 16 17 // Size retrieves the amount of data queued up for writing, this includes 18 // the keys, values, and deleted keys. 19 Size() int 20 21 // Write flushes any accumulated data to disk. 22 Write() error 23 24 // Reset resets the batch for reuse. 25 Reset() 26 27 // Replay replays the batch contents in the same order they were written 28 // to the batch. 29 Replay(w KeyValueWriterDeleter) error 30 31 // Inner returns a Batch writing to the inner database, if one exists. If 32 // this batch is already writing to the base DB, then itself should be 33 // returned. 34 Inner() Batch 35 } 36 37 // Batcher wraps the NewBatch method of a backing data store. 38 type Batcher interface { 39 // NewBatch creates a write-only database that buffers changes to its host db 40 // until a final write is called. 41 NewBatch() Batch 42 } 43 44 type BatchOp struct { 45 Key []byte 46 Value []byte 47 Delete bool 48 } 49 50 type BatchOps struct { 51 Ops []BatchOp 52 size int 53 } 54 55 func (b *BatchOps) Put(key, value []byte) error { 56 b.Ops = append(b.Ops, BatchOp{ 57 Key: slices.Clone(key), 58 Value: slices.Clone(value), 59 }) 60 b.size += len(key) + len(value) 61 return nil 62 } 63 64 func (b *BatchOps) Delete(key []byte) error { 65 b.Ops = append(b.Ops, BatchOp{ 66 Key: slices.Clone(key), 67 Delete: true, 68 }) 69 b.size += len(key) 70 return nil 71 } 72 73 func (b *BatchOps) Size() int { 74 return b.size 75 } 76 77 func (b *BatchOps) Reset() { 78 b.Ops = b.Ops[:0] 79 b.size = 0 80 } 81 82 func (b *BatchOps) Replay(w KeyValueWriterDeleter) error { 83 for _, op := range b.Ops { 84 if op.Delete { 85 if err := w.Delete(op.Key); err != nil { 86 return err 87 } 88 } else if err := w.Put(op.Key, op.Value); err != nil { 89 return err 90 } 91 } 92 return nil 93 }