Expand description
A read memo with the lifetime of one operation — the cheap half of not reading the same file twice.
prov’s passes are composed rather than fused: check runs a walk, then an
orphan sweep, then a fixity pass, then five more, and each of them starts
from a path and calls load on it. That composition is what makes the
passes independently testable and independently correct, and it is worth
keeping — but taken literally it means check reads and parses the same
document once per pass that cares about it. The walk loads every reachable
document to build the census; fixity_findings then loads every reachable
document again to hash its body. Two full reads and two full parses, for a
question the first read already answered.
So remember the answer for as long as the operation lasts, and no longer.
§Why the scope, and why it is explicit
A memo with no end is a cache, and a cache has to be invalidated. A memo
bounded by an operation barely has to be: nothing outside prov can write
to the workspace between two of check’s sub-passes in any sense prov could
have detected anyway, and everything inside prov that writes goes through
prov’s ChangeSet, which forgets what it touched
(Workspace::commit). There is no staleness window left that a stat could
have closed and this cannot.
The scope is explicit — a caller opens one with
Graph::read_scope and holds the guard — because a memo that switched
itself on would be a cache again, and because the caller is the only one who
knows where its operation begins. Scopes nest: an operation that opens one
and then calls another that opens its own gets a single memo lasting the
outer one, which is exactly the composition case (history_capture opens a
scope and then calls reachable_files, which is welcome to open its own).
§What is not memoized
Failures. A read that errored is not remembered, so a missing file is re-checked rather than pinned to its first answer — the cost is one syscall on a path prov already knows is trouble, and the alternative is a memo that can report a file absent after it appeared.
Structs§
- Read
Memo - What one operation has already read.
- Read
Scope - An open read scope. Hold it for the operation; dropping it leaves the scope, and dropping the outermost one drops everything the operation remembered.
Functions§
- lock
- Take a lock, recovering from a panic that poisoned it.