github.com/lazyledger/lazyledger-core@v0.35.0-dev.0.20210613111200-4c651f053571/libs/db/memdb/batch.go (about)

     1  package memdb
     2  
     3  import (
     4  	"fmt"
     5  
     6  	lldb "github.com/lazyledger/lazyledger-core/libs/db"
     7  )
     8  
     9  // memDBBatch operations
    10  type opType int
    11  
    12  const (
    13  	opTypeSet opType = iota + 1
    14  	opTypeDelete
    15  )
    16  
    17  type operation struct {
    18  	opType
    19  	key   []byte
    20  	value []byte
    21  }
    22  
    23  // memDBBatch handles in-memory batching.
    24  type memDBBatch struct {
    25  	db  *MemDB
    26  	ops []operation
    27  }
    28  
    29  var _ lldb.Batch = (*memDBBatch)(nil)
    30  
    31  // newMemDBBatch creates a new memDBBatch
    32  func newMemDBBatch(db *MemDB) *memDBBatch {
    33  	return &memDBBatch{
    34  		db:  db,
    35  		ops: []operation{},
    36  	}
    37  }
    38  
    39  // Set implements Batch.
    40  func (b *memDBBatch) Set(key, value []byte) error {
    41  	if len(key) == 0 {
    42  		return lldb.ErrKeyEmpty
    43  	}
    44  	if value == nil {
    45  		return lldb.ErrValueNil
    46  	}
    47  	if b.ops == nil {
    48  		return lldb.ErrBatchClosed
    49  	}
    50  	b.ops = append(b.ops, operation{opTypeSet, key, value})
    51  	return nil
    52  }
    53  
    54  // Delete implements Batch.
    55  func (b *memDBBatch) Delete(key []byte) error {
    56  	if len(key) == 0 {
    57  		return lldb.ErrKeyEmpty
    58  	}
    59  	if b.ops == nil {
    60  		return lldb.ErrBatchClosed
    61  	}
    62  	b.ops = append(b.ops, operation{opTypeDelete, key, nil})
    63  	return nil
    64  }
    65  
    66  // Write implements Batch.
    67  func (b *memDBBatch) Write() error {
    68  	if b.ops == nil {
    69  		return lldb.ErrBatchClosed
    70  	}
    71  	b.db.mtx.Lock()
    72  	defer b.db.mtx.Unlock()
    73  
    74  	for _, op := range b.ops {
    75  		switch op.opType {
    76  		case opTypeSet:
    77  			b.db.set(op.key, op.value)
    78  		case opTypeDelete:
    79  			b.db.delete(op.key)
    80  		default:
    81  			return fmt.Errorf("unknown operation type %v (%v)", op.opType, op)
    82  		}
    83  	}
    84  
    85  	// Make sure batch cannot be used afterwards. Callers should still call Close(), for errors.
    86  	return b.Close()
    87  }
    88  
    89  // WriteSync implements Batch.
    90  func (b *memDBBatch) WriteSync() error {
    91  	return b.Write()
    92  }
    93  
    94  // Close implements Batch.
    95  func (b *memDBBatch) Close() error {
    96  	b.ops = nil
    97  	return nil
    98  }