7
7
//! Specific pieces of configuration must implement the `TryUpdateKey` trait which
8
8
//! defines how to update internal fields based on key-value pairs.
9
9
use std:: collections:: HashMap ;
10
+ use std:: sync:: Arc ;
10
11
11
12
use :: object_store:: RetryConfig ;
12
13
use object_store:: { path:: Path , prefix:: PrefixStore , ObjectStore } ;
13
14
15
+ use super :: storage:: file_cache:: { self , FileCacheConfig } ;
14
16
use super :: storage:: LimitConfig ;
15
17
use super :: { storage:: runtime:: RuntimeConfig , IORuntime } ;
16
18
use crate :: { DeltaResult , DeltaTableError } ;
@@ -102,6 +104,11 @@ pub struct StorageConfig {
102
104
/// Configuration to limit the number of concurrent requests to the object store.
103
105
pub limit : Option < LimitConfig > ,
104
106
107
+ /// File cache configuration.
108
+ ///
109
+ /// Configuration to enable file cache for the Delta Log Store.
110
+ pub file_cache : Option < FileCacheConfig > ,
111
+
105
112
/// Properties that are not recognized by the storage configuration.
106
113
///
107
114
/// These properties are ignored by the storage configuration and can be used for custom purposes.
@@ -120,12 +127,27 @@ impl StorageConfig {
120
127
/// Depending on the configuration, the following layers may be added:
121
128
/// - Retry layer: Adds retry logic to the object store.
122
129
/// - Limit layer: Limits the number of concurrent requests to the object store.
130
+ /// - File cache layer: Adds a file cache to the object store.
123
131
pub fn decorate_store < T : ObjectStore + Clone > (
124
132
& self ,
125
133
store : T ,
126
134
table_root : & url:: Url ,
127
135
) -> DeltaResult < Box < dyn ObjectStore > > {
128
- let inner = Self :: decorate_prefix ( store, table_root) ?;
136
+ let inner = self . decorate_root_store ( store) ?;
137
+ let inner = Self :: decorate_prefix ( inner, table_root) ?;
138
+ Ok ( inner)
139
+ }
140
+
141
+ /// Wraps an object store with additional layers of functionality without prefix.
142
+ pub ( crate ) fn decorate_root_store < T : ObjectStore > (
143
+ & self ,
144
+ store : T ,
145
+ ) -> DeltaResult < Box < dyn ObjectStore > > {
146
+ let inner = if let Some ( file_cache) = self . file_cache . as_ref ( ) {
147
+ file_cache:: decorate_store ( Arc :: new ( store) , file_cache) ?
148
+ } else {
149
+ Box :: new ( store)
150
+ } ;
129
151
Ok ( inner)
130
152
}
131
153
@@ -222,6 +244,11 @@ impl StorageConfig {
222
244
remainder
223
245
} ;
224
246
247
+ let result = ParseResult :: < FileCacheConfig > :: from_iter ( remainder) ;
248
+ result. raise_errors ( ) ?;
249
+ props. file_cache = ( !result. is_default ) . then_some ( result. config ) ;
250
+ let remainder = result. unparsed ;
251
+
225
252
props. unknown_properties = remainder;
226
253
Ok ( props)
227
254
}
@@ -396,4 +423,36 @@ mod tests {
396
423
StorageConfig :: default ( ) . with_io_runtime ( IORuntime :: Config ( RuntimeConfig :: default ( ) ) ) ;
397
424
assert ! ( config. runtime. is_some( ) ) ;
398
425
}
426
+
427
+ #[ test]
428
+ fn test_file_cache_config_from_options ( ) {
429
+ let options = hashmap ! {
430
+ "file_cache_path" . to_string( ) => "/tmp/file_cache" . to_string( ) ,
431
+ } ;
432
+
433
+ let ( file_cache_config, remainder) : ( FileCacheConfig , _ ) =
434
+ super :: try_parse_impl ( options) . unwrap ( ) ;
435
+ assert ! ( remainder. is_empty( ) ) ;
436
+
437
+ assert_eq ! ( file_cache_config. path, "/tmp/file_cache" ) ;
438
+ assert ! ( file_cache_config. last_checkpoint_valid_duration. is_none( ) ) ;
439
+ }
440
+
441
+ #[ test]
442
+ fn test_file_cache_config_from_options_with_last_checkpoint_valid_duration ( ) {
443
+ let options = hashmap ! {
444
+ "file_cache_path" . to_string( ) => "/tmp/file_cache" . to_string( ) ,
445
+ "file_cache_last_checkpoint_valid_duration" . to_string( ) => "1h" . to_string( ) ,
446
+ } ;
447
+
448
+ let ( file_cache_config, remainder) : ( FileCacheConfig , _ ) =
449
+ super :: try_parse_impl ( options) . unwrap ( ) ;
450
+ assert ! ( remainder. is_empty( ) ) ;
451
+
452
+ assert_eq ! ( file_cache_config. path, "/tmp/file_cache" ) ;
453
+ assert_eq ! (
454
+ file_cache_config. last_checkpoint_valid_duration,
455
+ Some ( Duration :: from_secs( 3600 ) )
456
+ ) ;
457
+ }
399
458
}
0 commit comments