2626//! This mirrors how `quickwit-search` uses the resolver:
2727//! `storage_resolver.resolve(&uri).await` per request, no global registry.
2828//!
29- //! Only read operations ( `get_opts`, `get_range`, `head`) are implemented.
30- //! All write and list operations return `NotSupported` — DataFusion only
31- //! reads parquet files through this store.
29+ //! Only `get_opts` is implemented. All write, delete, copy, and list
30+ //! operations return `NotSupported` — DataFusion only reads parquet files
31+ //! through this store.
3232
3333use std:: sync:: Arc ;
3434
3535use async_trait:: async_trait;
3636use bytes:: Bytes ;
37+ use futures:: StreamExt ;
3738use futures:: stream:: BoxStream ;
3839use object_store:: path:: Path as ObjectPath ;
3940use object_store:: {
40- GetOptions , GetRange , GetResult , GetResultPayload , ListResult , MultipartUpload , ObjectMeta ,
41- ObjectStore , PutMultipartOptions , PutOptions , PutPayload , PutResult ,
41+ CopyOptions , GetOptions , GetRange , GetResult , GetResultPayload , ListResult , MultipartUpload ,
42+ ObjectMeta , ObjectStore , PutMultipartOptions , PutOptions , PutPayload , PutResult ,
4243 Result as ObjectStoreResult ,
4344} ;
4445use quickwit_common:: uri:: Uri ;
@@ -127,10 +128,13 @@ impl ObjectStore for QuickwitObjectStore {
127128 let location_str = location. as_ref ( ) ;
128129 let map_err = |err| to_object_store_error ( err, location_str) ;
129130
130- let ( bytes, byte_range) = match options. range {
131+ let ( bytes, byte_range) = match & options. range {
131132 Some ( GetRange :: Bounded ( r) ) => {
132133 let usize_range = r. start as usize ..r. end as usize ;
133- let data = storage. get_slice ( & path, usize_range) . await . map_err ( map_err) ?;
134+ let data = storage
135+ . get_slice ( & path, usize_range)
136+ . await
137+ . map_err ( map_err) ?;
134138 let b = Bytes :: copy_from_slice ( data. as_ref ( ) ) ;
135139 let len = b. len ( ) as u64 ;
136140 // The storage may return fewer bytes than requested if the range
@@ -140,17 +144,24 @@ impl ObjectStore for QuickwitObjectStore {
140144 }
141145 Some ( GetRange :: Suffix ( n) ) => {
142146 let file_size = storage. file_num_bytes ( & path) . await . map_err ( map_err) ?;
143- let start = file_size. saturating_sub ( n) ;
147+ let start = file_size. saturating_sub ( * n) ;
144148 let usize_range = start as usize ..file_size as usize ;
145- let data = storage. get_slice ( & path, usize_range) . await . map_err ( map_err) ?;
149+ let data = storage
150+ . get_slice ( & path, usize_range)
151+ . await
152+ . map_err ( map_err) ?;
146153 let b = Bytes :: copy_from_slice ( data. as_ref ( ) ) ;
147154 let len = b. len ( ) as u64 ;
148155 ( b, start..start + len)
149156 }
150157 Some ( GetRange :: Offset ( start) ) => {
151158 let file_size = storage. file_num_bytes ( & path) . await . map_err ( map_err) ?;
159+ let start = * start;
152160 let usize_range = start as usize ..file_size as usize ;
153- let data = storage. get_slice ( & path, usize_range) . await . map_err ( map_err) ?;
161+ let data = storage
162+ . get_slice ( & path, usize_range)
163+ . await
164+ . map_err ( map_err) ?;
154165 let b = Bytes :: copy_from_slice ( data. as_ref ( ) ) ;
155166 let len = b. len ( ) as u64 ;
156167 ( b, start..start + len)
@@ -171,45 +182,22 @@ impl ObjectStore for QuickwitObjectStore {
171182 e_tag : None ,
172183 version : None ,
173184 } ;
185+ options. check_preconditions ( & meta) ?;
186+
187+ let payload = if options. head {
188+ GetResultPayload :: Stream ( Box :: pin ( futures:: stream:: empty ( ) ) )
189+ } else {
190+ GetResultPayload :: Stream ( Box :: pin ( futures:: stream:: once ( async { Ok ( bytes) } ) ) )
191+ } ;
192+
174193 Ok ( GetResult {
175- payload : GetResultPayload :: Stream ( Box :: pin ( futures :: stream :: once ( async { Ok ( bytes ) } ) ) ) ,
194+ payload,
176195 meta,
177196 range : byte_range,
178197 attributes : Default :: default ( ) ,
179198 } )
180199 }
181200
182- async fn get_range (
183- & self ,
184- location : & ObjectPath ,
185- range : std:: ops:: Range < u64 > ,
186- ) -> ObjectStoreResult < Bytes > {
187- let storage = self . storage ( ) . await ?;
188- let path = object_path_to_std ( location) ;
189- let usize_range = range. start as usize ..range. end as usize ;
190- let data = storage
191- . get_slice ( & path, usize_range)
192- . await
193- . map_err ( |err| to_object_store_error ( err, location. as_ref ( ) ) ) ?;
194- Ok ( Bytes :: copy_from_slice ( data. as_ref ( ) ) )
195- }
196-
197- async fn head ( & self , location : & ObjectPath ) -> ObjectStoreResult < ObjectMeta > {
198- let storage = self . storage ( ) . await ?;
199- let path = object_path_to_std ( location) ;
200- let size = storage
201- . file_num_bytes ( & path)
202- . await
203- . map_err ( |err| to_object_store_error ( err, location. as_ref ( ) ) ) ?;
204- Ok ( ObjectMeta {
205- location : location. clone ( ) ,
206- last_modified : chrono:: Utc :: now ( ) ,
207- size,
208- e_tag : None ,
209- version : None ,
210- } )
211- }
212-
213201 async fn put_opts (
214202 & self ,
215203 _location : & ObjectPath ,
@@ -231,10 +219,18 @@ impl ObjectStore for QuickwitObjectStore {
231219 } )
232220 }
233221
234- async fn delete ( & self , _location : & ObjectPath ) -> ObjectStoreResult < ( ) > {
235- Err ( object_store:: Error :: NotSupported {
236- source : "QuickwitObjectStore is read-only" . into ( ) ,
237- } )
222+ fn delete_stream (
223+ & self ,
224+ locations : BoxStream < ' static , ObjectStoreResult < ObjectPath > > ,
225+ ) -> BoxStream < ' static , ObjectStoreResult < ObjectPath > > {
226+ locations
227+ . map ( |location| match location {
228+ Ok ( _) => Err ( object_store:: Error :: NotSupported {
229+ source : "QuickwitObjectStore is read-only" . into ( ) ,
230+ } ) ,
231+ Err ( err) => Err ( err) ,
232+ } )
233+ . boxed ( )
238234 }
239235
240236 fn list (
@@ -257,16 +253,11 @@ impl ObjectStore for QuickwitObjectStore {
257253 } )
258254 }
259255
260- async fn copy ( & self , _from : & ObjectPath , _to : & ObjectPath ) -> ObjectStoreResult < ( ) > {
261- Err ( object_store:: Error :: NotSupported {
262- source : "QuickwitObjectStore is read-only" . into ( ) ,
263- } )
264- }
265-
266- async fn copy_if_not_exists (
256+ async fn copy_opts (
267257 & self ,
268258 _from : & ObjectPath ,
269259 _to : & ObjectPath ,
260+ _options : CopyOptions ,
270261 ) -> ObjectStoreResult < ( ) > {
271262 Err ( object_store:: Error :: NotSupported {
272263 source : "QuickwitObjectStore is read-only" . into ( ) ,
0 commit comments