pub const CHEAP_DEPTH: u32 = 2;Expand description
The cheapest thing a cache can do is not cache.
The owner, 2026-08-30: “can the index point at the original git object and
decompress it directly instead of materialising everything?” — and it can,
because a packfile is not one stream. Every object is its own zlib stream at
its own offset, so oid → (offset, type, base, inflated size) is enough to
inflate exactly one object (crate::resolve::materialize_at). A whole
object is then one inflate of a mapped byte range: microseconds, no chain,
no delta application. Writing that into a cache costs a copy, a flush, an
fsync and a slice of somebody’s quota — to save microseconds it did not
need saving.
So the cache admits on rebuild cost, not on being read:
§It admits on cost DENSITY, not on cost
The first cut admitted anything over 16 KiB “because the inflate itself is the cost”. That is true and it is the wrong rule, because the budget is shared: what a cache should hold is what saves the most time per byte held. A 3 MiB whole blob costs one linear inflate — bandwidth-bound, microseconds a kilobyte — and would occupy the same 3 MiB as ~250 deep tree chains that each cost a chain walk. Admitting it evicts all of them.
| what the read paid | admitted? |
|---|---|
over MAX_CACHED_BYTES inflated | no — a bad tenant of a shared budget whatever its depth; its direct read is bandwidth-bound anyway |
depth 0–CHEAP_DEPTH | no — one inflate of one mapped zlib stream, plus at most two delta applications. Caching it spends quota to save microseconds |
deeper than CHEAP_DEPTH | yes — every extra link is another inflate plus a delta application, and git allows chains to 50 |
| a base outside this archive | yes — it went through a BaseSource, which is never the cheap path |
The thresholds are named, not tuned: CHEAP_DEPTH is 2 because git’s own
default pack.depth is 50 and a 0–2 chain is at most two delta applications
over a mapped buffer; MAX_CACHED_BYTES is 1 MiB because that is where one
object starts costing what hundreds of chain-heavy ones do.
This is also the zero-copy rule. A declined object is declined before
anything is copied, so the commonest reads — and every large one — cost the
cache exactly zero bytes. MEASURED by lane AA 2026-08-30: one 3 145 728 B
object read through gunnar-cli allocated 6 340 693 B, exactly two copies,
and the second was the cache taking a blob it should never have wanted.