From 59a85c1d751c85e585ec93398c3ba5c50bdef91f Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Sun, 23 Nov 2014 00:52:48 +0000 Subject: [PATCH] Use custom structure for /need calls (fixes #1001) Also, remove trimming by number of blocks as this no longer affects the size of the response. --- cmd/syncthing/gui.go | 19 ++++++++++++++++--- internal/model/model.go | 15 ++++++--------- internal/protocol/message.go | 13 ++++++++----- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index f330ea00f..b7129add4 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -291,10 +291,23 @@ func restGetNeed(m *model.Model, w http.ResponseWriter, r *http.Request) { var qs = r.URL.Query() var folder = qs.Get("folder") - files := m.NeedFolderFilesLimited(folder, 100, 2500) // max 100 files or 2500 blocks + files := m.NeedFolderFilesLimited(folder, 100) // max 100 files + // Convert the struct to a more loose structure, and inject the size. + output := make([]map[string]interface{}, 0, len(files)) + for _, file := range files { + output = append(output, map[string]interface{}{ + "Name": file.Name, + "Flags": file.Flags, + "Modified": file.Modified, + "Version": file.Version, + "LocalVersion": file.LocalVersion, + "NumBlocks": file.NumBlocks, + "Size": protocol.BlocksToSize(file.NumBlocks), + }) + } w.Header().Set("Content-Type", "application/json; charset=utf-8") - json.NewEncoder(w).Encode(files) + json.NewEncoder(w).Encode(output) } func restGetConnections(m *model.Model, w http.ResponseWriter, r *http.Request) { @@ -658,7 +671,7 @@ func restGetAutocompleteDirectory(w http.ResponseWriter, r *http.Request) { for _, subdirectory := range subdirectories { info, err := os.Stat(subdirectory) if err == nil && info.IsDir() { - ret = append(ret, subdirectory + pathSeparator) + ret = append(ret, subdirectory+pathSeparator) if len(ret) > 9 { break } diff --git a/internal/model/model.go b/internal/model/model.go index 73d10b604..a4ff705d0 100644 --- a/internal/model/model.go +++ b/internal/model/model.go @@ -396,20 +396,17 @@ func (m *Model) NeedSize(folder string) (files int, bytes int64) { } // NeedFiles returns the list of currently needed files, stopping at maxFiles -// files or maxBlocks blocks. Limits <= 0 are ignored. -func (m *Model) NeedFolderFilesLimited(folder string, maxFiles, maxBlocks int) []protocol.FileInfo { +// files. Limit <= 0 is ignored. +func (m *Model) NeedFolderFilesLimited(folder string, maxFiles int) []protocol.FileInfoTruncated { defer m.leveldbPanicWorkaround() m.fmut.RLock() defer m.fmut.RUnlock() - nblocks := 0 if rf, ok := m.folderFiles[folder]; ok { - fs := make([]protocol.FileInfo, 0, maxFiles) - rf.WithNeed(protocol.LocalDeviceID, func(f protocol.FileIntf) bool { - fi := f.(protocol.FileInfo) - fs = append(fs, fi) - nblocks += len(fi.Blocks) - return (maxFiles <= 0 || len(fs) < maxFiles) && (maxBlocks <= 0 || nblocks < maxBlocks) + fs := make([]protocol.FileInfoTruncated, 0, maxFiles) + rf.WithNeedTruncated(protocol.LocalDeviceID, func(f protocol.FileIntf) bool { + fs = append(fs, f.(protocol.FileInfoTruncated)) + return maxFiles <= 0 || len(fs) < maxFiles }) return fs } diff --git a/internal/protocol/message.go b/internal/protocol/message.go index 355050cab..9a96f80c5 100644 --- a/internal/protocol/message.go +++ b/internal/protocol/message.go @@ -81,16 +81,19 @@ func (f FileInfoTruncated) String() string { f.Name, f.Flags, f.Modified, f.Version, f.Size(), f.NumBlocks) } +func BlocksToSize(num uint32) int64 { + if num < 2 { + return BlockSize / 2 + } + return int64(num-1)*BlockSize + BlockSize/2 +} + // Returns a statistical guess on the size, not the exact figure func (f FileInfoTruncated) Size() int64 { if f.IsDeleted() || f.IsDirectory() { return 128 } - if f.NumBlocks < 2 { - return BlockSize / 2 - } else { - return int64(f.NumBlocks-1)*BlockSize + BlockSize/2 - } + return BlocksToSize(f.NumBlocks) } func (f FileInfoTruncated) IsDeleted() bool {