Purge in read order
Goal
objects.purge iterates oldest-read to newest-read. Selection order only — holders stay independent. If the pass is interrupted, the coldest objects are already handled.
Approach
Add read_at to dbObject. Track reads in memory; flush opportunistically (timer, shutdown, cache pressure, or piggybacked on purge). No per-read DB writes.
Bump at the Module, on the returned Reader, once per logical read, on successful close with bytes delivered. Identity is per object ID.
Qualified reads
Counts: user reads, peer-served reads, Load from external callers.
Skips: Probe, GetType, Contains, Scan, Free, RepoGroup race losers, seek-reopens, failed/cancelled reads.
Rejected alternatives
- Per-read DB write — write amplification on hot read paths.
- In-memory only — no persistence; read history is lost on every restart.
- Dedicated reads table — extra schema for no gain once flushing is in place.
- Filesystem atime — unreliable in practice and doesn't cover memory or network repos.
Open questions
- Flush triggers — which combination.
- Unknown
read_at semantics: eligible vs skip; fallback to CreatedAt.
dbObject is sparse and repo-agnostic — backfill on first scan, or add a repo column.
Follow-up
--not-read <duration> filter on top of the order, once tracking lands.
Purge in read order
Goal
objects.purgeiterates oldest-read to newest-read. Selection order only — holders stay independent. If the pass is interrupted, the coldest objects are already handled.Approach
Add
read_attodbObject. Track reads in memory; flush opportunistically (timer, shutdown, cache pressure, or piggybacked on purge). No per-read DB writes.Bump at the
Module, on the returnedReader, once per logical read, on successful close with bytes delivered. Identity is per object ID.Qualified reads
Counts: user reads, peer-served reads,
Loadfrom external callers.Skips:
Probe,GetType,Contains,Scan,Free,RepoGrouprace losers, seek-reopens, failed/cancelled reads.Rejected alternatives
Open questions
read_atsemantics: eligible vs skip; fallback toCreatedAt.dbObjectis sparse and repo-agnostic — backfill on first scan, or add a repo column.Follow-up
--not-read <duration>filter on top of the order, once tracking lands.