Files
DarkRoom/core
dtourolle 981022ab1d Ask a synced keyword's tombstone once per merge, not once per assignment
`merge_remote_catalog` on the reference library (catalog_bench, a copy
merged with itself: the steady state of a sync pass) cost 228-231 ms best
of 5. Timing its phases put 91 ms in the keyword half, not in the faces the
issue named.

Both assignment unions refuse a word this device holds only as a tombstone,
with a correlated `NOT EXISTS (... deleted = 1) OR EXISTS (... deleted = 0)`
per incoming assignment. The `deleted = 1` half has no index to use --
`keyword_terms_name` is partial on `deleted = 0` -- so it scanned the whole
vocabulary for each of the 10,800 rows:

  SCAN rk
  CORRELATED SCALAR SUBQUERY 1
    SCAN t
  CORRELATED SCALAR SUBQUERY 2
    SEARCH t USING COVERING INDEX keyword_terms_name (name=?)

The refused words are one set for the whole statement, so it is asked once:
`rk.keyword NOT IN (tombstoned names EXCEPT live names)`, which is the same
condition -- refused exactly when deleted under some identity and live under
none -- and which SQLite builds as a list before the walk:

  SCAN rk
  LIST SUBQUERY 2
    MERGE (EXCEPT) ...

The file-id union alone went from 72 ms to 11 ms (sqlite3 on a copy), and
the keyword phase of the merge from 91 ms to 28-35 ms. Every table of the
catalog checksums the same after the bench as after the old build's run,
and the merge tests for tombstones and renames pass unchanged.
2026-09-26 13:28:50 -04:00
..