Browse Source

lib/db: Use need func in withNeed and simplify (#6412)

Simon Frei 5 năm trước cách đây
mục cha
commit
a1cb1d70c4
1 tập tin đã thay đổi với 26 bổ sung45 xóa
  1. 26 45
      lib/db/transactions.go

+ 26 - 45
lib/db/transactions.go

@@ -8,11 +8,20 @@ package db
 
 import (
 	"bytes"
+	"fmt"
 
 	"github.com/syncthing/syncthing/lib/db/backend"
 	"github.com/syncthing/syncthing/lib/protocol"
 )
 
+type errDeviceEntryMissing struct {
+	name string
+}
+
+func (err errDeviceEntryMissing) Error() string {
+	return fmt.Sprintf("device present in global list but missing as device/fileinfo entry: %s", err.name)
+}
+
 // A readOnlyTransaction represents a database snapshot.
 type readOnlyTransaction struct {
 	backend.ReadTransaction
@@ -344,53 +353,25 @@ func (t *readOnlyTransaction) withNeed(folder, device []byte, truncate bool, fn
 		}
 
 		haveFV, have := vl.Get(device)
-		// XXX: This marks Concurrent (i.e. conflicting) changes as
-		// needs. Maybe we should do that, but it needs special
-		// handling in the puller.
-		if have && haveFV.Version.GreaterEqual(vl.Versions[0].Version) {
-			continue
-		}
 
 		name := t.keyer.NameFromGlobalVersionKey(dbi.Key())
-		needVersion := vl.Versions[0].Version
-		needDevice := protocol.DeviceIDFromBytes(vl.Versions[0].Device)
-
-		for i := range vl.Versions {
-			if !vl.Versions[i].Version.Equal(needVersion) {
-				// We haven't found a valid copy of the file with the needed version.
-				break
-			}
-
-			if vl.Versions[i].Invalid {
-				// The file is marked invalid, don't use it.
-				continue
-			}
-
-			dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, vl.Versions[i].Device, name)
-			if err != nil {
-				return err
-			}
-			gf, ok, err := t.getFileTrunc(dk, truncate)
-			if err != nil {
-				return err
-			}
-			if !ok {
-				continue
-			}
-
-			if gf.IsDeleted() && !have {
-				// We don't need deleted files that we don't have
-				break
-			}
-
-			l.Debugf("need folder=%q device=%v name=%q have=%v invalid=%v haveV=%v globalV=%v globalDev=%v", folder, devID, name, have, haveFV.Invalid, haveFV.Version, needVersion, needDevice)
-
-			if !fn(gf) {
-				return nil
-			}
-
-			// This file is handled, no need to look further in the version list
-			break
+		dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, vl.Versions[0].Device, name)
+		if err != nil {
+			return err
+		}
+		gf, ok, err := t.getFileTrunc(dk, truncate)
+		if err != nil {
+			return err
+		}
+		if !ok {
+			return errDeviceEntryMissing{string(name)}
+		}
+		if !need(gf, have, haveFV.Version) {
+			continue
+		}
+		l.Debugf("need folder=%q device=%v name=%q have=%v invalid=%v haveV=%v globalV=%v globalDev=%v", folder, devID, name, have, haveFV.Invalid, haveFV.Version, vl.Versions[0].Version, vl.Versions[0].Device)
+		if !fn(gf) {
+			return dbi.Error()
 		}
 	}
 	return dbi.Error()