Skip to main content

BytesGatherer

Struct BytesGatherer 

Source
pub struct BytesGatherer { /* private fields */ }
Expand description

A scatter-gather buffer that threads large blobs through the response pipeline by reference, eliminating application-layer copies for bulk data such as post bundles.

§Motivation

When serving a GetPostBundleV1 response the post bundle payload (potentially hundreds of KB, already brotli-compressed on disk) was previously copied multiple times before reaching the network. Then at the transport boundary the single Bytes was handed to HTTPS/TCP with no opportunity for vectored writes.

BytesGatherer fixes this by threading large blobs through the entire response path by reference. Small POD fields (header bytes, JSON metadata) accumulate into an internal BytesMut scratchpad, while large payloads are attached with push_bytes — a refcount bump only, no memcpy. At the transport boundary compact merges any adjacent small segments, sets Content-Length, and HTTP/2 receives a stream of Bytes chunks as separate DATA frames.

**Net result for GetPostBundle, the hottest-path of Hashiverse: ** multiple application-layer copies of the post bundle → 0. One kernel copy to the network card remains (unavoidable).

After compact(1024) the segment layout for a typical GetPostBundle response looks like:

Segment 0: [rpc_header (~300 B) + response_header (peers/token/counts) (~50 B) + flag (1 B)]
           ← merged by compact, one BytesMut flush
Segment 1: post_bundle Bytes (e.g. 500 KB)
           ← original Bytes from disk, zero copy

HTTP/2 sends these as 2 DATA frames. TCP concatenates to 1 contiguous buffer via to_bytes.

Implementations§

Source§

impl BytesGatherer

Source

pub fn from_bytes(bytes: Bytes) -> Self

Source

pub fn put_u8(&mut self, v: u8)

Source

pub fn put_u16_le(&mut self, v: u16)

Source

pub fn put_u16(&mut self, v: u16)

Source

pub fn put_u32_le(&mut self, v: u32)

Source

pub fn put_u32(&mut self, v: u32)

Source

pub fn put_u64(&mut self, v: u64)

Source

pub fn put_slice(&mut self, s: &[u8])

Source

pub fn put_bytes(&mut self, bytes: Bytes)

Push a large blob — flush accumulator first, store blob by reference (zero copy).

Source

pub fn put_bytes_gatherer(&mut self, other: BytesGatherer)

Merge another gatherer — zero copy for blobs; fast path if both are still assembling.

If other has no committed segments yet (all bytes are still in its scratchpad), the scratchpad bytes are appended directly into self.current — no flush, no new segment.

Source

pub fn is_empty(&self) -> bool

Returns true if the gatherer contains no bytes.

Source

pub fn len(&self) -> usize

Total byte count across all segments + current accumulator.

Source

pub fn compact(self, threshold: usize) -> Self

Merge adjacent segments smaller than threshold bytes into single segments. Large segments pass through untouched (zero copy). Generally, gall this at the transport boundary before streaming to optimise streaming window fragmentation.

Source

pub fn finish(self) -> Vec<Bytes>

Consume into Vec<Bytes> for streaming / vectored I/O.

Source

pub fn to_bytes(self) -> Bytes

Consume into one contiguous Bytes. Zero-copy fast path: single segment returned directly.

Trait Implementations§

Source§

impl Default for BytesGatherer

Source§

fn default() -> BytesGatherer

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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.

§

impl<T> Instrument for T

§

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

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

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

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

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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