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
impl BlobStream
Sourcepub fn plaintext_size(&self) -> u64
pub fn plaintext_size(&self) -> u64
The blob’s whole plaintext length, as proven when the stream opened. Every range must lie inside it.
Sourcepub async fn read_at(
&self,
offset: u64,
len: u64,
) -> Result<Vec<u8>, BlobCacheError>
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.