mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-24 07:28:27 +00:00
Handle needed files in batches
This commit is contained in:
parent
32a5e83612
commit
7943902d73
@ -207,8 +207,8 @@ func ldbReplace(db *leveldb.DB, repo, node []byte, fs []protocol.FileInfo) uint6
|
|||||||
if debug {
|
if debug {
|
||||||
l.Debugf("delete; repo=%q node=%x name=%q", repo, node, name)
|
l.Debugf("delete; repo=%q node=%x name=%q", repo, node, name)
|
||||||
}
|
}
|
||||||
batch.Delete(dbi.Key())
|
|
||||||
ldbRemoveFromGlobal(db, batch, repo, node, name)
|
ldbRemoveFromGlobal(db, batch, repo, node, name)
|
||||||
|
batch.Delete(dbi.Key())
|
||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -278,8 +278,17 @@ func (m *Model) LocalSize(repo string) (files, deleted int, bytes int64) {
|
|||||||
|
|
||||||
// NeedSize returns the number and total size of currently needed files.
|
// NeedSize returns the number and total size of currently needed files.
|
||||||
func (m *Model) NeedSize(repo string) (files int, bytes int64) {
|
func (m *Model) NeedSize(repo string) (files int, bytes int64) {
|
||||||
f, d, b := sizeOf(m.NeedFilesRepo(repo))
|
m.rmut.RLock()
|
||||||
return f + d, b
|
defer m.rmut.RUnlock()
|
||||||
|
if rf, ok := m.repoFiles[repo]; ok {
|
||||||
|
rf.WithNeed(protocol.LocalNodeID, func(f protocol.FileInfo) bool {
|
||||||
|
fs, de, by := sizeOfFile(f)
|
||||||
|
files += fs + de
|
||||||
|
bytes += by
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeedFiles returns the list of currently needed files
|
// NeedFiles returns the list of currently needed files
|
||||||
@ -287,10 +296,10 @@ func (m *Model) NeedFilesRepo(repo string) []protocol.FileInfo {
|
|||||||
m.rmut.RLock()
|
m.rmut.RLock()
|
||||||
defer m.rmut.RUnlock()
|
defer m.rmut.RUnlock()
|
||||||
if rf, ok := m.repoFiles[repo]; ok {
|
if rf, ok := m.repoFiles[repo]; ok {
|
||||||
var fs []protocol.FileInfo
|
fs := make([]protocol.FileInfo, 0, indexBatchSize)
|
||||||
rf.WithNeed(protocol.LocalNodeID, func(f protocol.FileInfo) bool {
|
rf.WithNeed(protocol.LocalNodeID, func(f protocol.FileInfo) bool {
|
||||||
fs = append(fs, f)
|
fs = append(fs, f)
|
||||||
return true
|
return len(fs) < indexBatchSize
|
||||||
})
|
})
|
||||||
if r := m.repoCfgs[repo].FileRanker(); r != nil {
|
if r := m.repoCfgs[repo].FileRanker(); r != nil {
|
||||||
files.SortBy(r).Sort(fs)
|
files.SortBy(r).Sort(fs)
|
||||||
@ -721,9 +730,10 @@ func (m *Model) ScanRepo(repo string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
batch := make([]protocol.FileInfo, 0, indexBatchSize)
|
batchSize := 100
|
||||||
|
batch := make([]protocol.FileInfo, 0, 00)
|
||||||
for f := range fchan {
|
for f := range fchan {
|
||||||
if len(batch) == indexBatchSize {
|
if len(batch) == batchSize {
|
||||||
fs.Update(protocol.LocalNodeID, batch)
|
fs.Update(protocol.LocalNodeID, batch)
|
||||||
batch = batch[:0]
|
batch = batch[:0]
|
||||||
}
|
}
|
||||||
@ -736,7 +746,7 @@ func (m *Model) ScanRepo(repo string) error {
|
|||||||
batch = batch[:0]
|
batch = batch[:0]
|
||||||
fs.WithHave(protocol.LocalNodeID, func(f protocol.FileInfo) bool {
|
fs.WithHave(protocol.LocalNodeID, func(f protocol.FileInfo) bool {
|
||||||
if !protocol.IsDeleted(f.Flags) {
|
if !protocol.IsDeleted(f.Flags) {
|
||||||
if len(batch) == indexBatchSize {
|
if len(batch) == batchSize {
|
||||||
fs.Update(protocol.LocalNodeID, batch)
|
fs.Update(protocol.LocalNodeID, batch)
|
||||||
batch = batch[:0]
|
batch = batch[:0]
|
||||||
}
|
}
|
||||||
@ -810,41 +820,52 @@ func (m *Model) State(repo string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) Override(repo string) {
|
func (m *Model) Override(repo string) {
|
||||||
fs := m.NeedFilesRepo(repo)
|
|
||||||
|
|
||||||
m.rmut.RLock()
|
m.rmut.RLock()
|
||||||
r := m.repoFiles[repo]
|
fs := m.repoFiles[repo]
|
||||||
m.rmut.RUnlock()
|
m.rmut.RUnlock()
|
||||||
|
|
||||||
for i := range fs {
|
batch := make([]protocol.FileInfo, 0, indexBatchSize)
|
||||||
f := &fs[i]
|
fs.WithNeed(protocol.LocalNodeID, func(need protocol.FileInfo) bool {
|
||||||
h := r.Get(protocol.LocalNodeID, f.Name)
|
if len(batch) == indexBatchSize {
|
||||||
if h.Name != f.Name {
|
fs.Update(protocol.LocalNodeID, batch)
|
||||||
|
batch = batch[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
have := fs.Get(protocol.LocalNodeID, need.Name)
|
||||||
|
if have.Name != need.Name {
|
||||||
// We are missing the file
|
// We are missing the file
|
||||||
f.Flags |= protocol.FlagDeleted
|
need.Flags |= protocol.FlagDeleted
|
||||||
f.Blocks = nil
|
need.Blocks = nil
|
||||||
} else {
|
} else {
|
||||||
// We have the file, replace with our version
|
// We have the file, replace with our version
|
||||||
*f = h
|
need = have
|
||||||
}
|
}
|
||||||
f.Version = lamport.Default.Tick(f.Version)
|
need.Version = lamport.Default.Tick(need.Version)
|
||||||
f.LocalVersion = 0
|
need.LocalVersion = 0
|
||||||
|
batch = append(batch, need)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if len(batch) > 0 {
|
||||||
|
fs.Update(protocol.LocalNodeID, batch)
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Update(protocol.LocalNodeID, fs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version returns the change version for the given repository. This is
|
// Version returns the change version for the given repository. This is
|
||||||
// guaranteed to increment if the contents of the local or global repository
|
// guaranteed to increment if the contents of the local or global repository
|
||||||
// has changed.
|
// has changed.
|
||||||
func (m *Model) LocalVersion(repo string) uint64 {
|
func (m *Model) LocalVersion(repo string) uint64 {
|
||||||
var ver uint64
|
|
||||||
|
|
||||||
m.rmut.Lock()
|
m.rmut.Lock()
|
||||||
for _, n := range m.repoNodes[repo] {
|
defer m.rmut.Unlock()
|
||||||
ver += m.repoFiles[repo].LocalVersion(n)
|
|
||||||
|
fs, ok := m.repoFiles[repo]
|
||||||
|
if !ok {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ver := fs.LocalVersion(protocol.LocalNodeID)
|
||||||
|
for _, n := range m.repoNodes[repo] {
|
||||||
|
ver += fs.LocalVersion(n)
|
||||||
}
|
}
|
||||||
m.rmut.Unlock()
|
|
||||||
|
|
||||||
return ver
|
return ver
|
||||||
}
|
}
|
||||||
|
@ -195,8 +195,10 @@ func (p *puller) run() {
|
|||||||
|
|
||||||
if v := p.model.LocalVersion(p.repoCfg.ID); v > prevVer {
|
if v := p.model.LocalVersion(p.repoCfg.ID); v > prevVer {
|
||||||
// Queue more blocks to fetch, if any
|
// Queue more blocks to fetch, if any
|
||||||
p.queueNeededBlocks()
|
if p.queueNeededBlocks() == 0 {
|
||||||
prevVer = v
|
// We've fetched all blocks we need
|
||||||
|
prevVer = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,7 +620,7 @@ func (p *puller) handleEmptyBlock(b bqBlock) {
|
|||||||
delete(p.openFiles, f.Name)
|
delete(p.openFiles, f.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *puller) queueNeededBlocks() {
|
func (p *puller) queueNeededBlocks() int {
|
||||||
queued := 0
|
queued := 0
|
||||||
for _, f := range p.model.NeedFilesRepo(p.repoCfg.ID) {
|
for _, f := range p.model.NeedFilesRepo(p.repoCfg.ID) {
|
||||||
lf := p.model.CurrentRepoFile(p.repoCfg.ID, f.Name)
|
lf := p.model.CurrentRepoFile(p.repoCfg.ID, f.Name)
|
||||||
@ -634,8 +636,9 @@ func (p *puller) queueNeededBlocks() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if debug && queued > 0 {
|
if debug && queued > 0 {
|
||||||
l.Debugf("%q: queued %d blocks", p.repoCfg.ID, queued)
|
l.Debugf("%q: queued %d items", p.repoCfg.ID, queued)
|
||||||
}
|
}
|
||||||
|
return queued
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *puller) closeFile(f protocol.FileInfo) {
|
func (p *puller) closeFile(f protocol.FileInfo) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user