pub trait CacheManager: Send + Sync {
// Required methods
fn put<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page: Bytes,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page_offset: usize,
dst: &'life2 mut [u8],
) -> Pin<Box<dyn Future<Output = usize> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn invalidate<'life0, 'life1, 'async_trait>(
&'life0 self,
file_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn state(&self) -> CacheState;
// Provided methods
fn schedule_fill(self: Arc<Self>, page_id: PageId, page: Bytes)
where Self: 'static { ... }
fn get_bytes<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page_offset: usize,
len: usize,
) -> Pin<Box<dyn Future<Output = Bytes> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn get_batch_bytes<'life0, 'life1, 'async_trait>(
&'life0 self,
requests: &'life1 [PageReadRequest],
) -> Pin<Box<dyn Future<Output = Vec<Bytes>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_file_open<'life0, 'life1, 'async_trait>(
&'life0 self,
_file_id: &'life1 str,
_length: i64,
_last_modification_time_ms: i64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Expand description
Local page cache abstraction.
Implementations coordinate the metadata/eviction cache, disk store and locking to serve cached pages. See the module docs for the best-effort contract.
All methods are intentionally infallible (bool / usize rather than
Result): cache failures must never propagate as read errors.
Required Methods§
Sourcefn put<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page: Bytes,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn put<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page: Bytes,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Store (fill) a whole page.
page should be the full page bytes (≤ page size). Returns true if
the page was cached, false otherwise (e.g. cache full, racing write,
or cache not in ReadWrite state).
Sourcefn get<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page_offset: usize,
dst: &'life2 mut [u8],
) -> Pin<Box<dyn Future<Output = usize> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn get<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page_offset: usize,
dst: &'life2 mut [u8],
) -> Pin<Box<dyn Future<Output = usize> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Read dst.len() bytes from page page_id starting at page_offset
into dst.
Returns the number of bytes actually read. 0 means a cache miss (or
any internal error): the caller must read from the worker/UFS instead.
Sourcefn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Delete a single page. Returns true if a page was removed.
Sourcefn invalidate<'life0, 'life1, 'async_trait>(
&'life0 self,
file_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn invalidate<'life0, 'life1, 'async_trait>(
&'life0 self,
file_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Invalidate all cached pages belonging to file_id.
Used when a file is overwritten or deleted so stale pages are not served. Implementations should treat this as best-effort.
Sourcefn state(&self) -> CacheState
fn state(&self) -> CacheState
Current operational state.
Provided Methods§
Sourcefn schedule_fill(self: Arc<Self>, page_id: PageId, page: Bytes)where
Self: 'static,
fn schedule_fill(self: Arc<Self>, page_id: PageId, page: Bytes)where
Self: 'static,
Schedule a best-effort cache fill that does not block the caller.
The default implementation spawns a detached task that calls
CacheManager::put. Implementations with bounded async write-back
override this to apply back-pressure (rejecting fills when the
write-back pool is saturated, recording
Client.CachePutAsyncRejectionErrors).
Sourcefn get_bytes<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page_offset: usize,
len: usize,
) -> Pin<Box<dyn Future<Output = Bytes> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_bytes<'life0, 'life1, 'async_trait>(
&'life0 self,
page_id: &'life1 PageId,
page_offset: usize,
len: usize,
) -> Pin<Box<dyn Future<Output = Bytes> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Read bytes from a cached page and return the owned Bytes directly.
The default implementation preserves the legacy get contract by
reading into a caller-owned buffer. io_uring-backed implementations
override this to return the kernel-filled buffer directly, avoiding one
extra copy on cache hits.
Sourcefn get_batch_bytes<'life0, 'life1, 'async_trait>(
&'life0 self,
requests: &'life1 [PageReadRequest],
) -> Pin<Box<dyn Future<Output = Vec<Bytes>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_batch_bytes<'life0, 'life1, 'async_trait>(
&'life0 self,
requests: &'life1 [PageReadRequest],
) -> Pin<Box<dyn Future<Output = Vec<Bytes>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Read multiple cached pages. Each output corresponds to the request at
the same index; an empty Bytes means miss or cache error.
Sourcefn on_file_open<'life0, 'life1, 'async_trait>(
&'life0 self,
_file_id: &'life1 str,
_length: i64,
_last_modification_time_ms: i64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_file_open<'life0, 'life1, 'async_trait>(
&'life0 self,
_file_id: &'life1 str,
_length: i64,
_last_modification_time_ms: i64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Notify the cache that a file was (re)opened with the given identity.
Implementations compare (length, last_modification_time_ms) against
the version recorded for file_id; if they differ (the file was
overwritten while reusing the same id), all cached pages for that file
are invalidated so stale data is never served. The default
implementation is a no-op.
Consistency caveat (best-effort): overwrite detection relies on the
modification-time granularity reported by the backing UFS. On a UFS that
only exposes second-level mtime, two writes of equal length within the
same second (and any same-(length, mtime) in-place overwrite) are
indistinguishable and may serve stale pages until the entry is evicted
or its TTL elapses. Use a short client_cache_ttl — or extend the
identity with an etag/version — where the UFS cannot guarantee
millisecond mtime precision.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".