Skip to content

Commit e2e97f5

Browse files
committed
made cachereader
1 parent 42c1389 commit e2e97f5

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/reader.rs

+57
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,63 @@ impl AsyncFileReader for PrefetchReader {
207207
}
208208
}
209209

210+
211+
/// reader that holds a cache. Because of interior mutability, it will always
212+
/// lock the cache (twice) for each get_bytes. This also special-cases
213+
/// get_tile_bytes
214+
/// When doing metadata fetches, it will fetch twice the requested size for the cache
215+
///
216+
#[derive(Debug)]
217+
pub struct CacheReader {
218+
reader: Arc<dyn AsyncFileReader>,
219+
cache: Arc<Mutex<(Range<u64>, Bytes)>>, // not sure if this should be an async_mutex on wasm-like environments to prevent blocking the main thread
220+
}
221+
222+
impl CacheReader {
223+
/// creates a ew cachereader with empty cache
224+
pub fn new(reader: Arc<dyn AsyncFileReader>) -> Self {
225+
Self {
226+
reader,
227+
cache: Arc::new(Mutex::new((0..0, Bytes::new()))),
228+
}
229+
}
230+
}
231+
232+
impl AsyncFileReader for CacheReader {
233+
fn get_bytes(&self, range: Range<u64>) -> BoxFuture<'_, AsyncTiffResult<Bytes>> {
234+
{
235+
let lock = self.cache.lock().unwrap_or_else(|e| e.into_inner());
236+
// check for cache
237+
if range.start >= lock.0.start /*&& range.start < lock.0.end*/ && range.end <= lock.0.end
238+
{
239+
let usize_range =
240+
(range.start - lock.0.start) as usize..(range.end - lock.0.start) as usize;
241+
let result = lock.1.slice(usize_range);
242+
return async { Ok(result) }.boxed();
243+
} else {
244+
println!("range {:?} doesn't contain {range:?}", lock.0);
245+
}
246+
}
247+
async move {
248+
let range_len = range.end - range.start;
249+
// this is based on a geometric series, since each overview is 1/2
250+
// the size, the n of tiles (~area) of the next overview is 1/4
251+
// however, due to the edges, this underestimates, and we'd rather
252+
// over-estimate I think?
253+
// So we add the edge of the next overview as well, which would give
254+
// 1.5*isqrt, so we round up.
255+
let full_len = 2 * range_len + 2 * range_len.isqrt();
256+
let new_range = range.start..range.start + full_len;
257+
println!("range {range:?} requested, fetching {new_range:?}");
258+
let res = self.reader.get_bytes(new_range.clone()).await?;
259+
let mut lock = self.cache.lock().unwrap_or_else(|e| e.into_inner());
260+
*lock = (new_range, res.clone());
261+
Ok(res.slice(0..(range.end - range.start) as usize))
262+
}
263+
.boxed()
264+
}
265+
}
266+
210267
#[derive(Debug, Clone, Copy)]
211268
pub(crate) enum Endianness {
212269
LittleEndian,

0 commit comments

Comments
 (0)