From 2ad901e6dc5dd5619aede9bee493902c093f8caf Mon Sep 17 00:00:00 2001 From: Nathaniel Ledford Date: Fri, 9 Oct 2026 10:15:12 -0400 Subject: [PATCH] LRC-LIB-SMARTCOLL: album_reaches uses a hash set; loop test describes the guard From review: the walk through smart-album references kept its seen-set in a Vec, which is quadratic over long chains. The loop test's comment now says what a saved loop does: inside it, the album being evaluated counts as holding no photos. Co-Authored-By: Claude Opus 5.5 --- crates/catalog/src/lib.rs | 5 ++--- crates/catalog/src/tests.rs | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/catalog/src/lib.rs b/crates/catalog/src/lib.rs index fd15415c2..10ca3617d 100644 --- a/crates/catalog/src/lib.rs +++ b/crates/catalog/src/lib.rs @@ -335,13 +335,12 @@ impl Catalog { /// rules of `from` would then change when those of `to` do). Loops in saved rules end the /// search, they don't repeat it. pub fn album_reaches(&self, from: AlbumId, to: AlbumId) -> bool { - let mut seen: Vec = Vec::new(); + let mut seen: std::collections::HashSet = std::collections::HashSet::new(); let mut next = vec![from]; while let Some(a) = next.pop() { - if seen.contains(&a) { + if !seen.insert(a) { continue; } - seen.push(a); let tested = self .albums .get(&a) diff --git a/crates/catalog/src/tests.rs b/crates/catalog/src/tests.rs index ec78153be..354d046e9 100644 --- a/crates/catalog/src/tests.rs +++ b/crates/catalog/src/tests.rs @@ -522,7 +522,8 @@ fn a_smart_album_can_exclude_another() { /// An album can't include itself, directly or through other smart albums: the check refuses the /// loop for the album being edited, and a loop saved anyway (an older version, a hand-edited file) -/// neither recurses forever nor crashes; it is reported and its rule matches nothing. +/// neither recurses forever nor crashes: inside it, the album being evaluated counts as holding no +/// photos, and every album in it is reported. #[test] fn smart_album_loops_are_refused_and_survived() { let mut c = Catalog::new();