lib/model: Prevent duplicate need count on recalculating metadata (#6964)
This commit is contained in:
@@ -918,6 +918,36 @@ func TestCheckLocalNeed(t *testing.T) {
|
|||||||
checkNeed()
|
checkNeed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDuplicateNeedCount(t *testing.T) {
|
||||||
|
db := NewLowlevel(backend.OpenMemory())
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
folder := "test"
|
||||||
|
testFs := fs.NewFilesystem(fs.FilesystemTypeFake, "")
|
||||||
|
|
||||||
|
fs := NewFileSet(folder, testFs, db)
|
||||||
|
files := []protocol.FileInfo{{Name: "foo", Version: protocol.Vector{}.Update(myID), Sequence: 1}}
|
||||||
|
fs.Update(protocol.LocalDeviceID, files)
|
||||||
|
files[0].Version = files[0].Version.Update(remoteDevice0.Short())
|
||||||
|
fs.Update(remoteDevice0, files)
|
||||||
|
|
||||||
|
db.CheckRepair()
|
||||||
|
|
||||||
|
fs = NewFileSet(folder, testFs, db)
|
||||||
|
found := false
|
||||||
|
for _, c := range fs.meta.counts.Counts {
|
||||||
|
if bytes.Equal(protocol.LocalDeviceID[:], c.DeviceID) && c.LocalFlags == needFlag {
|
||||||
|
if found {
|
||||||
|
t.Fatal("second need count for local device encountered")
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Fatal("no need count for local device encountered")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func numBlockLists(db *Lowlevel) (int, error) {
|
func numBlockLists(db *Lowlevel) (int, error) {
|
||||||
it, err := db.Backend.NewPrefixIterator([]byte{KeyTypeBlockList})
|
it, err := db.Backend.NewPrefixIterator([]byte{KeyTypeBlockList})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+10
-4
@@ -198,18 +198,24 @@ func (m *metadataTracker) updateFileLocked(dev protocol.DeviceID, f protocol.Fil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// emptyNeeded makes sure there is a zero counts in case the device needs nothing.
|
// emptyNeeded ensures that there is a need count for the given device and that it is empty.
|
||||||
func (m *metadataTracker) emptyNeeded(dev protocol.DeviceID) {
|
func (m *metadataTracker) emptyNeeded(dev protocol.DeviceID) {
|
||||||
m.mut.Lock()
|
m.mut.Lock()
|
||||||
defer m.mut.Unlock()
|
defer m.mut.Unlock()
|
||||||
|
|
||||||
m.dirty = true
|
m.dirty = true
|
||||||
|
|
||||||
m.indexes[metaKey{dev, needFlag}] = len(m.counts.Counts)
|
empty := Counts{
|
||||||
m.counts.Counts = append(m.counts.Counts, Counts{
|
|
||||||
DeviceID: dev[:],
|
DeviceID: dev[:],
|
||||||
LocalFlags: needFlag,
|
LocalFlags: needFlag,
|
||||||
})
|
}
|
||||||
|
key := metaKey{dev, needFlag}
|
||||||
|
if idx, ok := m.indexes[key]; ok {
|
||||||
|
m.counts.Counts[idx] = empty
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m.indexes[key] = len(m.counts.Counts)
|
||||||
|
m.counts.Counts = append(m.counts.Counts, empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// addNeeded adds a file to the needed counts
|
// addNeeded adds a file to the needed counts
|
||||||
|
|||||||
Reference in New Issue
Block a user