Skip to main content

Module scan_cache

Module scan_cache 

Source
Expand description

OT.3b — agenda scan results, remembered across restarts.

OT.3 priced the parse at 1–2 ms per file (benches/agenda_scan_input.rs). An agenda is refreshed far more often than its files change — gr, reopening the view, an autocmd, and every editor restart — and without a cache each of those reparses the whole project and re-calls the guest for every file.

§What is cached, and why not the tree

The rows, not the parse tree. Tree-sitter has no serialisation for a Tree — there is no to_bytes / from_bytes in the crate — so a persistent cache physically cannot hold snapshots. It has to hold what the scan derived, which is also what org-roam’s database holds for the same reason.

That turns out to be the better layer anyway: a hit skips the parse and the guest call, where a snapshot cache would only have skipped the parse.

§What it does NOT skip

The read. You cannot know a file is unchanged without looking at it, and the host reads it upstream regardless (it needs the text to build the source Document). A warm read is ~10–50 µs against a ~2 ms parse, so this is the cheap end and not worth an mtime pre-filter’s correctness risk.

§The key

(generation, path, content-hash).

Content hash, not mtime. The text is already in hand, so hashing costs ~2–5 µs against the ~2 ms it protects, and it is exactly right: no one-second mtime granularity, no filesystem that lies, no length collision to paper over. A file that came back byte-identical genuinely produces the same rows.

Generation is the opaque u64 the guest returns from begin — for org, derived from the day the scan is anchored to and the configured TODO keywords. Cached rows embed presentation computed against that anchor ("tomorrow", "overdue by 2 day(s)"), so serving them under a different anchor would render yesterday’s “tomorrow” as tomorrow — silently wrong at midnight, which is the exact bug begin’s anchor exists to prevent. Keying on the generation makes a cached value a pure function of its key, so that cannot happen: the day rolls, the generation changes, the cache is discarded.

The host never learns what a date group or a TODO keyword is. It compares two integers.

§Failure behaviour

Every failure degrades to “no cache”, never to an error and never to a wrong answer: a missing file, a schema-version mismatch, corrupt bytes, an unreadable directory, a failed write. A cache that cannot be trusted is simply not used, and the scan runs as it did before OT.3b.

Structs§

ScanCache
A persistent agenda-result cache for one source.