Count the grid by subtracting the hidden burst frames, not probing per image

The grid's total is read on every scroll reload (`load_window` compares it
to notice a delete). On the reference library it cost 1.3-1.5 ms best-of-50
by catalog_bench, 2-3.6 ms on a busy machine, and the issue measured 4 ms.

`uncollapsed` asked every visible image whether a collapsed burst stands in
for it -- two primary-key probes per image, 19,000 times, on a library with
no bursts at all:

  SCAN i USING INDEX images_grid_order
  CORRELATED SCALAR SUBQUERY
    SEARCH bm USING INTEGER PRIMARY KEY (rowid=?)
    CORRELATED SCALAR SUBQUERY
      SEARCH be USING INTEGER PRIMARY KEY (rowid=?)

`total_images_filtered` now counts what the filter keeps and subtracts the
frames `bursts::collapsed_away_frames` lists, under the same filter:

  SCALAR SUBQUERY: SCAN i USING INDEX images_grid_order
  SCALAR SUBQUERY: SCAN bm; SEARCH be ...; SEARCH i USING INTEGER PRIMARY KEY

The second half walks only `burst_members`. Each image is in it at most
once (it is the key), and the filter is applied to both halves, so the
subtraction removes exactly the rows the predicate used to drop. The new
fragment sits beside `not_collapsed_away` in bursts.rs, and a test holds
the two to the same rows with bursts open and closed.

After: 0.3 ms, the same count (19,152). The cells query keeps the predicate:
it is a window with a LIMIT and needs the rows, not their number. The
rated grid count (3.5-4 ms with a one-star filter) is unchanged: its cost
is the rating subquery per image, and changing how `RatingFilter` spells
it changes every grid and timeline query, which is left for its own change.
This commit is contained in:
2026-09-26 13:28:50 -04:00
parent d537e4a965
commit 87badb6f99
3 changed files with 79 additions and 5 deletions
+10 -2
View File
@@ -349,9 +349,17 @@ pub(super) fn total_images_filtered(
filter: &RatingFilter,
) -> Result<usize, dr_catalog::CatalogError> {
let rated = filter.sql();
let folded = uncollapsed("i");
// Everything the filter keeps, less the frames a collapsed burst stands
// in for -- rather than `uncollapsed` asked of every image. Paid on
// every scroll reload: the predicate probed `burst_members` and
// `burst_expanded` once per visible image, 19,000 times on the reference
// library, to hide none. The subtraction walks only the burst members.
let hidden = dr_catalog::bursts::collapsed_away_frames("i");
let n: i64 = catalog.connection().query_row(
&format!("SELECT count(*) FROM images i WHERE {VISIBLE}{rated}{folded}"),
&format!(
"SELECT (SELECT count(*) FROM images i WHERE {VISIBLE}{rated})
- (SELECT count(*) FROM {hidden} AND {VISIBLE}{rated})"
),
[],
|r| r.get(0),
)?;