diff --git a/lib/db/db_test.go b/lib/db/db_test.go index fbb6cfc8c..88701b47a 100644 --- a/lib/db/db_test.go +++ b/lib/db/db_test.go @@ -918,6 +918,36 @@ func TestCheckLocalNeed(t *testing.T) { 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) { it, err := db.Backend.NewPrefixIterator([]byte{KeyTypeBlockList}) if err != nil { diff --git a/lib/db/meta.go b/lib/db/meta.go index 28b440c00..01ae8393a 100644 --- a/lib/db/meta.go +++ b/lib/db/meta.go @@ -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) { m.mut.Lock() defer m.mut.Unlock() m.dirty = true - m.indexes[metaKey{dev, needFlag}] = len(m.counts.Counts) - m.counts.Counts = append(m.counts.Counts, Counts{ + empty := Counts{ DeviceID: dev[:], 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