Reduce number of calls to lstat.
Should make the scanner a bit faster, specially in networked filesystems
This commit is contained in:
+21
-23
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user