@@ -114,6 +114,44 @@ impl AsyncFileReader for ObjectReader {
114114 }
115115}
116116
117+ pub struct PrefetchReader {
118+ reader : Box < dyn AsyncFileReader > ,
119+ buffer : Bytes ,
120+ }
121+
122+ impl PrefetchReader {
123+ pub async fn new ( mut reader : Box < dyn AsyncFileReader > , prefetch : u64 ) -> Result < Self > {
124+ let buffer = reader. get_bytes ( 0 ..prefetch) . await ?;
125+ Ok ( Self { reader, buffer } )
126+ }
127+ }
128+
129+ impl AsyncFileReader for PrefetchReader {
130+ fn get_bytes ( & mut self , range : Range < u64 > ) -> BoxFuture < ' _ , Result < Bytes > > {
131+ if range. start < self . buffer . len ( ) as _ {
132+ if range. end < self . buffer . len ( ) as _ {
133+ let usize_range = range. start as usize ..range. end as usize ;
134+ let result = self . buffer . slice ( usize_range) ;
135+ async { Ok ( result) } . boxed ( )
136+ } else {
137+ // TODO: reuse partial internal buffer
138+ self . reader . get_bytes ( range)
139+ }
140+ } else {
141+ self . reader . get_bytes ( range)
142+ }
143+ }
144+
145+ fn get_byte_ranges ( & mut self , ranges : Vec < Range < u64 > > ) -> BoxFuture < ' _ , Result < Vec < Bytes > > >
146+ where
147+ Self : Send ,
148+ {
149+ // In practice, get_byte_ranges is only used for fetching tiles, which are unlikely to
150+ // overlap a metadata prefetch.
151+ self . reader . get_byte_ranges ( ranges)
152+ }
153+ }
154+
117155#[ derive( Debug , Clone , Copy , Default ) ]
118156pub enum Endianness {
119157 #[ default]
0 commit comments