From 274d3b6dce75837aad967a62514694419d42a97f Mon Sep 17 00:00:00 2001 From: Anthony Lukach Date: Sun, 23 Nov 2025 15:26:31 +1300 Subject: [PATCH 1/2] refactor: rename ExponentialMetadataCache to ReadAheadMetadataCache and update to support configuration --- src/metadata/cache.rs | 41 +++++++++++++++++++++++------------------ src/metadata/mod.rs | 2 +- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/metadata/cache.rs b/src/metadata/cache.rs index c823411..39de28c 100644 --- a/src/metadata/cache.rs +++ b/src/metadata/cache.rs @@ -87,45 +87,50 @@ impl SequentialCache { /// A MetadataFetch implementation that caches fetched data in exponentially growing chunks, /// sequentially from the beginning of the file. -pub struct ExponentialMetadataCache { +pub struct ReadAheadMetadataCache { inner: F, cache: Arc>, + + initial_size: u64, + increment_multiple: u64, } -impl ExponentialMetadataCache { - /// Create a new ExponentialMetadataCache wrapping the given MetadataFetch - pub fn new(inner: F) -> AsyncTiffResult { +impl ReadAheadMetadataCache { + /// Create a new EagerMetadataCache wrapping the given MetadataFetch + pub fn new(inner: F, initial_size: u64, increment_multiple: u64) -> AsyncTiffResult { Ok(Self { inner, cache: Arc::new(Mutex::new(SequentialCache::new())), + initial_size, + increment_multiple, }) } -} -fn next_fetch_size(existing_len: u64) -> u64 { - if existing_len == 0 { - 64 * 1024 - } else { - existing_len * 2 + fn next_fetch_size(&self, current_len: u64) -> u64 { + if current_len == 0 { + self.initial_size + } else { + current_len * self.increment_multiple + } } } -impl MetadataFetch for ExponentialMetadataCache { +impl MetadataFetch for ReadAheadMetadataCache { fn fetch(&self, range: Range) -> BoxFuture<'_, AsyncTiffResult> { let cache = self.cache.clone(); Box::pin(async move { - let mut g = cache.lock().await; + let mut cache = cache.lock().await; // First check if we already have the range cached - if g.contains(range.start..range.end) { - return Ok(g.slice(range)); + if cache.contains(range.start..range.end) { + return Ok(cache.slice(range)); } // Compute the correct fetch range - let start_len = g.len; + let start_len = cache.len; let needed = range.end.saturating_sub(start_len); - let fetch_size = next_fetch_size(start_len).max(needed); + let fetch_size = &self.next_fetch_size(start_len).max(needed); let fetch_range = start_len..start_len + fetch_size; // Perform the fetch while holding mutex @@ -133,9 +138,9 @@ impl MetadataFetch for ExponentialMetadataCache< let bytes = self.inner.fetch(fetch_range).await?; // Now append safely - g.append_buffer(bytes); + cache.append_buffer(bytes); - Ok(g.slice(range)) + Ok(cache.slice(range)) }) } } diff --git a/src/metadata/mod.rs b/src/metadata/mod.rs index b566eff..6df0de2 100644 --- a/src/metadata/mod.rs +++ b/src/metadata/mod.rs @@ -62,6 +62,6 @@ pub mod cache; mod fetch; mod reader; -pub use cache::ExponentialMetadataCache; +pub use cache::ReadAheadMetadataCache; pub use fetch::{MetadataFetch, PrefetchBuffer}; pub use reader::{ImageFileDirectoryReader, TiffMetadataReader}; From 0037d48919057f6c79830acf1d280ddcc6d2ca3b Mon Sep 17 00:00:00 2001 From: Anthony Lukach Date: Sun, 23 Nov 2025 15:32:56 +1300 Subject: [PATCH 2/2] Fixup --- src/metadata/cache.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/metadata/cache.rs b/src/metadata/cache.rs index 39de28c..dbac62d 100644 --- a/src/metadata/cache.rs +++ b/src/metadata/cache.rs @@ -97,7 +97,16 @@ pub struct ReadAheadMetadataCache { impl ReadAheadMetadataCache { /// Create a new EagerMetadataCache wrapping the given MetadataFetch - pub fn new(inner: F, initial_size: u64, increment_multiple: u64) -> AsyncTiffResult { + pub fn new(inner: F) -> AsyncTiffResult { + Self::with_increment_configuration(inner, 32 * 1024, 2) + } + + /// Create a new EagerMetadataCache with custom initial size and increment multiple + pub fn with_increment_configuration( + inner: F, + initial_size: u64, + increment_multiple: u64, + ) -> AsyncTiffResult { Ok(Self { inner, cache: Arc::new(Mutex::new(SequentialCache::new())),