pub fn walk_observed(
pack: &[u8],
oid_len: usize,
on_entry: &mut dyn FnMut(u64, u64),
) -> Result<PackWalk>Expand description
walk, telling somebody how far it has got, entry by entry.
§This is the walk, not a second one
There is exactly one place on this system that knows how many objects of a
pack have been taken in while the taking is still happening, and it is the
loop below: a pack entry carries no length, so finding the boundaries is
how the pack gets split at all, and the loop already inflates every entry to
find where the next one starts. Counting the entries as they go past is
therefore free — no extra pass, no extra inflate, not one byte decompressed
that was not already being decompressed. Any other way of learning the same
number would be a second pack decoder, which LAW 5 forbids and which
gunnar-wire’s fetch_pack refuses for the same reason.
on_entry is called once per entry, after that entry is accounted for,
with (entries so far, the count the header declared). Per entry and not
per batch because the loop is per entry: batching here would be inventing a
coarseness the code does not have.
§&mut dyn FnMut and not a generic
walk and this are one function, and a generic parameter would
monomorphise the whole 70-line body a second time for the no-op closure —
the same machine code twice, on the push hot path, so that a call that
publishes nothing can skip an indirect call it makes once per object. The
dyn call is dwarfed by the inflate on the line above it.