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.
This commit is contained in:
Audrius Butkevicius 2014-11-23 00:52:48 +00:00
parent ba019efaf1
commit 59a85c1d75
3 changed files with 30 additions and 17 deletions

View File

@ -291,10 +291,23 @@ func restGetNeed(m *model.Model, w http.ResponseWriter, r *http.Request) {
var qs = r.URL.Query() var qs = r.URL.Query()
var folder = qs.Get("folder") 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") 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) { 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 { for _, subdirectory := range subdirectories {
info, err := os.Stat(subdirectory) info, err := os.Stat(subdirectory)
if err == nil && info.IsDir() { if err == nil && info.IsDir() {
ret = append(ret, subdirectory + pathSeparator) ret = append(ret, subdirectory+pathSeparator)
if len(ret) > 9 { if len(ret) > 9 {
break break
} }

View File

@ -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 // NeedFiles returns the list of currently needed files, stopping at maxFiles
// files or maxBlocks blocks. Limits <= 0 are ignored. // files. Limit <= 0 is ignored.
func (m *Model) NeedFolderFilesLimited(folder string, maxFiles, maxBlocks int) []protocol.FileInfo { func (m *Model) NeedFolderFilesLimited(folder string, maxFiles int) []protocol.FileInfoTruncated {
defer m.leveldbPanicWorkaround() defer m.leveldbPanicWorkaround()
m.fmut.RLock() m.fmut.RLock()
defer m.fmut.RUnlock() defer m.fmut.RUnlock()
nblocks := 0
if rf, ok := m.folderFiles[folder]; ok { if rf, ok := m.folderFiles[folder]; ok {
fs := make([]protocol.FileInfo, 0, maxFiles) fs := make([]protocol.FileInfoTruncated, 0, maxFiles)
rf.WithNeed(protocol.LocalDeviceID, func(f protocol.FileIntf) bool { rf.WithNeedTruncated(protocol.LocalDeviceID, func(f protocol.FileIntf) bool {
fi := f.(protocol.FileInfo) fs = append(fs, f.(protocol.FileInfoTruncated))
fs = append(fs, fi) return maxFiles <= 0 || len(fs) < maxFiles
nblocks += len(fi.Blocks)
return (maxFiles <= 0 || len(fs) < maxFiles) && (maxBlocks <= 0 || nblocks < maxBlocks)
}) })
return fs return fs
} }

View File

@ -81,16 +81,19 @@ func (f FileInfoTruncated) String() string {
f.Name, f.Flags, f.Modified, f.Version, f.Size(), f.NumBlocks) 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 // Returns a statistical guess on the size, not the exact figure
func (f FileInfoTruncated) Size() int64 { func (f FileInfoTruncated) Size() int64 {
if f.IsDeleted() || f.IsDirectory() { if f.IsDeleted() || f.IsDirectory() {
return 128 return 128
} }
if f.NumBlocks < 2 { return BlocksToSize(f.NumBlocks)
return BlockSize / 2
} else {
return int64(f.NumBlocks-1)*BlockSize + BlockSize/2
}
} }
func (f FileInfoTruncated) IsDeleted() bool { func (f FileInfoTruncated) IsDeleted() bool {