mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-22 22:58:25 +00:00
lib/db need not depend on lib/config
This commit is contained in:
parent
54269553c8
commit
4a9997e449
@ -16,12 +16,9 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/syncthing/protocol"
|
"github.com/syncthing/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/config"
|
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
@ -112,48 +109,21 @@ func (m *BlockMap) blockKey(hash []byte, file string) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BlockFinder struct {
|
type BlockFinder struct {
|
||||||
db *leveldb.DB
|
db *leveldb.DB
|
||||||
folders []string
|
|
||||||
mut sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlockFinder(db *leveldb.DB, cfg *config.Wrapper) *BlockFinder {
|
func NewBlockFinder(db *leveldb.DB) *BlockFinder {
|
||||||
if blockFinder != nil {
|
if blockFinder != nil {
|
||||||
return blockFinder
|
return blockFinder
|
||||||
}
|
}
|
||||||
|
|
||||||
f := &BlockFinder{
|
f := &BlockFinder{
|
||||||
db: db,
|
db: db,
|
||||||
mut: sync.NewRWMutex(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f.CommitConfiguration(config.Configuration{}, cfg.Raw())
|
|
||||||
cfg.Subscribe(f)
|
|
||||||
|
|
||||||
return 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 {
|
func (f *BlockFinder) String() string {
|
||||||
return fmt.Sprintf("BlockFinder@%p", f)
|
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
|
// they are happy with the block) or false to continue iterating for whatever
|
||||||
// reason. The iterator finally returns the result, whether or not a
|
// reason. The iterator finally returns the result, whether or not a
|
||||||
// satisfying block was eventually found.
|
// satisfying block was eventually found.
|
||||||
func (f *BlockFinder) Iterate(hash []byte, iterFn func(string, string, int32) bool) bool {
|
func (f *BlockFinder) Iterate(folders []string, hash []byte, iterFn func(string, string, int32) bool) bool {
|
||||||
f.mut.RLock()
|
|
||||||
folders := f.folders
|
|
||||||
f.mut.RUnlock()
|
|
||||||
for _, folder := range folders {
|
for _, folder := range folders {
|
||||||
key := toBlockKey(hash, folder, "")
|
key := toBlockKey(hash, folder, "")
|
||||||
iter := f.db.NewIterator(util.BytesPrefix(key), nil)
|
iter := f.db.NewIterator(util.BytesPrefix(key), nil)
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/syncthing/protocol"
|
"github.com/syncthing/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/config"
|
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/storage"
|
"github.com/syndtr/goleveldb/leveldb/storage"
|
||||||
@ -30,6 +29,7 @@ func genBlocks(n int) []protocol.BlockInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var f1, f2, f3 protocol.FileInfo
|
var f1, f2, f3 protocol.FileInfo
|
||||||
|
var folders = []string{"folder1", "folder2"}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
blocks := genBlocks(30)
|
blocks := genBlocks(30)
|
||||||
@ -57,16 +57,7 @@ func setup() (*leveldb.DB, *BlockFinder) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
return db, NewBlockFinder(db)
|
||||||
wrapper := config.Wrap("", config.Configuration{})
|
|
||||||
wrapper.SetFolder(config.FolderConfiguration{
|
|
||||||
ID: "folder1",
|
|
||||||
})
|
|
||||||
wrapper.SetFolder(config.FolderConfiguration{
|
|
||||||
ID: "folder2",
|
|
||||||
})
|
|
||||||
|
|
||||||
return db, NewBlockFinder(db, wrapper)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbEmpty(db *leveldb.DB) bool {
|
func dbEmpty(db *leveldb.DB) bool {
|
||||||
@ -94,21 +85,21 @@ func TestBlockMapAddUpdateWipe(t *testing.T) {
|
|||||||
t.Fatal(err)
|
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 {
|
if folder != "folder1" || file != "f1" || index != 0 {
|
||||||
t.Fatal("Mismatch")
|
t.Fatal("Mismatch")
|
||||||
}
|
}
|
||||||
return true
|
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 {
|
if folder != "folder1" || file != "f2" || index != 0 {
|
||||||
t.Fatal("Mismatch")
|
t.Fatal("Mismatch")
|
||||||
}
|
}
|
||||||
return true
|
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")
|
t.Fatal("Unexpected block")
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
@ -123,17 +114,17 @@ func TestBlockMapAddUpdateWipe(t *testing.T) {
|
|||||||
t.Fatal(err)
|
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")
|
t.Fatal("Unexpected block")
|
||||||
return false
|
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")
|
t.Fatal("Unexpected block")
|
||||||
return false
|
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 {
|
if folder != "folder1" || file != "f3" || index != 0 {
|
||||||
t.Fatal("Mismatch")
|
t.Fatal("Mismatch")
|
||||||
}
|
}
|
||||||
@ -180,7 +171,7 @@ func TestBlockFinderLookup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
counter := 0
|
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++
|
counter++
|
||||||
switch counter {
|
switch counter {
|
||||||
case 1:
|
case 1:
|
||||||
@ -196,6 +187,7 @@ func TestBlockFinderLookup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
if counter != 2 {
|
if counter != 2 {
|
||||||
t.Fatal("Incorrect count", counter)
|
t.Fatal("Incorrect count", counter)
|
||||||
}
|
}
|
||||||
@ -208,7 +200,7 @@ func TestBlockFinderLookup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
counter = 0
|
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++
|
counter++
|
||||||
switch counter {
|
switch counter {
|
||||||
case 1:
|
case 1:
|
||||||
@ -220,6 +212,7 @@ func TestBlockFinderLookup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
if counter != 1 {
|
if counter != 1 {
|
||||||
t.Fatal("Incorrect count")
|
t.Fatal("Incorrect count")
|
||||||
}
|
}
|
||||||
@ -240,7 +233,7 @@ func TestBlockFinderFix(t *testing.T) {
|
|||||||
t.Fatal(err)
|
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")
|
t.Fatal("Block not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,11 +242,11 @@ func TestBlockFinderFix(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Iterate(f1.Blocks[0].Hash, iterFn) {
|
if f.Iterate(folders, f1.Blocks[0].Hash, iterFn) {
|
||||||
t.Fatal("Unexpected block")
|
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")
|
t.Fatal("Block not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ func NewModel(cfg *config.Wrapper, id protocol.DeviceID, deviceName, clientName,
|
|||||||
}),
|
}),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
db: ldb,
|
db: ldb,
|
||||||
finder: db.NewBlockFinder(ldb, cfg),
|
finder: db.NewBlockFinder(ldb),
|
||||||
progressEmitter: NewProgressEmitter(cfg),
|
progressEmitter: NewProgressEmitter(cfg),
|
||||||
id: id,
|
id: id,
|
||||||
shortID: id.Short(),
|
shortID: id.Short(),
|
||||||
|
@ -1107,15 +1107,17 @@ func (p *rwFolder) copierRoutine(in <-chan copyBlocksState, pullChan chan<- pull
|
|||||||
}
|
}
|
||||||
|
|
||||||
folderRoots := make(map[string]string)
|
folderRoots := make(map[string]string)
|
||||||
|
var folders []string
|
||||||
p.model.fmut.RLock()
|
p.model.fmut.RLock()
|
||||||
for folder, cfg := range p.model.folderCfgs {
|
for folder, cfg := range p.model.folderCfgs {
|
||||||
folderRoots[folder] = cfg.Path()
|
folderRoots[folder] = cfg.Path()
|
||||||
|
folders = append(folders, folder)
|
||||||
}
|
}
|
||||||
p.model.fmut.RUnlock()
|
p.model.fmut.RUnlock()
|
||||||
|
|
||||||
for _, block := range state.blocks {
|
for _, block := range state.blocks {
|
||||||
buf = buf[:int(block.Size)]
|
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))
|
fd, err := os.Open(filepath.Join(folderRoots[folder], file))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
@ -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}},
|
{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)
|
// Layout of the files: (indexes from the above array)
|
||||||
// 12345678 - Required file
|
// 12345678 - Required file
|
||||||
// 02005008 - Existing file (currently in the index)
|
// 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.
|
// Verify that the blocks we say exist on file, really exist in the db.
|
||||||
for _, idx := range []int{2, 3, 4, 7} {
|
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")
|
t.Error("Didn't find block")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +279,7 @@ func TestCopierCleanup(t *testing.T) {
|
|||||||
// Add file to index
|
// Add file to index
|
||||||
m.updateLocals("default", []protocol.FileInfo{file})
|
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")
|
t.Error("Expected block not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,11 +288,11 @@ func TestCopierCleanup(t *testing.T) {
|
|||||||
// Update index (removing old blocks)
|
// Update index (removing old blocks)
|
||||||
m.updateLocals("default", []protocol.FileInfo{file})
|
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")
|
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")
|
t.Error("Expected block not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,11 +301,11 @@ func TestCopierCleanup(t *testing.T) {
|
|||||||
// Update index (removing old blocks)
|
// Update index (removing old blocks)
|
||||||
m.updateLocals("default", []protocol.FileInfo{file})
|
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")
|
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")
|
t.Error("Expected block not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +336,7 @@ func TestLastResortPulling(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check that that particular block is there
|
// 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")
|
t.Error("Expected block not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,11 +363,11 @@ func TestLastResortPulling(t *testing.T) {
|
|||||||
<-pullChan
|
<-pullChan
|
||||||
|
|
||||||
// Verify that it did fix the incorrect hash.
|
// 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")
|
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")
|
t.Error("Expected block not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user