@@ -244,7 +244,7 @@ impl AsyncFileReader for Bytes {
244
244
async { Ok ( self . slice ( usize_range) ) } . boxed ( )
245
245
} else {
246
246
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 ) ;
248
248
async move { Err ( AsyncTiffError :: EndOfFile ( range_len, range_read) ) } . boxed ( )
249
249
}
250
250
}
@@ -254,7 +254,9 @@ impl AsyncFileReader for Bytes {
254
254
/// holds a cache for out-of-prefetch metadata.
255
255
///
256
256
/// 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.
258
260
///
259
261
/// # Examples
260
262
///
@@ -280,7 +282,7 @@ impl AsyncFileReader for Bytes {
280
282
/// *reader.get_metadata_bytes(start..start + len).await?,
281
283
/// [42; 16 * 1024]
282
284
/// );
283
- ///
285
+ ///
284
286
/// // this is now also (exactly) cached
285
287
/// assert_eq!(
286
288
/// *reader
@@ -291,7 +293,7 @@ impl AsyncFileReader for Bytes {
291
293
///
292
294
/// // this will not check the cache
293
295
/// reader.get_image_bytes(start..start + len).await?;
294
- ///
296
+ ///
295
297
/// # Ok::<(),AsyncTiffError>(())
296
298
/// # });
297
299
/// ```
@@ -338,7 +340,20 @@ impl AsyncFileReader for PrefetchReader {
338
340
}
339
341
// determine new cache size
340
342
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 _ ) ;
342
357
let new_c_range = range. start ..range. start + estimate;
343
358
344
359
// put in new cache
0 commit comments