From 030908f6ac4ad043fca9fdc6ea0e33f2e1b41e9c Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Tue, 6 Jan 2026 22:27:46 +0100 Subject: [PATCH] CollectionWatcher: Avoid checking for valid media file early Optimize the collection scanning process by deferring media file validation from the initial directory scan to the actual file processing stage. Instead of calling `IsMediaFileBlocking` early to filter files, all non-rejected files are added to the scan queue and validated later during `ReadFileBlocking`. Invalid files are removed from the tracked files list, causing them to be treated as deleted from the collection. --- src/collection/collectionwatcher.cpp | 18 +++++++++++------- src/collection/collectionwatcher.h | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/collection/collectionwatcher.cpp b/src/collection/collectionwatcher.cpp index e50576f9a..cba84055b 100644 --- a/src/collection/collectionwatcher.cpp +++ b/src/collection/collectionwatcher.cpp @@ -620,11 +620,8 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu album_art[dir_part] << child_filepath; t->AddToProgress(1); } - else if (tagreader_client_->IsMediaFileBlocking(child_filepath)) { - files_on_disk << child_filepath; - } else { - t->AddToProgress(1); + files_on_disk << child_filepath; } } } @@ -727,7 +724,9 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu #endif if (new_cue.isEmpty() || new_cue_mtime == 0) { // If no CUE or it's about to lose it. - UpdateNonCueAssociatedSong(file, fingerprint, matching_songs, art_automatic, cue_deleted, t); + if (!UpdateNonCueAssociatedSong(file, fingerprint, matching_songs, art_automatic, cue_deleted, t)) { + files_on_disk.removeAll(file); + } } else { // If CUE associated. UpdateCueAssociatedSongs(file, path, fingerprint, new_cue, art_automatic, matching_songs, t); @@ -784,7 +783,9 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu const QUrl art_automatic = ArtForSong(file, album_art); if (new_cue.isEmpty() || new_cue_mtime == 0) { // If no CUE or it's about to lose it. - UpdateNonCueAssociatedSong(file, fingerprint, matching_songs, art_automatic, matching_songs_has_cue && new_cue_mtime == 0, t); + if (!UpdateNonCueAssociatedSong(file, fingerprint, matching_songs, art_automatic, matching_songs_has_cue && new_cue_mtime == 0, t)) { + files_on_disk.removeAll(file); + } } else { // If CUE associated. UpdateCueAssociatedSongs(file, path, fingerprint, new_cue, art_automatic, matching_songs, t); @@ -795,6 +796,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu const SongList songs = ScanNewFile(file, path, fingerprint, new_cue, &cues_processed); if (songs.isEmpty()) { + files_on_disk.removeAll(file); t->AddToProgress(1); continue; } @@ -901,7 +903,7 @@ void CollectionWatcher::UpdateCueAssociatedSongs(const QString &file, } -void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file, +bool CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file, const QString &fingerprint, const SongList &matching_songs, const QUrl &art_automatic, @@ -931,6 +933,8 @@ void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file, AddChangedSong(file, matching_song, song_on_disk, t); } + return result.success() && song_on_disk.is_valid(); + } SongList CollectionWatcher::ScanNewFile(const QString &file, const QString &path, const QString &fingerprint, const QString &matching_cue, QSet *cues_processed) const { diff --git a/src/collection/collectionwatcher.h b/src/collection/collectionwatcher.h index fa8f857bd..ea1415b50 100644 --- a/src/collection/collectionwatcher.h +++ b/src/collection/collectionwatcher.h @@ -202,7 +202,7 @@ class CollectionWatcher : public QObject { // Updates the sections of a cue associated and altered (according to mtime) media file during a scan. void UpdateCueAssociatedSongs(const QString &file, const QString &path, const QString &fingerprint, const QString &matching_cue, const QUrl &art_automatic, const SongList &old_cue_songs, ScanTransaction *t) const; // Updates a single non-cue associated and altered (according to mtime) song during a scan. - void UpdateNonCueAssociatedSong(const QString &file, const QString &fingerprint, const SongList &matching_songs, const QUrl &art_automatic, const bool cue_deleted, ScanTransaction *t); + bool UpdateNonCueAssociatedSong(const QString &file, const QString &fingerprint, const SongList &matching_songs, const QUrl &art_automatic, const bool cue_deleted, ScanTransaction *t); // Scans a single media file that's present on the disk but not yet in the collection. // It may result in a multiple files added to the collection when the media file has many sections (like a CUE related media file). SongList ScanNewFile(const QString &file, const QString &path, const QString &fingerprint, const QString &matching_cue, QSet *cues_processed) const;