Struct FileBlobStore
pub struct FileBlobStore { /* private fields */ }Expand description
NVMe-backed, O_DIRECT, single-packed-file blob store.
Construct via FileBlobStore::open. Thread-safe; the
underlying file handle is shared and pread/pwrite are
atomic at the syscall boundary.
Implementations§
§impl FileBlobStore
impl FileBlobStore
pub fn open<P: Into<PathBuf>>(data_dir: P) -> Result<Self>
pub fn open<P: Into<PathBuf>>(data_dir: P) -> Result<Self>
Open or create a persistent store at data_dir.
Creates the directory if missing. On Linux opens the packed
data file with O_DIRECT | O_CLOEXEC; on other Unixes opens
with O_CLOEXEC only (macOS additionally sets F_NOCACHE).
Loads the manifest if present; otherwise starts empty.
Trait Implementations§
§impl BlobStore for FileBlobStore
impl BlobStore for FileBlobStore
§fn read_blobs(
&self,
guids: &[BlobGuid],
dsts: &mut [AlignedBlobBuf],
) -> Vec<Result<()>> ⓘ
fn read_blobs( &self, guids: &[BlobGuid], dsts: &mut [AlignedBlobBuf], ) -> Vec<Result<()>> ⓘ
Batched full-frame read. On io_uring every read goes down a
single ring submission (one Mutex acquire, queue depth =
batch width) instead of N serialised pread_at calls; on the
pread path the lock-free positional reads fan out across
worker threads for the same device parallelism.
§fn read_blob_range(
&self,
guid: BlobGuid,
byte_offset: u64,
dst: &mut [u8],
) -> Result<()>
fn read_blob_range( &self, guid: BlobGuid, byte_offset: u64, dst: &mut [u8], ) -> Result<()>
Positional ranged read for page-granular cold lookups. byte_offset,
dst.len(), and dst’s base must be 4 KB-aligned (whole pages) so the
O_DIRECT / F_NOCACHE read is accepted; the buffer-manager paging
layer guarantees this. Goes straight through read_exact_at (a plain
positional pread) rather than the 512 KB-tuned io_uring ring.
§fn alloc_blob_buf_zeroed(&self) -> AlignedBlobBuf
fn alloc_blob_buf_zeroed(&self) -> AlignedBlobBuf
§fn read_blob(&self, guid: BlobGuid, dst: &mut AlignedBlobBuf) -> Result<()>
fn read_blob(&self, guid: BlobGuid, dst: &mut AlignedBlobBuf) -> Result<()>
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<()>
§fn write_blobs(&self, writes: &[(BlobGuid, &AlignedBlobBuf)]) -> Result<()>
fn write_blobs(&self, writes: &[(BlobGuid, &AlignedBlobBuf)]) -> Result<()>
§fn write_blobs_with_data_sync(
&self,
writes: &[(BlobGuid, &AlignedBlobBuf)],
) -> Result<()>
fn write_blobs_with_data_sync( &self, writes: &[(BlobGuid, &AlignedBlobBuf)], ) -> Result<()>
§fn delete_blob(&self, guid: BlobGuid) -> Result<()>
fn delete_blob(&self, guid: BlobGuid) -> Result<()>
guid. No-op if it doesn’t exist.§fn list_blobs(&self) -> Result<Vec<BlobGuid>>
fn list_blobs(&self) -> Result<Vec<BlobGuid>>
§fn needs_flush(&self) -> bool
fn needs_flush(&self) -> bool
true whenever a prior
returned write, delete, or metadata update still needs
Self::flush to make it durable.