cache: Remove entries that no longer exist in the source

list directory with 25k files

before(1.43.1)
5m24s

after
3m21s
This commit is contained in:
dcpu 2018-10-06 19:23:33 +09:00 committed by Nick Craig-Wood
parent ddbd4fd881
commit c0084f43dd

View file

@ -11,6 +11,7 @@ import (
"os/signal" "os/signal"
"path" "path"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -891,7 +892,6 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) {
fs.Debugf(dir, "list: cached entries: %v", entries) fs.Debugf(dir, "list: cached entries: %v", entries)
return entries, nil return entries, nil
} }
// FIXME need to clean existing cached listing
// we first search any temporary files stored locally // we first search any temporary files stored locally
var cachedEntries fs.DirEntries var cachedEntries fs.DirEntries
@ -917,27 +917,42 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) {
} }
// search from the source // search from the source
entries, err = f.Fs.List(dir) sourceEntries, err := f.Fs.List(dir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
fs.Debugf(dir, "list: read %v from source", len(entries)) fs.Debugf(dir, "list: read %v from source", len(sourceEntries))
fs.Debugf(dir, "list: source entries: %v", entries) fs.Debugf(dir, "list: source entries: %v", sourceEntries)
sort.Sort(sourceEntries)
for _, entry := range entries {
entryRemote := entry.Remote()
i := sort.Search(len(sourceEntries), func(i int) bool { return sourceEntries[i].Remote() >= entryRemote })
if i < len(sourceEntries) && sourceEntries[i].Remote() == entryRemote {
continue
}
fp := path.Join(f.Root(), entryRemote)
switch entry.(type) {
case fs.Object:
_ = f.cache.RemoveObject(fp)
case fs.Directory:
_ = f.cache.RemoveDir(fp)
}
fs.Debugf(dir, "list: remove entry: %v", entryRemote)
}
entries = nil
// and then iterate over the ones from source (temp Objects will override source ones) // and then iterate over the ones from source (temp Objects will override source ones)
var batchDirectories []*Directory var batchDirectories []*Directory
for _, entry := range entries { sort.Sort(cachedEntries)
tmpCnt := len(cachedEntries)
for _, entry := range sourceEntries {
switch o := entry.(type) { switch o := entry.(type) {
case fs.Object: case fs.Object:
// skip over temporary objects (might be uploading) // skip over temporary objects (might be uploading)
found := false oRemote := o.Remote()
for _, t := range cachedEntries { i := sort.Search(tmpCnt, func(i int) bool { return cachedEntries[i].Remote() >= oRemote })
if t.Remote() == o.Remote() { if i < tmpCnt && cachedEntries[i].Remote() == oRemote {
found = true
break
}
}
if found {
continue continue
} }
co := ObjectFromOriginal(f, o).persist() co := ObjectFromOriginal(f, o).persist()