Repository: syncthing/syncthing
File: lib/model/model.go (Go)

Code before:
		return FolderCompletion{} // Folder doesn't exist, so we hardly have any of it
	}

	snap := rf.Snapshot()
	defer snap.Release()

	counts := snap.GlobalSize()
	if counts.Bytes == 0 {
		// Folder is empty, so we have all of it
		return FolderCompletion{
			CompletionPct: 100,
		}
	}

	m.pmut.RLock()
	downloaded := m.deviceDownloads[device].BytesDownloaded(folder)
	m.pmut.RUnlock()

	need := snap.NeedSize(device)
	need.Bytes -= downloaded
	// This might might be more than it really is, because some blocks can be of a smaller size.
	if need.Bytes < 0 {
		need.Bytes = 0
	}

	comp := NewFolderCompletion(counts.Bytes, need.Bytes, counts.Files+counts.Directories+counts.Symlinks, need.Files+need.Directories+need.Symlinks, need.Deleted)

	l.Debugf("%v Completion(%s, %q): %f (%d / %d)", m, device, folder, comp.CompletionPct, need.Bytes, counts.Bytes)
	return comp
}

// DBSnapshot returns a snapshot of the database content relevant to the given folder.
func (m *model) DBSnapshot(folder string) (*db.Snapshot, error) {
	m.fmut.RLock()
	err := m.checkFolderRunningLocked(folder)
	rf := m.folderFiles[folder]
	m.fmut.RUnlock()
	if err != nil {
		return nil, err
	}
	return rf.Snapshot(), nil
}

func (m *model) FolderProgressBytesCompleted(folder string) int64 {
	return m.progressEmitter.BytesCompleted(folder)
}

// NeedFolderFiles returns paginated list of currently needed files in
// progress, queued, and to be queued on next puller iteration.
func (m *model) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfoTruncated, []db.FileInfoTruncated, []db.FileInfoTruncated) {
	m.fmut.RLock()

Review comment (suggestion):
Almost feel like this should be `NewFolderCompletion(global, need)` and the summing happens internally.

Code after:
	}

	snap := rf.Snapshot()
	defer snap.Release()

	global := snap.GlobalSize()
	if global.Bytes == 0 {
		// Folder is empty, so we have all of it
		return FolderCompletion{
			CompletionPct: 100,
		}
	}

	m.pmut.RLock()
	downloaded := m.deviceDownloads[device].BytesDownloaded(folder)
	m.pmut.RUnlock()

	need := snap.NeedSize(device)
	need.Bytes -= downloaded
	// This might might be more than it really is, because some blocks can be of a smaller size.
	if need.Bytes < 0 {
		need.Bytes = 0
	}

	comp := newFolderCompletion(global, need)

	l.Debugf("%v Completion(%s, %q): %v", m, device, folder, comp.Map())
	return comp
}

// DBSnapshot returns a snapshot of the database content relevant to the given folder.
func (m *model) DBSnapshot(folder string) (*db.Snapshot, error) {
	m.fmut.RLock()
	err := m.checkFolderRunningLocked(folder)
	rf := m.folderFiles[folder]
	m.fmut.RUnlock()
	if err != nil {
		return nil, err
	}
	return rf.Snapshot(), nil
}

func (m *model) FolderProgressBytesCompleted(folder string) int64 {
	return m.progressEmitter.BytesCompleted(folder)
}

// NeedFolderFiles returns paginated list of currently needed files in
// progress, queued, and to be queued on next puller iteration.
func (m *model) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfoTruncated, []db.FileInfoTruncated, []db.FileInfoTruncated) {
	m.fmut.RLock()
	rf, rfOk := m.folderFiles[folder]