Trait BlobStore
pub trait BlobStore: Send + Sync {
// Required methods
fn read_blob(&self, guid: BlobGuid, dst: &mut AlignedBlobBuf) -> Result<()>;
fn write_blob(&self, guid: BlobGuid, src: &AlignedBlobBuf) -> Result<()>;
fn delete_blob(&self, guid: BlobGuid) -> Result<()>;
fn list_blobs(&self) -> Result<Vec<BlobGuid>>;
fn flush(&self) -> Result<()>;
// Provided methods
fn alloc_blob_buf_zeroed(&self) -> AlignedBlobBuf { ... }
fn alloc_blob_buf_uninit(&self) -> AlignedBlobBuf { ... }
fn write_blobs(&self, writes: &[(BlobGuid, &AlignedBlobBuf)]) -> Result<()> { ... }
fn write_blobs_with_data_sync(
&self,
writes: &[(BlobGuid, &AlignedBlobBuf)],
) -> Result<()> { ... }
fn needs_flush(&self) -> bool { ... }
fn has_blob(&self, guid: BlobGuid) -> Result<bool> { ... }
}Expand description
A blob-granular storage interface.
All implementations are Send + Sync so the buffer manager can
drive concurrent I/O from multiple worker threads.
§Contract
read_blob/write_blobalways operate on a fullPAGE_SIZE-byte frame. Partial I/O is not supported.write_blobis atomic at the blob level: either the entire new image is visible to subsequent reads, or the old image is. No torn writes (FileBlobStoreachieves this via O_DIRECT page-aligned writes on NVMe — physically atomic for ≤ 4 KB, logically atomic for 512 KB via journal coordination).flushblocks until every write that returned before the call is durable on the underlying medium.
Required Methods§
fn read_blob(&self, guid: BlobGuid, dst: &mut AlignedBlobBuf) -> Result<()>
fn read_blob(&self, guid: BlobGuid, dst: &mut AlignedBlobBuf) -> Result<()>
Read blob guid into dst. dst.len() == PAGE_SIZE.
fn write_blob(&self, guid: BlobGuid, src: &AlignedBlobBuf) -> Result<()>
fn write_blob(&self, guid: BlobGuid, src: &AlignedBlobBuf) -> Result<()>
Write src as blob guid. src.len() == PAGE_SIZE.
Returns once the write has been submitted to the medium.
Call BlobStore::flush to wait for it to be durable.
fn delete_blob(&self, guid: BlobGuid) -> Result<()>
fn delete_blob(&self, guid: BlobGuid) -> Result<()>
Delete blob guid. No-op if it doesn’t exist.
fn list_blobs(&self) -> Result<Vec<BlobGuid>>
fn list_blobs(&self) -> Result<Vec<BlobGuid>>
Enumerate every blob currently stored.
Provided Methods§
fn alloc_blob_buf_zeroed(&self) -> AlignedBlobBuf
fn alloc_blob_buf_zeroed(&self) -> AlignedBlobBuf
Allocate a zero-filled blob buffer suitable for this store.
The default is a heap-backed 4 KB-aligned frame. Linux
io_uring file stores override this to lease from
their registered fixed-buffer pool when available.
fn alloc_blob_buf_uninit(&self) -> AlignedBlobBuf
fn alloc_blob_buf_uninit(&self) -> AlignedBlobBuf
Allocate an uninitialized blob buffer suitable for this store. Callers must fill all bytes before reading.
fn write_blobs(&self, writes: &[(BlobGuid, &AlignedBlobBuf)]) -> Result<()>
fn write_blobs(&self, writes: &[(BlobGuid, &AlignedBlobBuf)]) -> Result<()>
Write a batch of full-blob images.
The default implementation loops over Self::write_blob.
Stores with a cheaper native batch path should override
this. The contract is conservative: if this returns Err,
the caller must assume an arbitrary prefix may have reached
the store and retry the whole batch later.
fn write_blobs_with_data_sync(
&self,
writes: &[(BlobGuid, &AlignedBlobBuf)],
) -> Result<()>
fn write_blobs_with_data_sync( &self, writes: &[(BlobGuid, &AlignedBlobBuf)], ) -> Result<()>
Write a batch and, if the store can do it cheaply, make the data-file bytes durable before returning.
This is deliberately narrower than Self::flush: callers
must still call flush to persist metadata/manifest changes.
The hook exists for Linux io_uring, where checkpoint
write batches can keep data writes and fdatasync on the
same ring turn, then let the later manifest flush skip the
data sync if no newer writes raced in.
fn needs_flush(&self) -> bool
fn needs_flush(&self) -> bool
Conservative hint for callers that want to skip a no-op
flush. Stores should return true whenever a prior
returned write, delete, or metadata update still needs
Self::flush to make it durable.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".