Reduce number of calls to lstat.

Should make the scanner a bit faster, specially in networked filesystems
This commit is contained in:
Deluan
2021-07-21 22:17:37 -04:00
parent 86c0b422f6
commit 876dda83f2
+21 -23
View File
@@ -2,6 +2,7 @@ package scanner
import ( import (
"context" "context"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@@ -249,7 +250,7 @@ func (s *TagScanner) processChangedDir(ctx context.Context, dir string, fullScan
currentTracks[t.Path] = t currentTracks[t.Path] = t
} }
// Load tracks FileInfo from the folder // Load track list from the folder
files, err := loadAllAudioFiles(dir) files, err := loadAllAudioFiles(dir)
if err != nil { if err != nil {
return err return err
@@ -268,15 +269,21 @@ func (s *TagScanner) processChangedDir(ctx context.Context, dir string, fullScan
// If track from folder is newer than the one in DB, select for update/insert in DB // If track from folder is newer than the one in DB, select for update/insert in DB
log.Trace(ctx, "Processing changed folder", "dir", dir, "tracksInDB", len(currentTracks), "tracksInFolder", len(files)) log.Trace(ctx, "Processing changed folder", "dir", dir, "tracksInDB", len(currentTracks), "tracksInFolder", len(files))
var filesToUpdate []string var filesToUpdate []string
for filePath, info := range files { for filePath, entry := range files {
c, ok := currentTracks[filePath] c, inDB := currentTracks[filePath]
if !ok { if !inDB || fullScan {
filesToUpdate = append(filesToUpdate, filePath) filesToUpdate = append(filesToUpdate, filePath)
s.cnt.added++ s.cnt.added++
} } else {
if ok && (info.ModTime().After(c.UpdatedAt) || fullScan) { info, err := entry.Info()
filesToUpdate = append(filesToUpdate, filePath) if err != nil {
s.cnt.updated++ log.Error("Could not stat file", "filePath", filePath, err)
continue
}
if info.ModTime().After(c.UpdatedAt) {
filesToUpdate = append(filesToUpdate, filePath)
s.cnt.updated++
}
} }
// Force a refresh of the album and artist, to cater for cover art files // Force a refresh of the album and artist, to cater for cover art files
@@ -311,7 +318,7 @@ func (s *TagScanner) processChangedDir(ctx context.Context, dir string, fullScan
err = buffer.flush() err = buffer.flush()
log.Info(ctx, "Finished processing changed folder", "dir", dir, "updated", numUpdatedTracks, log.Info(ctx, "Finished processing changed folder", "dir", dir, "updated", numUpdatedTracks,
"purged", numPurgedTracks, "elapsed", time.Since(start)) "deleted", numPurgedTracks, "elapsed", time.Since(start))
return err return err
} }
@@ -393,16 +400,12 @@ func (s *TagScanner) withAdminUser(ctx context.Context) context.Context {
return request.WithUser(ctx, *u) return request.WithUser(ctx, *u)
} }
func loadAllAudioFiles(dirPath string) (map[string]os.FileInfo, error) { func loadAllAudioFiles(dirPath string) (map[string]fs.DirEntry, error) {
dir, err := os.Open(dirPath) files, err := fs.ReadDir(os.DirFS(dirPath), ".")
if err != nil { if err != nil {
return nil, err return nil, err
} }
files, err := dir.Readdir(-1) fileInfos := make(map[string]fs.DirEntry)
if err != nil {
return nil, err
}
audioFiles := make(map[string]os.FileInfo)
for _, f := range files { for _, f := range files {
if f.IsDir() { if f.IsDir() {
continue continue
@@ -414,13 +417,8 @@ func loadAllAudioFiles(dirPath string) (map[string]os.FileInfo, error) {
if !utils.IsAudioFile(filePath) { if !utils.IsAudioFile(filePath) {
continue continue
} }
fi, err := os.Stat(filePath) fileInfos[filePath] = f
if err != nil {
log.Error("Could not stat file", "filePath", filePath, err)
} else {
audioFiles[filePath] = fi
}
} }
return audioFiles, nil return fileInfos, nil
} }