@@ -35,6 +35,7 @@ type Fetch = Box<dyn Fn(usize, usize) -> Result<Vec<u8>> + Send + Sync>;
35
35
36
36
pub struct LazyBuffer {
37
37
blocks : HashMap < usize , LazyBlock > ,
38
+ blocks_read : HashMap < usize , usize > ,
38
39
block_size : usize ,
39
40
download_threshold : usize ,
40
41
length : usize ,
@@ -45,6 +46,7 @@ impl LazyBuffer {
45
46
pub fn new ( length : usize , block_size : usize , download_threshold : usize , fetch : Fetch ) -> Self {
46
47
Self {
47
48
blocks : HashMap :: new ( ) ,
49
+ blocks_read : HashMap :: new ( ) ,
48
50
block_size,
49
51
download_threshold,
50
52
length,
@@ -76,13 +78,25 @@ impl LazyBuffer {
76
78
}
77
79
let block_index = offset / self . block_size ;
78
80
let block_offset = offset - block_index * self . block_size ;
79
- if !self . blocks . contains_key ( & block_index) && buf. len ( ) <= self . download_threshold {
81
+ let block_read = self
82
+ . blocks_read
83
+ . get ( & block_index)
84
+ . copied ( )
85
+ . unwrap_or_default ( ) ;
86
+ let buffer_size = buf. len ( ) ;
87
+ if !self . blocks . contains_key ( & block_index)
88
+ && block_read + buffer_size <= self . download_threshold
89
+ {
80
90
// skip full block fetch if buf is smaller than download_threshold
81
- let data = ( self . fetch ) ( offset, buf . len ( ) ) ?;
82
- if data. len ( ) != buf . len ( ) {
91
+ let data = ( self . fetch ) ( offset, buffer_size ) ?;
92
+ if data. len ( ) != buffer_size {
83
93
return Err ( Error :: new ( ErrorKind :: UnexpectedEof , "read out of bounds" ) ) ;
84
94
}
85
95
buf. copy_from_slice ( & data) ;
96
+ self . blocks_read
97
+ . entry ( block_index)
98
+ . and_modify ( |size| * size += buffer_size)
99
+ . or_insert ( buffer_size) ;
86
100
} else {
87
101
self . get_block ( block_index) ?. read ( buf, block_offset) ?;
88
102
}
0 commit comments