pub fn plan(
request: &Request,
delivery: &Delivery,
route: Route,
) -> Result<Plan, RequestError>Expand description
Validate a request and derive the least-retention plan for its delivery and route.
A summary reducer is legal when no content analysis is requested, the sole requested
view is an unfiltered summary, the scan retains its whole population, and the policy
does not require the snapshot to participate. crate::open and live sessions still
promise an index and therefore always plan full retention. Any future requirement the
compact tier cannot prove falls closed to RetainedState::FullIndex.
Control observation is the caller’s decision, not this planner’s: a report’s rows carry
the ignored share of every size they show (fdu-elnn), so a scan that reads .gitignore
displays what it paid for, and one that turned it off shows no share rather than a zero.
The summary reducer classifies each entry against the control table the index would
hold and folds the ignored share without retaining the entry (fdu-1ovb), so the default
fdu --view summary takes it as well. A narrowed population (--ignored=exclude|only)
is also a selection by ignored state, which is_unfiltered sends to the index; the
planner checks the scope’s population as well rather than rest on validation pairing
the two.
The compact tier is not gated on the cache being unavailable, because for an
unfiltered metadata summary the snapshot cannot save the work the scan is doing.
Revalidating a loaded snapshot stats every entry anyway, so the reusable index and its
write are additive cost with nothing to amortise them: measured on Linux/ext4 over
84,539 entries, the compact tier answered in 71 ms against 161 ms for a warm
revalidating Auto run, and even a no-scan stale answer cost 81 ms because
deserialisation is about as expensive per record as a warm walk. A snapshot earns its
keep when it avoids expensive work — re-reading file bodies for content analysis, or a
cold filesystem walk — not when it merely mirrors a walk that still has to happen.
Two deliveries still require the index, for reasons that are about intent rather than
cost. Delivery::stale_ok must answer from the snapshot without touching the tree,
so it has no scan to reduce. CachePolicy::On is an explicit request to leave a
current snapshot, and honouring it means materialising the index that gets written —
though with no cache path configured there is nothing to write, and the compact tier
answers it like any other summary.
A tree takes a folded index under the same route, policy, and analysis conditions,
when TreeRetention::for_request finds the tree projection is its only reader and
its share threshold bounds the rows it can show. Every directory is kept, since the
tree shows directories by their subtree totals; only files too small to be shown are
folded into their directory. The default fdu PATH is such a tree: at its 1% share
the index keeps at most a hundred files.
Persistence follows the same reasoning as the read. Under CachePolicy::Auto a
one-shot metadata report writes nothing, because no later one-shot report reads what
it would store: on a million-entry Linux tree the write was 0.26 s of a 1.51 s default
run. Content analysis writes, because its sidecar spares re-reading unchanged files
and is paired with the snapshot beside it; sessions, watches, and refreshes write,
because they are the later reader.