Skip to main content

BlobStream

Struct BlobStream 

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

One opened blob’s plaintext, ready to serve ranges. Held by a host that is streaming or seeking a blob (playback probing a codec header, then a tail, then decoding forward) rather than loading it whole.

The stream owns the open file handle its identity was proven through (local_blob::OpenExactFile), which is what lets read_at cost only the bytes it returns. Proving a blob’s identity means reading all of it, so proving it per range makes every range cost the whole blob; proving it once at [open_blob_stream] and then reading the descriptor that was proven costs the whole blob once per stream.

Holding the descriptor is what makes that safe rather than merely cheaper. A path can be replaced between two reads; the descriptor cannot — it refers to the bytes that were hashed for as long as the stream lives, even if the file is evicted, renamed, or deleted from under it. So the stream serves exactly the plaintext the row named when it opened, and nothing can be swapped in behind it.

What that leaves uncovered is an in-place rewrite of the descriptor’s own file. A blob’s identity is one hash over its whole content, so there is nothing smaller to re-check a single range against — catching a mid-stream rewrite would mean re-reading the whole blob per range, which is the cost this type exists to remove. It is reachable only for a file the user owns and edits themselves: coven’s own copies (the local store, pinned/, cache/) are published by rename or hard link and never written in place, so for those the swap case above is the only one there is. [read_blob] and the next [open_blob_stream] both re-prove the file and reject a rewritten one.

Implementations§

Source§

impl BlobStream

Source

pub fn plaintext_size(&self) -> u64

The blob’s whole plaintext length, as proven when the stream opened. Every range must lie inside it.

Source

pub async fn read_at( &self, offset: u64, len: u64, ) -> Result<Vec<u8>, BlobCacheError>

Serve len plaintext bytes starting at offset from the proven handle: one positioned read, no hashing, no cloud, no reopening by path.

len == 0 is an empty result, and an offset + len past the blob’s plaintext size (or an overflow) is an error, never a short read. The size checked against is the one proven at open, so the bound is the file’s real length rather than a number the caller supplied.

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

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,