pub trait StorageBackend: Send + Sync {
// Required methods
fn read(&mut self, requests: &[ReadRequest], stream: u64) -> Result<()>;
fn write_from_host(&mut self, key: GroupKey, src: &[u8]) -> Result<()>;
fn group_layout(&self) -> GroupLayout;
// Provided methods
fn read_async(
&mut self,
requests: &[ReadRequest],
stream: u64,
) -> Result<()> { ... }
fn read_blocks(
&mut self,
requests: &[BlockReadRequest],
stream: u64,
) -> Result<()> { ... }
fn read_blocks_async(
&mut self,
requests: &[BlockReadRequest],
stream: u64,
) -> Result<()> { ... }
fn write_block_from_host(
&mut self,
base_key: GroupKey,
src: &[u8],
) -> Result<()> { ... }
fn write_blocks_run(
&mut self,
base_key: GroupKey,
run_len: usize,
src: &[u8],
) -> Result<()> { ... }
fn supports_write_run_coalescing(&self) -> bool { ... }
fn register_landing_region(&mut self, base: u64, len: usize) -> Result<()> { ... }
}Required Methods§
Sourcefn read(&mut self, requests: &[ReadRequest], stream: u64) -> Result<()>
fn read(&mut self, requests: &[ReadRequest], stream: u64) -> Result<()>
Synchronously fulfil all requests, returning when the corresponding
HBM destinations are populated and visible on stream. The backend
chooses how to schedule (blocking POSIX pread, batched io_uring,
etc.). At return, the stream has been synchronised so the caller
can issue subsequent kernels that depend on the data.
Sourcefn write_from_host(&mut self, key: GroupKey, src: &[u8]) -> Result<()>
fn write_from_host(&mut self, key: GroupKey, src: &[u8]) -> Result<()>
One-shot sequential write — used at offload time to populate disk from a host-side K/V buffer.
Sourcefn group_layout(&self) -> GroupLayout
fn group_layout(&self) -> GroupLayout
Immutable disk/device geometry. The default block methods below use it to fan a block op back out to the per-head path; io_uring/posix return their layout spec, Cascade delegates to its backing, RDMA returns its layout.
Provided Methods§
Sourcefn read_async(&mut self, requests: &[ReadRequest], stream: u64) -> Result<()>
fn read_async(&mut self, requests: &[ReadRequest], stream: u64) -> Result<()>
Async variant of read: enqueue the tier read + H2D on stream and
return WITHOUT a terminal host stream_sync. Default = the synchronous
read, so file backends need no change and the on-demand path stays
byte-identical.
Sourcefn read_blocks(
&mut self,
requests: &[BlockReadRequest],
stream: u64,
) -> Result<()>
fn read_blocks( &mut self, requests: &[BlockReadRequest], stream: u64, ) -> Result<()>
Block-granular read: fulfil each request with ONE contiguous
block_bytes op instead of 2·nkv per-head reads. Same stream contract
as read. The DEFAULT fans out to read via expand_blocks_to_groups,
so posix/RDMA/Cascade stay correct (just un-coalesced) with no change.
Sourcefn read_blocks_async(
&mut self,
requests: &[BlockReadRequest],
stream: u64,
) -> Result<()>
fn read_blocks_async( &mut self, requests: &[BlockReadRequest], stream: u64, ) -> Result<()>
Async block-granular read — the coalesced twin of read_async for the
prefetch path. DEFAULT fans out to read_async.
Sourcefn write_block_from_host(
&mut self,
base_key: GroupKey,
src: &[u8],
) -> Result<()>
fn write_block_from_host( &mut self, base_key: GroupKey, src: &[u8], ) -> Result<()>
Block-granular write: ONE contiguous block_bytes op. src is exactly
block_bytes laid out [K0,K1,…,K(nkv-1),V0,…,V(nkv-1)] at group_stride
pitch. base_key carries the block identity (kv_head/kind ignored).
DEFAULT splits src back into the 2·nkv per-head group_stride stripes
and calls write_from_host per head — byte-identical on-disk image.
Sourcefn write_blocks_run(
&mut self,
base_key: GroupKey,
run_len: usize,
src: &[u8],
) -> Result<()>
fn write_blocks_run( &mut self, base_key: GroupKey, run_len: usize, src: &[u8], ) -> Result<()>
Write a run of run_len strictly-consecutive same-layer blocks in ONE
contiguous op. base_key carries the run’s FIRST block; src is exactly
run_len · block_bytes. DEFAULT fans out to run_len
write_block_from_host calls — byte- AND op-identical to the
un-coalesced path (and run_len == 1 is exactly one call).
Sourcefn supports_write_run_coalescing(&self) -> bool
fn supports_write_run_coalescing(&self) -> bool
Whether this backend can service write_blocks_run as a single wide op.
DEFAULT false: RDMA/Cascade keep the per-block fan-out, and the caller
stays on the per-block write path.