Files
LibreMail/app
JMR-dev 8632500cf6 perf(data): route MailBackfiller.persistBatch through batched updateHeaderContents
persistBatch refreshed each pre-existing backfilled header with a per-row
updateHeaderContent in its own implicit transaction — the same N-commits-per-page
anti-pattern #310 fixed in MailSyncer. Route the whole pre-existing subset through
the batched MessageDao.updateHeaderContents(List) @Transaction so a page costs one
commit instead of one fsync per message (amplified on the encrypted cache).

Semantics are unchanged: updateHeaderContents applies updateHeaderContent to each
row in list order, so the same rows get the same values (and the same casefold
columns); the isNotEmpty guard still skips an empty refresh batch; brand-new rows
stay insert-only. No schema change.

Adds a PII-free, counts-only AppLog breadcrumb at the persist point.

Tests:
- MailBackfillerTest: the refresh routes through the batched update and never the
  per-row one; a partial page refreshes only its pre-existing subset in one batched
  call; an all-new page skips the batch entirely (empty boundary); breadcrumb counts.
- MessageDaoTest (real Room): the batch writes byte-for-byte the same row as the
  per-row path; an empty batch is a no-op.

Closes #322
2026-07-07 23:42:58 -05:00
..