Просмотр исходного кода

lib/db: Commit meta when dropping device (#6862)

Simon Frei 5 лет назад
Родитель
Сommit
424d1b1608
2 измененных файлов с 18 добавлено и 17 удалено
  1. 8 6
      lib/db/backend/backend.go
  2. 10 11
      lib/db/lowlevel.go

+ 8 - 6
lib/db/backend/backend.go

@@ -15,6 +15,9 @@ import (
 	"github.com/syncthing/syncthing/lib/locations"
 )
 
+// CommitHook is a function that is executed before a WriteTransaction is
+// committed or before it is flushed to disk, e.g. on calling CheckPoint. The
+// transaction can be accessed via a closure.
 type CommitHook func(WriteTransaction) error
 
 // The Reader interface specifies the read-only operations available on the
@@ -54,12 +57,11 @@ type ReadTransaction interface {
 // A Checkpoint is a potential partial commit of the transaction so far, for
 // purposes of saving memory when transactions are in-RAM. Note that
 // transactions may be checkpointed *anyway* even if this is not called, due to
-// resource constraints, but this gives you a chance to decide when.
-//
-// Functions can be passed to Checkpoint. These are run if and only if the
-// checkpoint will result in a flush, and will run before the flush. The
-// transaction can be accessed via a closure. If an error is returned from
-// these functions the flush will be aborted and the error bubbled.
+// resource constraints, but this gives you a chance to decide when. If, and
+// only if, calling Checkpoint will result in a partial commit/flush, the
+// CommitHooks passed to Backend.NewWriteTransaction are called before
+// committing. If any of those returns an error, committing is aborted and the
+// error bubbled.
 type WriteTransaction interface {
 	ReadTransaction
 	Writer

+ 10 - 11
lib/db/lowlevel.go

@@ -362,7 +362,7 @@ func (db *Lowlevel) dropDeviceFolder(device, folder []byte, meta *metadataTracke
 	db.gcMut.RLock()
 	defer db.gcMut.RUnlock()
 
-	t, err := db.newReadWriteTransaction()
+	t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
 	if err != nil {
 		return err
 	}
@@ -843,20 +843,22 @@ func (db *Lowlevel) loadMetadataTracker(folder string) *metadataTracker {
 	return meta
 }
 
-func (db *Lowlevel) recalcMeta(folder string) (*metadataTracker, error) {
+func (db *Lowlevel) recalcMeta(folderStr string) (*metadataTracker, error) {
+	folder := []byte(folderStr)
+
 	meta := newMetadataTracker(db.keyer)
-	if err := db.checkGlobals([]byte(folder)); err != nil {
+	if err := db.checkGlobals(folder); err != nil {
 		return nil, err
 	}
 
-	t, err := db.newReadWriteTransaction()
+	t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
 	if err != nil {
 		return nil, err
 	}
 	defer t.close()
 
 	var deviceID protocol.DeviceID
-	err = t.withAllFolderTruncated([]byte(folder), func(device []byte, f FileInfoTruncated) bool {
+	err = t.withAllFolderTruncated(folder, func(device []byte, f FileInfoTruncated) bool {
 		copy(deviceID[:], device)
 		meta.addFile(deviceID, f)
 		return true
@@ -865,13 +867,13 @@ func (db *Lowlevel) recalcMeta(folder string) (*metadataTracker, error) {
 		return nil, err
 	}
 
-	err = t.withGlobal([]byte(folder), nil, true, func(f protocol.FileIntf) bool {
+	err = t.withGlobal(folder, nil, true, func(f protocol.FileIntf) bool {
 		meta.addFile(protocol.GlobalDeviceID, f)
 		return true
 	})
 
 	meta.emptyNeeded(protocol.LocalDeviceID)
-	err = t.withNeed([]byte(folder), protocol.LocalDeviceID[:], true, func(f protocol.FileIntf) bool {
+	err = t.withNeed(folder, protocol.LocalDeviceID[:], true, func(f protocol.FileIntf) bool {
 		meta.addNeeded(protocol.LocalDeviceID, f)
 		return true
 	})
@@ -880,7 +882,7 @@ func (db *Lowlevel) recalcMeta(folder string) (*metadataTracker, error) {
 	}
 	for _, device := range meta.devices() {
 		meta.emptyNeeded(device)
-		err = t.withNeed([]byte(folder), device[:], true, func(f protocol.FileIntf) bool {
+		err = t.withNeed(folder, device[:], true, func(f protocol.FileIntf) bool {
 			meta.addNeeded(device, f)
 			return true
 		})
@@ -890,9 +892,6 @@ func (db *Lowlevel) recalcMeta(folder string) (*metadataTracker, error) {
 	}
 
 	meta.SetCreated()
-	if err := meta.toDB(t, []byte(folder)); err != nil {
-		return nil, err
-	}
 	if err := t.Commit(); err != nil {
 		return nil, err
 	}