pub struct PackWriter { /* private fields */ }Expand description
Builds a packfile, enforcing entry/payload caps and streaming each
pushed entry’s frame directly into the final output buffer as it
arrives. Self::finish only patches the header’s entry count
(unknown up front from a streaming writer) and appends the trailer —
it never re-copies the pushed entries into a second, same-sized
buffer (issue #647).
Implementations§
Source§impl PackWriter
impl PackWriter
Sourcepub fn push_raw(
&mut self,
hash_of_bytes: Hash,
bytes: &[u8],
) -> Result<Hash, PackError>
pub fn push_raw( &mut self, hash_of_bytes: Hash, bytes: &[u8], ) -> Result<Hash, PackError>
Append a raw object entry. bytes is the fully serialised object
payload; hash_of_bytes is the BLAKE3 of those same bytes —
callers usually have it on hand from the object store, so we take
it explicitly to avoid an extra BLAKE3 pass over the same buffer.
Takes bytes by reference (not by value): the streaming writer
copies it straight into the output buffer as it’s pushed, so it
never needs to own the caller’s copy (issue #647). Returns the
same hash for chaining.
Applies the SPEC-PACKFILE §3.3 compression policy transparently:
if bytes compresses under zstd strictly smaller on the wire
(and is long enough to bother, see MIN_COMPRESS_LEN), this
emits a 0x03 zstd-raw entry instead of 0x00 raw — callers
never need to opt in. Either way the returned/stored identity
(hash_of_bytes) is unchanged; only the wire encoding differs.
Sourcepub fn push_delta(
&mut self,
base_hash: &Hash,
delta_stream: &[u8],
) -> Result<(), PackError>
pub fn push_delta( &mut self, base_hash: &Hash, delta_stream: &[u8], ) -> Result<(), PackError>
Append a delta entry. base_hash MUST refer to an earlier raw
entry in this pack OR an object already in the destination store.
delta_stream MUST be a valid SPEC-DELTA stream — we don’t
re-validate here (the writer is trusted), but the reader will.
Applies the same §3.3 compression policy as Self::push_raw,
but ONLY to delta_stream — base_hash is always written
uncompressed (SPEC-PACKFILE §3.4), so ordering/base-discovery
logic never needs to decompress anything. Emits 0x04
zstd-delta when the stream compresses strictly smaller on the
wire and is long enough to bother; 0x02 delta otherwise.
Sourcepub fn entry_count(&self) -> usize
pub fn entry_count(&self) -> usize
Number of entries pushed so far. Useful for sizing diagnostics.
Sourcepub fn total_payload(&self) -> u64
pub fn total_payload(&self) -> u64
Sum of wire payload bytes pushed so far — the quantity the
writer’s own internal cap check compares against
MAX_TOTAL_PAYLOAD. Measured post-compression (SPEC-PACKFILE
§5): each push_raw/push_delta call adds the wire payload
length, not the caller’s uncompressed input length. Callers
deciding whether to seal a pack before pushing another entry can
use a conservative uncompressed-length estimate against this
value — the actual wire cost is never more than that estimate,
since compression is only ever applied when it’s strictly
smaller (see maybe_compress).
Sourcepub fn finish(self) -> Result<Vec<u8>, PackError>
pub fn finish(self) -> Result<Vec<u8>, PackError>
Serialise the pack: header + entries + trailer. Entries are
already in self.buf (streamed in by push_raw/push_delta);
finish patches the header’s version (SPEC-PACKFILE §1: v2
iff at least one entry ended up compressed, v1 otherwise) and
entry_count, then appends the trailer,
BLAKE3(everything_before_trailer). The whole pack’s BLAKE3 is
the on-disk pack key — see pack_key.
Trait Implementations§
Source§impl Debug for PackWriter
impl Debug for PackWriter
Auto Trait Implementations§
impl Freeze for PackWriter
impl RefUnwindSafe for PackWriter
impl Send for PackWriter
impl Sync for PackWriter
impl Unpin for PackWriter
impl UnsafeUnpin for PackWriter
impl UnwindSafe for PackWriter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more