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.
This commit is contained in:
Jonas Kvinge
2026-01-06 22:27:46 +01:00
parent 34ae443548
commit 030908f6ac
2 changed files with 12 additions and 8 deletions

View File

@@ -620,11 +620,8 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu
album_art[dir_part] << child_filepath; album_art[dir_part] << child_filepath;
t->AddToProgress(1); t->AddToProgress(1);
} }
else if (tagreader_client_->IsMediaFileBlocking(child_filepath)) {
files_on_disk << child_filepath;
}
else { else {
t->AddToProgress(1); files_on_disk << child_filepath;
} }
} }
} }
@@ -727,7 +724,9 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu
#endif #endif
if (new_cue.isEmpty() || new_cue_mtime == 0) { // If no CUE or it's about to lose it. 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. else { // If CUE associated.
UpdateCueAssociatedSongs(file, path, fingerprint, new_cue, art_automatic, matching_songs, t); 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); 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. 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. else { // If CUE associated.
UpdateCueAssociatedSongs(file, path, fingerprint, new_cue, art_automatic, matching_songs, t); 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); const SongList songs = ScanNewFile(file, path, fingerprint, new_cue, &cues_processed);
if (songs.isEmpty()) { if (songs.isEmpty()) {
files_on_disk.removeAll(file);
t->AddToProgress(1); t->AddToProgress(1);
continue; 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 QString &fingerprint,
const SongList &matching_songs, const SongList &matching_songs,
const QUrl &art_automatic, const QUrl &art_automatic,
@@ -931,6 +933,8 @@ void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file,
AddChangedSong(file, matching_song, song_on_disk, t); 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<QString> *cues_processed) const { SongList CollectionWatcher::ScanNewFile(const QString &file, const QString &path, const QString &fingerprint, const QString &matching_cue, QSet<QString> *cues_processed) const {

View File

@@ -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. // 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; 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. // 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. // 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). // 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<QString> *cues_processed) const; SongList ScanNewFile(const QString &file, const QString &path, const QString &fingerprint, const QString &matching_cue, QSet<QString> *cues_processed) const;