diff --git a/lib/db/blockmap.go b/lib/db/blockmap.go index 40c40076b..3caa9ff5b 100644 --- a/lib/db/blockmap.go +++ b/lib/db/blockmap.go @@ -16,12 +16,9 @@ import ( "bytes" "encoding/binary" "fmt" - "sort" "github.com/syncthing/protocol" - "github.com/syncthing/syncthing/lib/config" "github.com/syncthing/syncthing/lib/osutil" - "github.com/syncthing/syncthing/lib/sync" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/util" @@ -112,48 +109,21 @@ func (m *BlockMap) blockKey(hash []byte, file string) []byte { } type BlockFinder struct { - db *leveldb.DB - folders []string - mut sync.RWMutex + db *leveldb.DB } -func NewBlockFinder(db *leveldb.DB, cfg *config.Wrapper) *BlockFinder { +func NewBlockFinder(db *leveldb.DB) *BlockFinder { if blockFinder != nil { return blockFinder } f := &BlockFinder{ - db: db, - mut: sync.NewRWMutex(), + db: db, } - f.CommitConfiguration(config.Configuration{}, cfg.Raw()) - cfg.Subscribe(f) - return f } -// VerifyConfiguration implementes the config.Committer interface -func (f *BlockFinder) VerifyConfiguration(from, to config.Configuration) error { - return nil -} - -// CommitConfiguration implementes the config.Committer interface -func (f *BlockFinder) CommitConfiguration(from, to config.Configuration) bool { - folders := make([]string, len(to.Folders)) - for i, folder := range to.Folders { - folders[i] = folder.ID - } - - sort.Strings(folders) - - f.mut.Lock() - f.folders = folders - f.mut.Unlock() - - return true -} - func (f *BlockFinder) String() string { return fmt.Sprintf("BlockFinder@%p", f) } @@ -163,10 +133,7 @@ func (f *BlockFinder) String() string { // they are happy with the block) or false to continue iterating for whatever // reason. The iterator finally returns the result, whether or not a // satisfying block was eventually found. -func (f *BlockFinder) Iterate(hash []byte, iterFn func(string, string, int32) bool) bool { - f.mut.RLock() - folders := f.folders - f.mut.RUnlock() +func (f *BlockFinder) Iterate(folders []string, hash []byte, iterFn func(string, string, int32) bool) bool { for _, folder := range folders { key := toBlockKey(hash, folder, "") iter := f.db.NewIterator(util.BytesPrefix(key), nil) diff --git a/lib/db/blockmap_test.go b/lib/db/blockmap_test.go index e0fdf7c40..3a1587038 100644 --- a/lib/db/blockmap_test.go +++ b/lib/db/blockmap_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/syncthing/protocol" - "github.com/syncthing/syncthing/lib/config" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/storage" @@ -30,6 +29,7 @@ func genBlocks(n int) []protocol.BlockInfo { } var f1, f2, f3 protocol.FileInfo +var folders = []string{"folder1", "folder2"} func init() { blocks := genBlocks(30) @@ -57,16 +57,7 @@ func setup() (*leveldb.DB, *BlockFinder) { if err != nil { panic(err) } - - wrapper := config.Wrap("", config.Configuration{}) - wrapper.SetFolder(config.FolderConfiguration{ - ID: "folder1", - }) - wrapper.SetFolder(config.FolderConfiguration{ - ID: "folder2", - }) - - return db, NewBlockFinder(db, wrapper) + return db, NewBlockFinder(db) } func dbEmpty(db *leveldb.DB) bool { @@ -94,21 +85,21 @@ func TestBlockMapAddUpdateWipe(t *testing.T) { t.Fatal(err) } - f.Iterate(f1.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool { if folder != "folder1" || file != "f1" || index != 0 { t.Fatal("Mismatch") } return true }) - f.Iterate(f2.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f2.Blocks[0].Hash, func(folder, file string, index int32) bool { if folder != "folder1" || file != "f2" || index != 0 { t.Fatal("Mismatch") } return true }) - f.Iterate(f3.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f3.Blocks[0].Hash, func(folder, file string, index int32) bool { t.Fatal("Unexpected block") return true }) @@ -123,17 +114,17 @@ func TestBlockMapAddUpdateWipe(t *testing.T) { t.Fatal(err) } - f.Iterate(f1.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool { t.Fatal("Unexpected block") return false }) - f.Iterate(f2.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f2.Blocks[0].Hash, func(folder, file string, index int32) bool { t.Fatal("Unexpected block") return false }) - f.Iterate(f3.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f3.Blocks[0].Hash, func(folder, file string, index int32) bool { if folder != "folder1" || file != "f3" || index != 0 { t.Fatal("Mismatch") } @@ -180,7 +171,7 @@ func TestBlockFinderLookup(t *testing.T) { } counter := 0 - f.Iterate(f1.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool { counter++ switch counter { case 1: @@ -196,6 +187,7 @@ func TestBlockFinderLookup(t *testing.T) { } return false }) + if counter != 2 { t.Fatal("Incorrect count", counter) } @@ -208,7 +200,7 @@ func TestBlockFinderLookup(t *testing.T) { } counter = 0 - f.Iterate(f1.Blocks[0].Hash, func(folder, file string, index int32) bool { + f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool { counter++ switch counter { case 1: @@ -220,6 +212,7 @@ func TestBlockFinderLookup(t *testing.T) { } return false }) + if counter != 1 { t.Fatal("Incorrect count") } @@ -240,7 +233,7 @@ func TestBlockFinderFix(t *testing.T) { t.Fatal(err) } - if !f.Iterate(f1.Blocks[0].Hash, iterFn) { + if !f.Iterate(folders, f1.Blocks[0].Hash, iterFn) { t.Fatal("Block not found") } @@ -249,11 +242,11 @@ func TestBlockFinderFix(t *testing.T) { t.Fatal(err) } - if f.Iterate(f1.Blocks[0].Hash, iterFn) { + if f.Iterate(folders, f1.Blocks[0].Hash, iterFn) { t.Fatal("Unexpected block") } - if !f.Iterate(f2.Blocks[0].Hash, iterFn) { + if !f.Iterate(folders, f2.Blocks[0].Hash, iterFn) { t.Fatal("Block not found") } } diff --git a/lib/model/model.go b/lib/model/model.go index 367bd5db7..425cbfc51 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -114,7 +114,7 @@ func NewModel(cfg *config.Wrapper, id protocol.DeviceID, deviceName, clientName, }), cfg: cfg, db: ldb, - finder: db.NewBlockFinder(ldb, cfg), + finder: db.NewBlockFinder(ldb), progressEmitter: NewProgressEmitter(cfg), id: id, shortID: id.Short(), diff --git a/lib/model/rwfolder.go b/lib/model/rwfolder.go index ed48d4b45..d08a1f700 100644 --- a/lib/model/rwfolder.go +++ b/lib/model/rwfolder.go @@ -1107,15 +1107,17 @@ func (p *rwFolder) copierRoutine(in <-chan copyBlocksState, pullChan chan<- pull } folderRoots := make(map[string]string) + var folders []string p.model.fmut.RLock() for folder, cfg := range p.model.folderCfgs { folderRoots[folder] = cfg.Path() + folders = append(folders, folder) } p.model.fmut.RUnlock() for _, block := range state.blocks { buf = buf[:int(block.Size)] - found := p.model.finder.Iterate(block.Hash, func(folder, file string, index int32) bool { + found := p.model.finder.Iterate(folders, block.Hash, func(folder, file string, index int32) bool { fd, err := os.Open(filepath.Join(folderRoots[folder], file)) if err != nil { return false diff --git a/lib/model/rwfolder_test.go b/lib/model/rwfolder_test.go index b6369c8ca..df34fdf4a 100644 --- a/lib/model/rwfolder_test.go +++ b/lib/model/rwfolder_test.go @@ -42,6 +42,8 @@ var blocks = []protocol.BlockInfo{ {Offset: 917504, Size: 0x20000, Hash: []uint8{0x96, 0x6b, 0x15, 0x6b, 0xc4, 0xf, 0x19, 0x18, 0xca, 0xbb, 0x5f, 0xd6, 0xbb, 0xa2, 0xc6, 0x2a, 0xac, 0xbb, 0x8a, 0xb9, 0xce, 0xec, 0x4c, 0xdb, 0x78, 0xec, 0x57, 0x5d, 0x33, 0xf9, 0x8e, 0xaf}}, } +var folders = []string{"default"} + // Layout of the files: (indexes from the above array) // 12345678 - Required file // 02005008 - Existing file (currently in the index) @@ -197,7 +199,7 @@ func TestCopierFinder(t *testing.T) { // Verify that the blocks we say exist on file, really exist in the db. for _, idx := range []int{2, 3, 4, 7} { - if m.finder.Iterate(blocks[idx].Hash, iterFn) == false { + if m.finder.Iterate(folders, blocks[idx].Hash, iterFn) == false { t.Error("Didn't find block") } } @@ -277,7 +279,7 @@ func TestCopierCleanup(t *testing.T) { // Add file to index m.updateLocals("default", []protocol.FileInfo{file}) - if !m.finder.Iterate(blocks[0].Hash, iterFn) { + if !m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Expected block not found") } @@ -286,11 +288,11 @@ func TestCopierCleanup(t *testing.T) { // Update index (removing old blocks) m.updateLocals("default", []protocol.FileInfo{file}) - if m.finder.Iterate(blocks[0].Hash, iterFn) { + if m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Unexpected block found") } - if !m.finder.Iterate(blocks[1].Hash, iterFn) { + if !m.finder.Iterate(folders, blocks[1].Hash, iterFn) { t.Error("Expected block not found") } @@ -299,11 +301,11 @@ func TestCopierCleanup(t *testing.T) { // Update index (removing old blocks) m.updateLocals("default", []protocol.FileInfo{file}) - if !m.finder.Iterate(blocks[0].Hash, iterFn) { + if !m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Unexpected block found") } - if m.finder.Iterate(blocks[1].Hash, iterFn) { + if m.finder.Iterate(folders, blocks[1].Hash, iterFn) { t.Error("Expected block not found") } } @@ -334,7 +336,7 @@ func TestLastResortPulling(t *testing.T) { } // Check that that particular block is there - if !m.finder.Iterate(blocks[0].Hash, iterFn) { + if !m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Expected block not found") } @@ -361,11 +363,11 @@ func TestLastResortPulling(t *testing.T) { <-pullChan // Verify that it did fix the incorrect hash. - if m.finder.Iterate(blocks[0].Hash, iterFn) { + if m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Found unexpected block") } - if !m.finder.Iterate(scanner.SHA256OfNothing, iterFn) { + if !m.finder.Iterate(folders, scanner.SHA256OfNothing, iterFn) { t.Error("Expected block not found") }