Jelajahi Sumber

lib/db: Update global count when removing the previous global version (#4968)

Simon Frei 7 tahun lalu
induk
melakukan
ef1633ac76
2 mengubah file dengan 82 tambahan dan 14 penghapusan
  1. 22 14
      lib/db/leveldb_transactions.go
  2. 60 0
      lib/db/set_test.go

+ 22 - 14
lib/db/leveldb_transactions.go

@@ -160,22 +160,30 @@ insert:
 		fl.Versions = append(fl.Versions, nv)
 		insertedAt = len(fl.Versions) - 1
 	}
-
-	if insertedAt == 0 {
-		// We just inserted a new newest version. Fixup the global size
-		// calculation.
-		if !file.Version.Equal(oldFile.Version) || file.Invalid != oldFile.Invalid {
+	// Fixup the global size calculation.
+	if hasOldFile {
+		// We removed the previous newest version
+		meta.removeFile(globalDeviceID, oldFile)
+		if insertedAt == 0 {
+			// inserted a new newest version
 			meta.addFile(globalDeviceID, file)
-			if hasOldFile {
-				// We have the old file that was removed at the head of the list.
+		} else {
+			// The previous second version is now the first
+			if newGlobal, ok := t.getFile(folder, fl.Versions[0].Device, name); ok {
+				// A failure to get the file here is surprising and our
+				// global size data will be incorrect until a restart...
+				meta.addFile(globalDeviceID, newGlobal)
+			}
+		}
+	} else if insertedAt == 0 {
+		// We just inserted a new newest version.
+		meta.addFile(globalDeviceID, file)
+		if len(fl.Versions) > 1 {
+			// The previous newest version is now at index 1, grab it from there.
+			if oldFile, ok := t.getFile(folder, fl.Versions[1].Device, name); ok {
+				// A failure to get the file here is surprising and our
+				// global size data will be incorrect until a restart...
 				meta.removeFile(globalDeviceID, oldFile)
-			} else if len(fl.Versions) > 1 {
-				// The previous newest version is now at index 1, grab it from there.
-				if oldFile, ok := t.getFile(folder, fl.Versions[1].Device, name); ok {
-					// A failure to get the file here is surprising and our
-					// global size data will be incorrect until a restart...
-					meta.removeFile(globalDeviceID, oldFile)
-				}
 			}
 		}
 	}

+ 60 - 0
lib/db/set_test.go

@@ -937,6 +937,66 @@ func TestIssue4925(t *testing.T) {
 	}
 }
 
+func TestMoveGlobalBack(t *testing.T) {
+	ldb := db.OpenMemory()
+
+	folder := "test"
+	file := "foo"
+	s := db.NewFileSet(folder, fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
+
+	localHave := fileList{{Name: file, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1}}}, Blocks: genBlocks(1), ModifiedS: 10, Size: 1}}
+	remote0Have := fileList{{Name: file, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1}, {ID: remoteDevice0.Short(), Value: 1}}}, Blocks: genBlocks(2), ModifiedS: 0, Size: 2}}
+
+	s.Update(protocol.LocalDeviceID, localHave)
+	s.Update(remoteDevice0, remote0Have)
+
+	if need := needList(s, protocol.LocalDeviceID); len(need) != 1 {
+		t.Error("Expected 1 local need, got", need)
+	} else if !need[0].IsEquivalent(remote0Have[0], false, false) {
+		t.Errorf("Local need incorrect;\n A: %v !=\n E: %v", need[0], remote0Have[0])
+	}
+
+	if need := needList(s, remoteDevice0); len(need) != 0 {
+		t.Error("Expected no need for remote 0, got", need)
+	}
+
+	ls := s.LocalSize()
+	if haveBytes := localHave[0].Size; ls.Bytes != haveBytes {
+		t.Errorf("Incorrect LocalSize bytes; %d != %d", ls.Bytes, haveBytes)
+	}
+
+	gs := s.GlobalSize()
+	if globalBytes := remote0Have[0].Size; gs.Bytes != globalBytes {
+		t.Errorf("Incorrect GlobalSize bytes; %d != %d", gs.Bytes, globalBytes)
+	}
+
+	// That's what happens when something becomes unignored or something.
+	// In any case it will be moved back from first spot in the global list
+	// which is the scenario to be tested here.
+	remote0Have[0].Version = remote0Have[0].Version.Update(remoteDevice0.Short()).DropOthers(remoteDevice0.Short())
+	s.Update(remoteDevice0, remote0Have)
+
+	if need := needList(s, remoteDevice0); len(need) != 1 {
+		t.Error("Expected 1 need for remote 0, got", need)
+	} else if !need[0].IsEquivalent(localHave[0], false, false) {
+		t.Errorf("Need for remote 0 incorrect;\n A: %v !=\n E: %v", need[0], localHave[0])
+	}
+
+	if need := needList(s, protocol.LocalDeviceID); len(need) != 0 {
+		t.Error("Expected no local need, got", need)
+	}
+
+	ls = s.LocalSize()
+	if haveBytes := localHave[0].Size; ls.Bytes != haveBytes {
+		t.Errorf("Incorrect LocalSize bytes; %d != %d", ls.Bytes, haveBytes)
+	}
+
+	gs = s.GlobalSize()
+	if globalBytes := localHave[0].Size; gs.Bytes != globalBytes {
+		t.Errorf("Incorrect GlobalSize bytes; %d != %d", gs.Bytes, globalBytes)
+	}
+}
+
 func replace(fs *db.FileSet, device protocol.DeviceID, files []protocol.FileInfo) {
 	fs.Drop(device)
 	fs.Update(device, files)