Skip to main content

StreamingPackBuilder

Struct StreamingPackBuilder 

Source
pub struct StreamingPackBuilder<W: Write + Read + Seek> { /* private fields */ }
Expand description

Streaming pack builder. Held generic over the pack writer (File in production, Cursor<Vec<u8>> in tests).

Implementations§

Source§

impl<W: Write + Read + Seek> StreamingPackBuilder<W>

Source

pub fn new( pack_writer: W, index_path: PathBuf, compression: CompressionConfig, bucket_dir: PathBuf, ) -> Result<Self>

Open a streaming builder against pack_writer, using bucket_dir for transient index buckets and writing the finalized index to index_path. The bucket dir is created if it doesn’t exist; on a successful finalize it’s removed (along with any bucket files left in it).

index_path is not created by new — opening happens at finalize so a misconfigured caller doesn’t leave an empty index file behind on early failure. It’s still recorded here so finalize can write to a known location and the caller can install the file by path.

The pack_writer must support Read because finalize re-streams the body to compute the trailer checksum — see the module-level note on the format.

Source

pub fn add( &mut self, hash: ContentHash, obj_type: ObjectType, data: Vec<u8>, ) -> Result<()>

Add an object with a content-hash id.

Source

pub fn add_id( &mut self, id: PackObjectId, obj_type: ObjectType, data: Vec<u8>, ) -> Result<()>

Add an object with an explicit id. Mirrors super::PackBuilder::add_id.

§Memory shape

Per-entry, the only allocations are:

  • data: Vec<u8> (the input, owned by the caller — comes from gix’ find_object and isn’t ours to stream further).
  • A ~40-byte stack scratch for the entry header.
  • zstd’s internal compression context (~128 KB constant).
  • One 50-byte index-bucket entry buffered into the bucket’s BufWriter.

The compressed payload is never materialized as a Vec<u8> — it streams directly through zstd::stream::write::Encoder into the pack writer. The pack format requires a compressed_size varint before the compressed bytes, which we don’t know yet when we write the header; we reserve a 10-byte placeholder and seek-back to patch it after the encoder finishes. Heddle’s varint decoder accepts non-canonical encodings (it walks continuation bits without enforcing minimum-byte form), so the padded write decodes back to the same value any reader expects.

Source

pub fn finalize(self) -> Result<(W, PackStats)>

Close the pack: patch the header count, append the BLAKE3 trailer, build the sorted index from bucket files, and clean up the bucket directory. Returns (pack_writer, index_bytes, stats) so the caller can install the pack into its store.

On any failure the bucket dir is left in place; rerunning the import will overwrite stale bucket files (they’re keyed by fixed name, not content) so this isn’t a correctness issue — just a small amount of disk churn until the next clean finalize.

Trait Implementations§

Source§

impl<W: Write + Read + Seek> Drop for StreamingPackBuilder<W>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<W> Freeze for StreamingPackBuilder<W>
where W: Freeze,

§

impl<W> RefUnwindSafe for StreamingPackBuilder<W>
where W: RefUnwindSafe,

§

impl<W> Send for StreamingPackBuilder<W>
where W: Send,

§

impl<W> Sync for StreamingPackBuilder<W>
where W: Sync,

§

impl<W> Unpin for StreamingPackBuilder<W>
where W: Unpin,

§

impl<W> UnsafeUnpin for StreamingPackBuilder<W>
where W: UnsafeUnpin,

§

impl<W> UnwindSafe for StreamingPackBuilder<W>
where W: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more