From 6860e6ccaf360fd1f505c7080f832e0c71a5d156 Mon Sep 17 00:00:00 2001 From: Daan Meijer Date: Mon, 26 Oct 2026 12:28:40 +0100 Subject: [PATCH] Albums: no numbered volumes or stray suffixes; the replay report counts the group's releases acs5152s1.11 is a volume, Broforce.vol00+01.par2.temp a par2: neither an album's member. replay:corpus reported every release in the scratch catalog as the group's. Co-Authored-By: Claude Fable 5.1 --- commands/replay_corpus.ts | 14 ++++++++------ edge/src/indexer.rs | 9 +++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/commands/replay_corpus.ts b/commands/replay_corpus.ts index 0868291..723708b 100644 --- a/commands/replay_corpus.ts +++ b/commands/replay_corpus.ts @@ -199,7 +199,7 @@ export default class ReplayCorpus extends BaseCommand { this.exitCode = 1 return } - await this.report(ranges, Date.now() - started) + await this.report(groupId, ranges, Date.now() - started) } private async benchBinary(): Promise { @@ -310,8 +310,8 @@ export default class ReplayCorpus extends BaseCommand { return out } - /** What the replay left in the catalog, and its size per article. */ - private async report(ranges: StoredRange[], elapsedMs: number) { + /** What the replay left in the catalog (this group's releases; the sizes are the whole catalog's), per article. */ + private async report(groupId: number, ranges: StoredRange[], elapsedMs: number) { const ids = ranges.map((r) => r.id) const { rows: counts } = await db.rawQuery( `SELECT count(*)::bigint AS releases, @@ -326,10 +326,12 @@ export default class ReplayCorpus extends BaseCommand { coalesce(sum(files), 0)::bigint AS files, coalesce(sum(segments), 0)::bigint AS segments, coalesce(sum(bytes), 0)::bigint AS bytes - FROM releases` + FROM releases WHERE group_id = ?`, + [groupId] ) const { rows: sources } = await db.rawQuery( - `SELECT source, count(*)::bigint AS n FROM releases GROUP BY source ORDER BY source` + `SELECT source, count(*)::bigint AS n FROM releases WHERE group_id = ? GROUP BY source ORDER BY source`, + [groupId] ) const { rows: headerRows } = await db.rawQuery( `SELECT coalesce(sum(headers), 0)::bigint AS headers FROM ranges WHERE id = ANY(?::bigint[])`, @@ -371,7 +373,7 @@ export default class ReplayCorpus extends BaseCommand { ) } this.logger.info( - `NVMe tables: ${(nvme / 1e6).toFixed(1)} MB, ${(nvme / Math.max(1, headers)).toFixed(2)} B/header; HDD tables (CHUNK_TABLESPACE): ${(other / 1e6).toFixed(1)} MB, ${(other / Math.max(1, headers)).toFixed(2)} B/header.` + `NVMe tables: ${(nvme / 1e6).toFixed(1)} MB, ${(nvme / Math.max(1, headers)).toFixed(2)} B/header; HDD tables (CHUNK_TABLESPACE): ${(other / 1e6).toFixed(1)} MB, ${(other / Math.max(1, headers)).toFixed(2)} B/header (the whole catalog's sizes over this group's headers: only the first group's are its own).` ) } } diff --git a/edge/src/indexer.rs b/edge/src/indexer.rs index 483401a..af8b4c5 100644 --- a/edge/src/indexer.rs +++ b/edge/src/indexer.rs @@ -737,10 +737,12 @@ struct OpenAlbum { /// The template a file name joins an album by: every digit run as "#" ("1481439079025_014.jpg.data" → /// "#_#.jpg.data"); none for a name without a number, a random one, an archive, a volume or a sidecar. pub fn album_template(name: &str) -> Option { - if is_random_file(name) || names::is_par2(name) || names::is_archive_start(name) || names::is_later_volume(name) || names::is_sidecar(name) { + let (stem, ext) = split_extension(name); + // A numbered extension is a volume ("acs5152s1.11"), and a stray suffix hides none of the above ("x.par2.temp"). + let volume = |n: &str| names::is_par2(n) || names::is_archive_start(n) || names::is_later_volume(n); + if is_random_file(name) || names::is_sidecar(name) || volume(name) || volume(stem) || (ext.len() > 1 && ext.bytes().skip(1).all(|c| c.is_ascii_digit())) { return None; } - let (stem, ext) = split_extension(name); let mut out = String::with_capacity(name.len()); let mut runs = 0; let mut in_digits = false; @@ -1416,6 +1418,9 @@ mod tests { assert_eq!(album_template("Scan_001.vol00+01.par2"), None); assert_eq!(album_template("Scan_001.nfo"), None); assert_eq!(album_template("NoNumber.mp4"), None); + assert_eq!(album_template("acs5152s1.11"), None); + assert_eq!(album_template("Broforce.vol00+01.par2.temp"), None); + assert_eq!(album_template("Starship For Rent 3 (2024).epub").as_deref(), Some("Starship For Rent # (#).epub")); assert_eq!(album_template("c3453cdd2a3645a8f3cf3d22319abe63"), None); assert_eq!(album_name(&["1481439079025_001.jpg.data", "1481439079025_014.jpg.data"]), "1481439079025_#.jpg.data"); assert_eq!(album_name(&["1481439079025_001.jpg.data", "1481439080000_001.jpg.data"]), "#_001.jpg.data");