Expand description
One pass over a pushed packfile’s entries — the split the closure check falls out of. Ours, gated against gix’s grammar entry for entry. The split: one pass over a pushed packfile’s entries, and nothing else.
This is what crate::store’s put_pack walks before it stores a byte, and
it is the reason the closure check costs nothing extra (§13.7): the walk
has to visit every entry anyway to find where the next one starts, so the set
of entry boundaries and the set of delta bases fall out of it for free. No
index is consulted to answer is this pack self-contained.
§What it does NOT do
It does not compute oids. An entry’s oid is
sha1("<type> <size>\0" ‖ inflated content), and for a delta that content
only exists after the chain is resolved — that is git index-pack’s job, it
is the indexer’s work by §13.9 (“the index is built after the ack, over a
channel”), and it is deliberately not on the ack path. So a [PackEntry]
carries the five facts the pack itself states — extent, type, declared
size and delta base — and no more.
§Why the bytes are inflated but the output is thrown away
A pack entry has no length field. The only way to find entry n+1 is to run
the zlib stream of entry n to its end and ask the decompressor how many
input bytes it consumed. So the walk pays one inflate over the pack — but
it never materialises an object: the output goes into one reusable
[SCRATCH]-sized buffer and is discarded, so peak memory is the scratch
buffer and not the repository. total_out is still checked against the
declared size, because a stream that inflates to a different length than its
header claims is a corrupt pack and the honest answer is an error.
§Whose grammar is this
Ours, and §18 is the reason it is allowed to be: the plan records the choice
between keeping gix as a grammar library and writing the two parsers
ourselves as open, and it prescribes exactly how to settle it — “write the
two parsers, and gate them behind a test that runs both ours and gix’s over a
real corpus and requires byte-identical output on every entry”. That gate is
[tests::ours_and_gix_agree_on_every_entry_of_every_pack], which drives
gix_pack::data::input::BytesToEntriesIter (a dev-dependency, so no gix
crate enters a shipped archiver) over the same bytes and requires the five
facts to match entry for entry. Writing the parser is therefore executing the
plan’s decision procedure, not pre-empting its decision: if the gate ever
fails, gix is the arbiter and this module is wrong.
The one dependency it adds is flate2 on its pure-Rust zlib-rs backend —
the same crate and the same backend ldeflate already pulls in
non-optionally through znippy-common, so the build graph is unchanged: no
C, no cmake, no build-script network, and --no-default-features still
builds in seconds.
Structs§
- Closure
- What the closure check found. Derived from the walk alone — no index, no disk, no oid resolution.
- Emit
Entry - One object to emit: where its stored entry is, and what it deltas against.
- Emit
Report - What emitting produced, in facts a caller can assert on.
- Pack
Entry - One entry, as the pack itself states it.
- Pack
Walk - What one pass over a pack found.
Enums§
- Delta
Base - Where a delta entry’s base is.
- Entry
Bytes - Where an entry’s bytes are — an address into the archive, or bytes that exist nowhere else.
Functions§
- emit_
pack - Assemble ordered entries into a packfile.
- encode_
ofs_ distance - Encode an
OFS_DELTAbackwards distance — the inverse of [ofs_distance]. - encode_
type_ and_ size - Encode the type/size header — the inverse of [
type_and_size]. - header_
len - How many bytes of a stored entry are header — everything before the compressed payload.
- ofs_
distance_ of - An
OFS_DELTA’s backwards distance to its base, and how many bytes it occupied.bstarts immediately after the type/size varint. - resolve_
against - One entry’s bytes, resolved against a buffer that spans the archive’s
coordinate space — the in-memory resolver, and the one
emit_pack’s callers use when the archive is a&[u8]rather than a mapping. - topological_
order - Order
entriesso that every delta follows the base it names. - type_
and_ size_ of - The type/size varint, for a caller outside this module that needs to find where an entry’s header ends — reading the grammar rather than assuming a width.
- walk
- Walk a pushed pack’s entries.