pub struct BlockCache<F: AsyncFileReader> { /* private fields */ }Expand description
A caching wrapper that fetches fixed-size aligned blocks around each accessed offset.
Unlike a sequential readahead cache, a block cache handles the scattered access patterns of HDF5 metadata efficiently: the superblock is at offset 0, object headers and B-tree nodes are scattered across the file, and a sequential cache would waste bandwidth fetching unneeded array data between metadata structures.
When a byte range is requested, the cache fetches any aligned blocks that overlap the range and caches them for future reads. Nearby metadata reads (e.g., an object header and its continuation chunk, or adjacent B-tree nodes) naturally share blocks.
Default block size is 8 MiB, which typically resolves all metadata for a GOES-16 MCMIPF file (~164 datasets) in about 10 requests.
Implementations§
Source§impl<F: AsyncFileReader> BlockCache<F>
impl<F: AsyncFileReader> BlockCache<F>
Source§impl<F: AsyncFileReader> BlockCache<F>
impl<F: AsyncFileReader> BlockCache<F>
Sourcepub async fn pre_warm(&self, file_size: u64, max_bytes: u64) -> Result<()>
pub async fn pre_warm(&self, file_size: u64, max_bytes: u64) -> Result<()>
Pre-fetch blocks in parallel to eliminate sequential cache misses during metadata traversal (B-tree parsing, object headers, etc.).
- If
max_bytescovers the entire file, every block is fetched. - Otherwise only the first
max_bytes / block_sizeblocks are fetched (HDF5 metadata — superblock, root group, B-tree nodes — is typically concentrated near the beginning of the file).
Issues a single batched get_byte_ranges call so that the backend
can coalesce and parallelize the fetches.
Trait Implementations§
Source§impl<F: AsyncFileReader + Send + Sync> AsyncFileReader for BlockCache<F>
impl<F: AsyncFileReader + Send + Sync> AsyncFileReader for BlockCache<F>
Source§fn get_bytes<'life0, 'async_trait>(
&'life0 self,
range: Range<u64>,
) -> Pin<Box<dyn Future<Output = Result<Bytes>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_bytes<'life0, 'async_trait>(
&'life0 self,
range: Range<u64>,
) -> Pin<Box<dyn Future<Output = Result<Bytes>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_byte_ranges<'life0, 'async_trait>(
&'life0 self,
ranges: Vec<Range<u64>>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Bytes>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_byte_ranges<'life0, 'async_trait>(
&'life0 self,
ranges: Vec<Range<u64>>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Bytes>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
get_bytes
sequentially; ObjectReader overrides this with get_ranges().Source§fn file_size<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<u64>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn file_size<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<u64>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
BlockCache::pre_warm
to fetch all blocks in parallel. The default returns None.