Skip to main content

SegmentCache

Trait SegmentCache 

Source
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 | None and put(key: str, segment_id: int, data: Buffer) -> None. vortex.open and vortex.open_readable accept it with the cache_key that they accept now, and the stubs declare it as a typing.Protocol. Then users can use cachetools, diskcache, Redis, or a cache that many processes share.
  • A Rust adapter holds the Python object and the SegmentSourceId of one file, and implements this trait. get calls Python through spawn_blocking and Python::attach, as PyReadable::read_at does, and wraps the buffer that Python returns without a copy. put gives Python a read-only object that owns a clone of the ByteBuffer and exports it through __getbuffer__, as ReadBuffer does, so Python can keep it without a copy.

Required Methods§

Source

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.

Source

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".

Implementors§