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