lib/model: Optimize rename detection in scanner (#7315)

This commit is contained in:
Simon Frei 2021-01-31 21:02:42 +01:00 committed by GitHub
parent fbe52faf49
commit 249bcb3a01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -549,7 +549,7 @@ func (f *folder) scanSubdirs(subDirs []string) error {
} }
f.clearScanErrors(subDirs) f.clearScanErrors(subDirs)
alreadyUsed := make(map[string]struct{}) alreadyUsedOrExisting := make(map[string]struct{})
for res := range fchan { for res := range fchan {
if res.Err != nil { if res.Err != nil {
f.newScanError(res.Path, res.Err) f.newScanError(res.Path, res.Err)
@ -571,7 +571,7 @@ func (f *folder) scanSubdirs(subDirs []string) error {
switch f.Type { switch f.Type {
case config.FolderTypeReceiveOnly, config.FolderTypeReceiveEncrypted: case config.FolderTypeReceiveOnly, config.FolderTypeReceiveEncrypted:
default: default:
if nf, ok := f.findRename(snap, res.File, alreadyUsed); ok { if nf, ok := f.findRename(snap, res.File, alreadyUsedOrExisting); ok {
batchAppend(nf, snap) batchAppend(nf, snap)
changes++ changes++
} }
@ -582,6 +582,10 @@ func (f *folder) scanSubdirs(subDirs []string) error {
return err return err
} }
// Might have grown large, isn't used anymore and this function may keep
// running for some time.
alreadyUsedOrExisting = nil
if len(subDirs) == 0 { if len(subDirs) == 0 {
// If we have no specific subdirectories to traverse, set it to one // If we have no specific subdirectories to traverse, set it to one
// empty prefix so we traverse the entire folder contents once. // empty prefix so we traverse the entire folder contents once.
@ -728,7 +732,7 @@ func (f *folder) scanSubdirs(subDirs []string) error {
return nil return nil
} }
func (f *folder) findRename(snap *db.Snapshot, file protocol.FileInfo, alreadyUsed map[string]struct{}) (protocol.FileInfo, bool) { func (f *folder) findRename(snap *db.Snapshot, file protocol.FileInfo, alreadyUsedOrExisting map[string]struct{}) (protocol.FileInfo, bool) {
if len(file.Blocks) == 0 || file.Size == 0 { if len(file.Blocks) == 0 || file.Size == 0 {
return protocol.FileInfo{}, false return protocol.FileInfo{}, false
} }
@ -745,7 +749,12 @@ func (f *folder) findRename(snap *db.Snapshot, file protocol.FileInfo, alreadyUs
default: default:
} }
if _, ok := alreadyUsed[fi.Name]; ok { if fi.Name == file.Name {
alreadyUsedOrExisting[fi.Name] = struct{}{}
return true
}
if _, ok := alreadyUsedOrExisting[fi.Name]; ok {
return true return true
} }
@ -764,12 +773,12 @@ func (f *folder) findRename(snap *db.Snapshot, file protocol.FileInfo, alreadyUs
return true return true
} }
alreadyUsedOrExisting[fi.Name] = struct{}{}
if !osutil.IsDeleted(f.mtimefs, fi.Name) { if !osutil.IsDeleted(f.mtimefs, fi.Name) {
return true return true
} }
alreadyUsed[fi.Name] = struct{}{}
nf = fi nf = fi
nf.SetDeleted(f.shortID) nf.SetDeleted(f.shortID)
nf.LocalFlags = f.localFlags nf.LocalFlags = f.localFlags