@@ -212,6 +212,28 @@ impl<K: Hash + Eq + Clone, V> Cached<K, V> for TimedSizedCache<K, V> {
212
212
& mut stamped. 1
213
213
}
214
214
215
+ fn cache_try_get_or_set_with < F : FnOnce ( ) -> Result < V , E > , E > (
216
+ & mut self ,
217
+ key : K ,
218
+ f : F ,
219
+ ) -> Result < & mut V , E > {
220
+ let setter = || Ok ( ( Instant :: now ( ) , f ( ) ?) ) ;
221
+ let max_seconds = self . seconds ;
222
+ let ( was_present, was_valid, stamped) =
223
+ self . store . try_get_or_set_with_if ( key, setter, |stamped| {
224
+ stamped. 0 . elapsed ( ) . as_secs ( ) < max_seconds
225
+ } ) ?;
226
+ if was_present && was_valid {
227
+ if self . refresh {
228
+ stamped. 0 = Instant :: now ( ) ;
229
+ }
230
+ self . hits += 1 ;
231
+ } else {
232
+ self . misses += 1 ;
233
+ }
234
+ Ok ( & mut stamped. 1 )
235
+ }
236
+
215
237
fn cache_set ( & mut self , key : K , val : V ) -> Option < V > {
216
238
let stamped = self . store . cache_set ( key, ( Instant :: now ( ) , val) ) ;
217
239
stamped. and_then ( |( instant, v) | {
@@ -634,6 +656,27 @@ mod tests {
634
656
assert_eq ! ( c. cache_get_or_set_with( 6 , || 42 ) , & 6 ) ;
635
657
636
658
assert_eq ! ( c. cache_misses( ) , Some ( 11 ) ) ;
659
+
660
+ c. cache_reset ( ) ;
661
+ fn _try_get ( n : usize ) -> Result < usize , String > {
662
+ if n < 10 {
663
+ Ok ( n)
664
+ } else {
665
+ Err ( "dead" . to_string ( ) )
666
+ }
667
+ }
668
+
669
+ let res: Result < & mut usize , String > = c. cache_try_get_or_set_with ( 0 , || _try_get ( 10 ) ) ;
670
+ assert ! ( res. is_err( ) ) ;
671
+ assert ! ( c. key_order( ) . next( ) . is_none( ) ) ;
672
+
673
+ let res: Result < & mut usize , String > = c. cache_try_get_or_set_with ( 0 , || _try_get ( 1 ) ) ;
674
+ assert_eq ! ( res. unwrap( ) , & 1 ) ;
675
+ let res: Result < & mut usize , String > = c. cache_try_get_or_set_with ( 0 , || _try_get ( 5 ) ) ;
676
+ assert_eq ! ( res. unwrap( ) , & 1 ) ;
677
+ sleep ( Duration :: new ( 2 , 0 ) ) ;
678
+ let res: Result < & mut usize , String > = c. cache_try_get_or_set_with ( 0 , || _try_get ( 5 ) ) ;
679
+ assert_eq ! ( res. unwrap( ) , & 5 ) ;
637
680
}
638
681
639
682
#[ cfg( feature = "async" ) ]
0 commit comments