storage: deduplicate BoltDBBatch/MemoryBatch

BoltDB doesn't have internal batching mechanism, thus we have a substitute for
it, but this substitute is absolutely identical to MemoryBatch, so it's better
to unify them and import ac5d2f94d3 fix into the
MemoryBatch.
This commit is contained in:
Roman Khimov 2019-09-26 18:39:53 +03:00
parent 8bf37f45fc
commit af557cea19
3 changed files with 14 additions and 27 deletions

View file

@ -24,25 +24,6 @@ type BoltDBStore struct {
db *bbolt.DB db *bbolt.DB
} }
// BoltDBBatch simple batch implementation to satisfy the Store interface.
type BoltDBBatch struct {
mem map[*[]byte][]byte
}
// Len implements the Batch interface.
func (b *BoltDBBatch) Len() int {
return len(b.mem)
}
// Put implements the Batch interface.
func (b *BoltDBBatch) Put(k, v []byte) {
vcopy := make([]byte, len(v))
copy(vcopy, v)
kcopy := make([]byte, len(k))
copy(kcopy, k)
b.mem[&kcopy] = vcopy
}
// NewBoltDBStore returns a new ready to use BoltDB storage with created bucket. // NewBoltDBStore returns a new ready to use BoltDB storage with created bucket.
func NewBoltDBStore(cfg BoltDBOptions) (*BoltDBStore, error) { func NewBoltDBStore(cfg BoltDBOptions) (*BoltDBStore, error) {
var opts *bbolt.Options // should be exposed via BoltDBOptions if anything needed var opts *bbolt.Options // should be exposed via BoltDBOptions if anything needed
@ -94,7 +75,7 @@ func (s *BoltDBStore) Get(key []byte) (val []byte, err error) {
func (s *BoltDBStore) PutBatch(batch Batch) error { func (s *BoltDBStore) PutBatch(batch Batch) error {
return s.db.Batch(func(tx *bbolt.Tx) error { return s.db.Batch(func(tx *bbolt.Tx) error {
b := tx.Bucket(Bucket) b := tx.Bucket(Bucket)
for k, v := range batch.(*BoltDBBatch).mem { for k, v := range batch.(*MemoryBatch).m {
err := b.Put(*k, v) err := b.Put(*k, v)
if err != nil { if err != nil {
return err return err
@ -122,9 +103,7 @@ func (s *BoltDBStore) Seek(key []byte, f func(k, v []byte)) {
// Batch implements the Batch interface and returns a boltdb // Batch implements the Batch interface and returns a boltdb
// compatible Batch. // compatible Batch.
func (s *BoltDBStore) Batch() Batch { func (s *BoltDBStore) Batch() Batch {
return &BoltDBBatch{ return newMemoryBatch()
mem: make(map[*[]byte][]byte),
}
} }
// Close releases all db resources. // Close releases all db resources.

View file

@ -12,14 +12,14 @@ import (
func TestBoltDBBatch(t *testing.T) { func TestBoltDBBatch(t *testing.T) {
boltDB := BoltDBStore{} boltDB := BoltDBStore{}
want := &BoltDBBatch{mem: map[*[]byte][]byte{}} want := &MemoryBatch{m: map[*[]byte][]byte{}}
if got := boltDB.Batch(); !reflect.DeepEqual(got, want) { if got := boltDB.Batch(); !reflect.DeepEqual(got, want) {
t.Errorf("BoltDB Batch() = %v, want %v", got, want) t.Errorf("BoltDB Batch() = %v, want %v", got, want)
} }
} }
func TestBoltDBBatch_Len(t *testing.T) { func TestBoltDBBatch_Len(t *testing.T) {
batch := &BoltDBBatch{mem: map[*[]byte][]byte{}} batch := &MemoryBatch{m: map[*[]byte][]byte{}}
want := len(map[*[]byte][]byte{}) want := len(map[*[]byte][]byte{})
assert.Equal(t, want, batch.Len()) assert.Equal(t, want, batch.Len())
} }

View file

@ -20,8 +20,11 @@ type MemoryBatch struct {
// Put implements the Batch interface. // Put implements the Batch interface.
func (b *MemoryBatch) Put(k, v []byte) { func (b *MemoryBatch) Put(k, v []byte) {
key := &k vcopy := make([]byte, len(v))
b.m[key] = v copy(vcopy, v)
kcopy := make([]byte, len(k))
copy(kcopy, k)
b.m[&kcopy] = vcopy
} }
// Len implements the Batch interface. // Len implements the Batch interface.
@ -76,6 +79,11 @@ func (s *MemoryStore) Seek(key []byte, f func(k, v []byte)) {
// Batch implements the Batch interface and returns a compatible Batch. // Batch implements the Batch interface and returns a compatible Batch.
func (s *MemoryStore) Batch() Batch { func (s *MemoryStore) Batch() Batch {
return newMemoryBatch()
}
// newMemoryBatch returns new memory batch.
func newMemoryBatch() *MemoryBatch {
return &MemoryBatch{ return &MemoryBatch{
m: make(map[*[]byte][]byte), m: make(map[*[]byte][]byte),
} }