lib/db: Rework flush hooks (#6838)

This commit is contained in:
Audrius Butkevicius
2020-07-19 08:55:27 +02:00
committed by GitHub
parent 851ee51c1b
commit 55147f5901
8 changed files with 62 additions and 60 deletions
+4 -2
View File
@@ -15,6 +15,8 @@ import (
"github.com/syncthing/syncthing/lib/locations"
)
type CommitHook func(WriteTransaction) error
// The Reader interface specifies the read-only operations available on the
// main database and on read-only transactions (snapshots). Note that when
// called directly on the database handle these operations may take implicit
@@ -61,7 +63,7 @@ type ReadTransaction interface {
type WriteTransaction interface {
ReadTransaction
Writer
Checkpoint(...func() error) error
Checkpoint() error
Commit() error
}
@@ -108,7 +110,7 @@ type Backend interface {
Reader
Writer
NewReadTransaction() (ReadTransaction, error)
NewWriteTransaction() (WriteTransaction, error)
NewWriteTransaction(hooks ...CommitHook) (WriteTransaction, error)
Close() error
Compact() error
}
+18 -11
View File
@@ -69,7 +69,7 @@ func (b *badgerBackend) NewReadTransaction() (ReadTransaction, error) {
}, nil
}
func (b *badgerBackend) NewWriteTransaction() (WriteTransaction, error) {
func (b *badgerBackend) NewWriteTransaction(hooks ...CommitHook) (WriteTransaction, error) {
rel1, err := newReleaser(b.closeWG)
if err != nil {
return nil, err
@@ -90,9 +90,10 @@ func (b *badgerBackend) NewWriteTransaction() (WriteTransaction, error) {
txn: rtxn,
rel: rel1,
},
txn: wtxn,
bdb: b.bdb,
rel: rel2,
txn: wtxn,
bdb: b.bdb,
rel: rel2,
commitHooks: hooks,
}, nil
}
@@ -249,10 +250,11 @@ func (l badgerSnapshot) Release() {
type badgerTransaction struct {
badgerSnapshot
txn *badger.Txn
bdb *badger.DB
rel *releaser
size int
txn *badger.Txn
bdb *badger.DB
rel *releaser
size int
commitHooks []CommitHook
}
func (t *badgerTransaction) Delete(key []byte) error {
@@ -295,15 +297,20 @@ func (t *badgerTransaction) transactionRetried(fn func(*badger.Txn) error) error
func (t *badgerTransaction) Commit() error {
defer t.rel.Release()
defer t.badgerSnapshot.Release()
for _, hook := range t.commitHooks {
if err := hook(t); err != nil {
return err
}
}
return wrapBadgerErr(t.txn.Commit())
}
func (t *badgerTransaction) Checkpoint(preFlush ...func() error) error {
func (t *badgerTransaction) Checkpoint() error {
if t.size < checkpointFlushMinSize {
return nil
}
for _, hook := range preFlush {
if err := hook(); err != nil {
for _, hook := range t.commitHooks {
if err := hook(t); err != nil {
return err
}
}
+14 -12
View File
@@ -59,7 +59,7 @@ func (b *leveldbBackend) newSnapshot() (leveldbSnapshot, error) {
}, nil
}
func (b *leveldbBackend) NewWriteTransaction() (WriteTransaction, error) {
func (b *leveldbBackend) NewWriteTransaction(hooks ...CommitHook) (WriteTransaction, error) {
rel, err := newReleaser(b.closeWG)
if err != nil {
return nil, err
@@ -74,6 +74,7 @@ func (b *leveldbBackend) NewWriteTransaction() (WriteTransaction, error) {
ldb: b.ldb,
batch: new(leveldb.Batch),
rel: rel,
commitHooks: hooks,
}, nil
}
@@ -142,9 +143,10 @@ func (l leveldbSnapshot) Release() {
// an actual leveldb transaction)
type leveldbTransaction struct {
leveldbSnapshot
ldb *leveldb.DB
batch *leveldb.Batch
rel *releaser
ldb *leveldb.DB
batch *leveldb.Batch
rel *releaser
commitHooks []CommitHook
}
func (t *leveldbTransaction) Delete(key []byte) error {
@@ -157,8 +159,8 @@ func (t *leveldbTransaction) Put(key, val []byte) error {
return t.checkFlush(dbFlushBatchMax)
}
func (t *leveldbTransaction) Checkpoint(preFlush ...func() error) error {
return t.checkFlush(dbFlushBatchMin, preFlush...)
func (t *leveldbTransaction) Checkpoint() error {
return t.checkFlush(dbFlushBatchMin)
}
func (t *leveldbTransaction) Commit() error {
@@ -174,19 +176,19 @@ func (t *leveldbTransaction) Release() {
}
// checkFlush flushes and resets the batch if its size exceeds the given size.
func (t *leveldbTransaction) checkFlush(size int, preFlush ...func() error) error {
func (t *leveldbTransaction) checkFlush(size int) error {
if len(t.batch.Dump()) < size {
return nil
}
for _, hook := range preFlush {
if err := hook(); err != nil {
return err
}
}
return t.flush()
}
func (t *leveldbTransaction) flush() error {
for _, hook := range t.commitHooks {
if err := hook(t); err != nil {
return err
}
}
if t.batch.Len() == 0 {
return nil
}