pub trait SegmentCache: Send + Sync {
// Required methods
fn get<'life0, 'async_trait>(
&'life0 self,
id: SegmentId,
) -> Pin<Box<dyn Future<Output = VortexResult<Option<ByteBuffer>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn put<'life0, 'async_trait>(
&'life0 self,
id: SegmentId,
buffer: ByteBuffer,
) -> Pin<Box<dyn Future<Output = VortexResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
}Expand description
Cache for individual segment byte buffers.
Caches are optional and operate above a SegmentSource. They should only store host buffers:
device buffers and other non-host handles should be passed through uncached.
To bring your own cache, implement this trait and give it to the file with
VortexOpenOptions::with_segment_cache. A SegmentId is unique only within one file, so a
cache that many files share must also key its entries by file. Give each file its own
implementation of this trait that holds the SegmentSourceId of that file and adds it to
the key, as MokaSegmentCache::for_file does with FileSegmentCache.
The Python bindings accept only a MokaSegmentCache. A cache written in Python can use the
same design as PyReadable in vortex-python:
- The Python object has the methods
get(key: str, segment_id: int) -> Buffer | Noneandput(key: str, segment_id: int, data: Buffer) -> None.vortex.openandvortex.open_readableaccept it with thecache_keythat they accept now, and the stubs declare it as atyping.Protocol. Then users can usecachetools,diskcache, Redis, or a cache that many processes share. - A Rust adapter holds the Python object and the
SegmentSourceIdof one file, and implements this trait.getcalls Python throughspawn_blockingandPython::attach, asPyReadable::read_atdoes, and wraps the buffer that Python returns without a copy.putgives Python a read-only object that owns a clone of theByteBufferand exports it through__getbuffer__, asReadBufferdoes, so Python can keep it without a copy.
Required Methods§
Sourcefn get<'life0, 'async_trait>(
&'life0 self,
id: SegmentId,
) -> Pin<Box<dyn Future<Output = VortexResult<Option<ByteBuffer>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get<'life0, 'async_trait>(
&'life0 self,
id: SegmentId,
) -> Pin<Box<dyn Future<Output = VortexResult<Option<ByteBuffer>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Return a cached segment, or None on cache miss.
Lookups may be polled while a segment request is constructed, before its returned future is polled. Ready misses preserve the source’s eager read registration. Pending lookups delay registration until they resolve and the caller polls the request, which can reduce read coalescing. This prevents cache hits from registering source reads.
Sourcefn put<'life0, 'async_trait>(
&'life0 self,
id: SegmentId,
buffer: ByteBuffer,
) -> Pin<Box<dyn Future<Output = VortexResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn put<'life0, 'async_trait>(
&'life0 self,
id: SegmentId,
buffer: ByteBuffer,
) -> Pin<Box<dyn Future<Output = VortexResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Store a segment in the cache.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".