Skip to content

Commit feefadd

Browse files
committed
made minimum block size equal to prefetch, added explanations
1 parent feefadd commit feefadd

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

src/reader.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl AsyncFileReader for Bytes {
244244
async { Ok(self.slice(usize_range)) }.boxed()
245245
} else {
246246
let range_len = range.end - range.start;
247-
let range_read = range_len - (range.end-self.len() as u64);
247+
let range_read = range_len - (range.end - self.len() as u64);
248248
async move { Err(AsyncTiffError::EndOfFile(range_len, range_read)) }.boxed()
249249
}
250250
}
@@ -254,7 +254,9 @@ impl AsyncFileReader for Bytes {
254254
/// holds a cache for out-of-prefetch metadata.
255255
///
256256
/// When a request is out-of-bounds, an estimate of the remaining
257-
/// `tile_offsets`/`tile_byte_counts` array is made as `2*(len+2*len.isqrt())`
257+
/// `tile_offsets`+`tile_byte_counts` array is made as
258+
/// `(2*len+4*len.isqrt()).max(prefetch)`, where `len` is the length of the
259+
/// requested range and `prefetch` is the size of the prefetch buffer.
258260
///
259261
/// # Examples
260262
///
@@ -280,7 +282,7 @@ impl AsyncFileReader for Bytes {
280282
/// *reader.get_metadata_bytes(start..start + len).await?,
281283
/// [42; 16 * 1024]
282284
/// );
283-
///
285+
///
284286
/// // this is now also (exactly) cached
285287
/// assert_eq!(
286288
/// *reader
@@ -291,7 +293,7 @@ impl AsyncFileReader for Bytes {
291293
///
292294
/// // this will not check the cache
293295
/// reader.get_image_bytes(start..start + len).await?;
294-
///
296+
///
295297
/// # Ok::<(),AsyncTiffError>(())
296298
/// # });
297299
/// ```
@@ -338,7 +340,20 @@ impl AsyncFileReader for PrefetchReader {
338340
}
339341
// determine new cache size
340342
let range_len = range.end - range.start;
341-
let estimate = 2 * (range_len + 2 * range_len.isqrt()).max(8 * 1024);
343+
// estimate (for bigtiff):
344+
// each overview is 1/4 the previous =geometric series=> 4/3*range_len
345+
// assume request was TileOffsets =Long8+Long=> 3/2*4/3*range_len = 2*range_len
346+
//
347+
// add edge of one overview down:
348+
// n_tiles0 = range_len/8
349+
// n_tiles1 = 1/4*n_tiles0
350+
// edge_tiles1 ≈ √n_tiles1 = √range_len/√2⁶ = √range_len/(4√2)
351+
// each edge is 1/2 the previous =geometric series=> 2*edge_tiles1 = √range_len/(2√2)
352+
// edge_bytes = 8*√range_len/(2√2) = 4/√2*√range_len
353+
// Long8+Long => 3/2*4/√2*√range_len = 6/√2*√range_len ≈ 4*√range_len
354+
//
355+
// 2*range_len+4*√range_len
356+
let estimate = (2 * range_len + 4 * range_len.isqrt()).max(self.buffer.len() as _);
342357
let new_c_range = range.start..range.start + estimate;
343358

344359
// put in new cache

0 commit comments

Comments
 (0)