mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 23:00:58 +00:00
lib/model: Fix wild completion percentages
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3188
This commit is contained in:
parent
72154aa668
commit
fc173bf679
@ -25,7 +25,6 @@ type deviceFolderFileDownloadState struct {
|
|||||||
type deviceFolderDownloadState struct {
|
type deviceFolderDownloadState struct {
|
||||||
mut sync.RWMutex
|
mut sync.RWMutex
|
||||||
files map[string]deviceFolderFileDownloadState
|
files map[string]deviceFolderFileDownloadState
|
||||||
numberOfBlocksInProgress int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has returns whether a block at that specific index, and that specific version of the file
|
// Has returns whether a block at that specific index, and that specific version of the file
|
||||||
@ -57,7 +56,6 @@ func (p *deviceFolderDownloadState) Update(updates []protocol.FileDownloadProgre
|
|||||||
for _, update := range updates {
|
for _, update := range updates {
|
||||||
local, ok := p.files[update.Name]
|
local, ok := p.files[update.Name]
|
||||||
if update.UpdateType == protocol.UpdateTypeForget && ok && local.version.Equal(update.Version) {
|
if update.UpdateType == protocol.UpdateTypeForget && ok && local.version.Equal(update.Version) {
|
||||||
p.numberOfBlocksInProgress -= len(local.blockIndexes)
|
|
||||||
delete(p.files, update.Name)
|
delete(p.files, update.Name)
|
||||||
} else if update.UpdateType == protocol.UpdateTypeAppend {
|
} else if update.UpdateType == protocol.UpdateTypeAppend {
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -66,25 +64,25 @@ func (p *deviceFolderDownloadState) Update(updates []protocol.FileDownloadProgre
|
|||||||
version: update.Version,
|
version: update.Version,
|
||||||
}
|
}
|
||||||
} else if !local.version.Equal(update.Version) {
|
} else if !local.version.Equal(update.Version) {
|
||||||
p.numberOfBlocksInProgress -= len(local.blockIndexes)
|
|
||||||
local.blockIndexes = append(local.blockIndexes[:0], update.BlockIndexes...)
|
local.blockIndexes = append(local.blockIndexes[:0], update.BlockIndexes...)
|
||||||
local.version = update.Version
|
local.version = update.Version
|
||||||
} else {
|
} else {
|
||||||
local.blockIndexes = append(local.blockIndexes, update.BlockIndexes...)
|
local.blockIndexes = append(local.blockIndexes, update.BlockIndexes...)
|
||||||
}
|
}
|
||||||
p.files[update.Name] = local
|
p.files[update.Name] = local
|
||||||
p.numberOfBlocksInProgress += len(update.BlockIndexes)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumberOfBlocksInProgress returns the number of blocks the device has downloaded
|
// GetBlockCounts returns a map filename -> number of blocks downloaded.
|
||||||
// for a specific folder.
|
func (p *deviceFolderDownloadState) GetBlockCounts() map[string]int {
|
||||||
func (p *deviceFolderDownloadState) NumberOfBlocksInProgress() int {
|
|
||||||
p.mut.RLock()
|
p.mut.RLock()
|
||||||
n := p.numberOfBlocksInProgress
|
res := make(map[string]int, len(p.files))
|
||||||
|
for name, state := range p.files {
|
||||||
|
res[name] = len(state.blockIndexes)
|
||||||
|
}
|
||||||
p.mut.RUnlock()
|
p.mut.RUnlock()
|
||||||
return n
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// deviceDownloadState represents the state of all in progress downloads
|
// deviceDownloadState represents the state of all in progress downloads
|
||||||
@ -134,20 +132,21 @@ func (t *deviceDownloadState) Has(folder, file string, version protocol.Vector,
|
|||||||
return f.Has(file, version, index)
|
return f.Has(file, version, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumberOfBlocksInProgress returns the number of blocks the device has downloaded
|
// GetBlockCounts returns a map filename -> number of blocks downloaded for the
|
||||||
// for all folders.
|
// given folder.
|
||||||
func (t *deviceDownloadState) NumberOfBlocksInProgress() int {
|
func (t *deviceDownloadState) GetBlockCounts(folder string) map[string]int {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return 0
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
n := 0
|
|
||||||
t.mut.RLock()
|
t.mut.RLock()
|
||||||
for _, folder := range t.folders {
|
for name, state := range t.folders {
|
||||||
n += folder.NumberOfBlocksInProgress()
|
if name == folder {
|
||||||
|
return state.GetBlockCounts()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t.mut.RUnlock()
|
t.mut.RUnlock()
|
||||||
return n
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDeviceDownloadState() *deviceDownloadState {
|
func newDeviceDownloadState() *deviceDownloadState {
|
||||||
|
@ -374,16 +374,25 @@ func (m *Model) Completion(device protocol.DeviceID, folder string) float64 {
|
|||||||
return 100 // Folder is empty, so we have all of it
|
return 100 // Folder is empty, so we have all of it
|
||||||
}
|
}
|
||||||
|
|
||||||
var need int64
|
m.pmut.RLock()
|
||||||
|
counts := m.deviceDownloads[device].GetBlockCounts(folder)
|
||||||
|
m.pmut.RUnlock()
|
||||||
|
|
||||||
|
var need, fileNeed, downloaded int64
|
||||||
rf.WithNeedTruncated(device, func(f db.FileIntf) bool {
|
rf.WithNeedTruncated(device, func(f db.FileIntf) bool {
|
||||||
need += f.Size()
|
ft := f.(db.FileInfoTruncated)
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
// This might might be more than it really is, because some blocks can be of a smaller size.
|
// This might might be more than it really is, because some blocks can be of a smaller size.
|
||||||
m.pmut.RLock()
|
downloaded = int64(counts[ft.Name] * protocol.BlockSize)
|
||||||
need -= int64(m.deviceDownloads[device].NumberOfBlocksInProgress() * protocol.BlockSize)
|
|
||||||
m.pmut.RUnlock()
|
fileNeed = ft.Size() - downloaded
|
||||||
|
if fileNeed < 0 {
|
||||||
|
fileNeed = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
need += fileNeed
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
needRatio := float64(need) / float64(tot)
|
needRatio := float64(need) / float64(tot)
|
||||||
completionPct := 100 * (1 - needRatio)
|
completionPct := 100 * (1 - needRatio)
|
||||||
@ -1083,13 +1092,13 @@ func (m *Model) DownloadProgress(device protocol.DeviceID, folder string, update
|
|||||||
|
|
||||||
m.pmut.RLock()
|
m.pmut.RLock()
|
||||||
m.deviceDownloads[device].Update(folder, updates)
|
m.deviceDownloads[device].Update(folder, updates)
|
||||||
blocks := m.deviceDownloads[device].NumberOfBlocksInProgress()
|
state := m.deviceDownloads[device].GetBlockCounts(folder)
|
||||||
m.pmut.RUnlock()
|
m.pmut.RUnlock()
|
||||||
|
|
||||||
events.Default.Log(events.RemoteDownloadProgress, map[string]interface{}{
|
events.Default.Log(events.RemoteDownloadProgress, map[string]interface{}{
|
||||||
"device": device.String(),
|
"device": device.String(),
|
||||||
"folder": folder,
|
"folder": folder,
|
||||||
"blocks": blocks,
|
"state": state,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user