@@ -4,6 +4,8 @@ use std::hash::Hash;
44use lru:: LruCache ;
55#[ cfg( feature = "ttl-cache" ) ]
66use std:: collections:: VecDeque ;
7+ use std:: fmt:: Debug ;
8+ use thiserror:: Error ;
79#[ cfg( feature = "ttl-cache" ) ]
810use std:: ops:: Add ;
911#[ cfg( feature = "ttl-cache" ) ]
@@ -12,15 +14,26 @@ use tokio::time::{Instant, Duration};
1214pub trait CacheBacking < K , V >
1315 where K : Eq + Hash + Sized + Clone + Send ,
1416 V : Sized + Clone + Send {
15- fn get_mut ( & mut self , key : & K ) -> Option < & mut V > ;
16- fn get ( & mut self , key : & K ) -> Option < & V > ;
17- fn set ( & mut self , key : K , value : V ) -> Option < V > ;
18- fn remove ( & mut self , key : & K ) -> Option < V > ;
19- fn contains_key ( & self , key : & K ) -> bool ;
20- fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send + ' static > ) ;
21- fn clear ( & mut self ) ;
17+ type Meta : Clone + Send ;
18+
19+ fn get_mut ( & mut self , key : & K ) -> Result < Option < & mut V > , BackingError > ;
20+ fn get ( & mut self , key : & K ) -> Result < Option < & V > , BackingError > ;
21+ fn set ( & mut self , key : K , value : V , meta : Option < Self :: Meta > ) -> Result < Option < V > , BackingError > ;
22+ fn remove ( & mut self , key : & K ) -> Result < Option < V > , BackingError > ;
23+ fn contains_key ( & self , key : & K ) -> Result < bool , BackingError > ;
24+ fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send + ' static > ) -> Result < ( ) , BackingError > ;
25+ fn clear ( & mut self ) -> Result < ( ) , BackingError > ;
2226}
2327
28+ #[ derive( Debug , Clone , Error ) ]
29+ pub enum BackingError {
30+ #[ error( transparent) ]
31+ TtlError ( #[ from] TtlError ) ,
32+ }
33+
34+ #[ derive( Copy , Clone , Debug , Default ) ]
35+ pub struct NoMeta { }
36+
2437#[ cfg( feature = "lru-cache" ) ]
2538pub struct LruCacheBacking < K , V > {
2639 lru : LruCache < K , V > ,
@@ -31,27 +44,29 @@ impl<
3144 K : Eq + Hash + Sized + Clone + Send ,
3245 V : Sized + Clone + Send
3346> CacheBacking < K , V > for LruCacheBacking < K , V > {
34- fn get_mut ( & mut self , key : & K ) -> Option < & mut V > {
35- self . lru . get_mut ( key)
47+ type Meta = NoMeta ;
48+
49+ fn get_mut ( & mut self , key : & K ) -> Result < Option < & mut V > , BackingError > {
50+ Ok ( self . lru . get_mut ( key) )
3651 }
3752
38- fn get ( & mut self , key : & K ) -> Option < & V > {
39- self . lru . get ( key)
53+ fn get ( & mut self , key : & K ) -> Result < Option < & V > , BackingError > {
54+ Ok ( self . lru . get ( key) )
4055 }
4156
42- fn set ( & mut self , key : K , value : V ) -> Option < V > {
43- self . lru . put ( key, value)
57+ fn set ( & mut self , key : K , value : V , _meta : Option < Self :: Meta > ) -> Result < Option < V > , BackingError > {
58+ Ok ( self . lru . put ( key, value) )
4459 }
4560
46- fn remove ( & mut self , key : & K ) -> Option < V > {
47- self . lru . pop ( key)
61+ fn remove ( & mut self , key : & K ) -> Result < Option < V > , BackingError > {
62+ Ok ( self . lru . pop ( key) )
4863 }
4964
50- fn contains_key ( & self , key : & K ) -> bool {
51- self . lru . contains ( & key. clone ( ) )
65+ fn contains_key ( & self , key : & K ) -> Result < bool , BackingError > {
66+ Ok ( self . lru . contains ( & key. clone ( ) ) )
5267 }
5368
54- fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send > ) {
69+ fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send > ) -> Result < ( ) , BackingError > {
5570 let keys = self . lru . iter ( )
5671 . filter_map ( |( key, value) | {
5772 if predicate ( ( key, value) ) {
@@ -65,10 +80,12 @@ impl<
6580 for key in keys. into_iter ( ) {
6681 self . lru . pop ( & key) ;
6782 }
83+ Ok ( ( ) )
6884 }
6985
70- fn clear ( & mut self ) {
86+ fn clear ( & mut self ) -> Result < ( ) , BackingError > {
7187 self . lru . clear ( ) ;
88+ Ok ( ( ) )
7289 }
7390}
7491
@@ -114,51 +131,71 @@ impl<K> From<(K, Instant)> for TTlEntry<K> {
114131 }
115132}
116133
134+ #[ derive( Debug , Clone , Error ) ]
135+ pub enum TtlError {
136+ #[ error( "The expiry for key not found" ) ]
137+ ExpiryNotFound ,
138+ #[ error( "No key for expiry matched key" ) ]
139+ ExpiryKeyNotFound ,
140+ }
141+
142+ #[ cfg( feature = "ttl-cache" ) ]
143+ #[ derive( Debug , Copy , Clone ) ]
144+ pub struct TtlMeta {
145+ pub ttl : Duration ,
146+ }
147+
148+ #[ cfg( feature = "ttl-cache" ) ]
149+ impl From < Duration > for TtlMeta {
150+ fn from ( ttl : Duration ) -> Self {
151+ Self { ttl }
152+ }
153+ }
154+
117155#[ cfg( feature = "ttl-cache" ) ]
118156impl <
119157 K : Eq + Hash + Sized + Clone + Send ,
120158 V : Sized + Clone + Send
121159> CacheBacking < K , V > for TtlCacheBacking < K , V > {
122- fn get_mut ( & mut self , key : & K ) -> Option < & mut V > {
160+ type Meta = TtlMeta ;
161+
162+ fn get_mut ( & mut self , key : & K ) -> Result < Option < & mut V > , BackingError > {
123163 self . remove_old ( ) ;
124- self . map . get_mut ( key)
125- . map ( |( value, _) | value)
164+ Ok ( self . map . get_mut ( key)
165+ . map ( |( value, _) | value) )
126166 }
127167
128- fn get ( & mut self , key : & K ) -> Option < & V > {
168+ fn get ( & mut self , key : & K ) -> Result < Option < & V > , BackingError > {
129169 self . remove_old ( ) ;
130- self . map . get ( key)
131- . map ( |( value, _) | value)
170+ Ok ( self . map . get ( key)
171+ . map ( |( value, _) | value) )
132172 }
133173
134- fn set ( & mut self , key : K , value : V ) -> Option < V > {
174+ fn set ( & mut self , key : K , value : V , meta : Option < Self :: Meta > ) -> Result < Option < V > , BackingError > {
135175 self . remove_old ( ) ;
136- let expiry = Instant :: now ( ) . add ( self . ttl ) ;
137- let result = self . replace ( key. clone ( ) , value, expiry) ;
138- match self . expiry_queue . binary_search_by_key ( & expiry, |entry| entry. expiry ) {
139- Ok ( found) => {
140- self . expiry_queue . insert ( found + 1 , ( key, expiry) . into ( ) ) ;
141- }
142- Err ( idx) => {
143- self . expiry_queue . insert ( idx, ( key, expiry) . into ( ) ) ;
144- }
145- }
146- result
176+ let ttl = if let Some ( meta) = meta {
177+ meta. ttl
178+ } else {
179+ self . ttl
180+ } ;
181+ let expiry = Instant :: now ( ) . add ( ttl) ;
182+ let result = self . replace ( key. clone ( ) , value, expiry) ?;
183+ Ok ( result)
147184 }
148185
149- fn remove ( & mut self , key : & K ) -> Option < V > {
186+ fn remove ( & mut self , key : & K ) -> Result < Option < V > , BackingError > {
150187 self . remove_old ( ) ;
151- self . remove_key ( key)
188+ Ok ( self . remove_key ( key) ? )
152189 }
153190
154- fn contains_key ( & self , key : & K ) -> bool {
191+ fn contains_key ( & self , key : & K ) -> Result < bool , BackingError > {
155192 // we cant clean old keys on this, since the self ref is not mutable :(
156- self . map . get ( key)
193+ Ok ( self . map . get ( key)
157194 . filter ( |( _, expiry) | Instant :: now ( ) . lt ( expiry) )
158- . is_some ( )
195+ . is_some ( ) )
159196 }
160197
161- fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send > ) {
198+ fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send > ) -> Result < ( ) , BackingError > {
162199 let keys = self . map . iter ( )
163200 . filter_map ( |( key, ( value, _) ) | {
164201 if predicate ( ( key, value) ) {
@@ -174,11 +211,13 @@ impl<
174211 // optimize looping through expiry_queue multiple times?
175212 self . expiry_queue . retain ( |entry| entry. key . ne ( & key) )
176213 }
214+ Ok ( ( ) )
177215 }
178216
179- fn clear ( & mut self ) {
217+ fn clear ( & mut self ) -> Result < ( ) , BackingError > {
180218 self . expiry_queue . clear ( ) ;
181219 self . map . clear ( ) ;
220+ Ok ( ( ) )
182221 }
183222}
184223
@@ -203,34 +242,43 @@ impl<K: Eq + Hash + Sized + Clone + Send, V: Sized + Clone + Send> TtlCacheBacki
203242 }
204243 }
205244
206- fn replace ( & mut self , key : K , value : V , expiry : Instant ) -> Option < V > {
245+ fn replace ( & mut self , key : K , value : V , expiry : Instant ) -> Result < Option < V > , TtlError > {
207246 let entry = self . map . insert ( key. clone ( ) , ( value, expiry) ) ;
208- self . cleanup_expiry ( entry, & key)
247+ let res = self . cleanup_expiry ( entry, & key) ;
248+ match self . expiry_queue . binary_search_by_key ( & expiry, |entry| entry. expiry ) {
249+ Ok ( found) => {
250+ self . expiry_queue . insert ( found + 1 , ( key, expiry) . into ( ) ) ;
251+ }
252+ Err ( idx) => {
253+ self . expiry_queue . insert ( idx, ( key, expiry) . into ( ) ) ;
254+ }
255+ }
256+ res
209257 }
210258
211- fn remove_key ( & mut self , key : & K ) -> Option < V > {
259+ fn remove_key ( & mut self , key : & K ) -> Result < Option < V > , TtlError > {
212260 let entry = self . map . remove ( key) ;
213261 self . cleanup_expiry ( entry, key)
214262 }
215263
216- fn cleanup_expiry ( & mut self , entry : Option < ( V , Instant ) > , key : & K ) -> Option < V > {
264+ fn cleanup_expiry ( & mut self , entry : Option < ( V , Instant ) > , key : & K ) -> Result < Option < V > , TtlError > {
217265 if let Some ( ( value, old_expiry) ) = entry {
218266 match self . expiry_queue . binary_search_by_key ( & old_expiry, |entry| entry. expiry ) {
219267 Ok ( found) => {
220268 let index = self . expiry_index_on_key_eq ( found, & old_expiry, key) ;
221269 if let Some ( index) = index {
222270 self . expiry_queue . remove ( index) ;
223271 } else {
224- // expiry not found (key)???
272+ return Err ( TtlError :: ExpiryKeyNotFound ) ;
225273 }
226274 }
227275 Err ( _) => {
228- // expiry not found???
276+ return Err ( TtlError :: ExpiryNotFound ) ;
229277 }
230278 }
231- Some ( value)
279+ Ok ( Some ( value) )
232280 } else {
233- None
281+ Ok ( None )
234282 }
235283 }
236284
@@ -274,32 +322,36 @@ impl<
274322 K : Eq + Hash + Sized + Clone + Send ,
275323 V : Sized + Clone + Send
276324> CacheBacking < K , V > for HashMapBacking < K , V > {
277- fn get_mut ( & mut self , key : & K ) -> Option < & mut V > {
278- self . map . get_mut ( key)
325+ type Meta = NoMeta ;
326+
327+ fn get_mut ( & mut self , key : & K ) -> Result < Option < & mut V > , BackingError > {
328+ Ok ( self . map . get_mut ( key) )
279329 }
280330
281- fn get ( & mut self , key : & K ) -> Option < & V > {
282- self . map . get ( key)
331+ fn get ( & mut self , key : & K ) -> Result < Option < & V > , BackingError > {
332+ Ok ( self . map . get ( key) )
283333 }
284334
285- fn set ( & mut self , key : K , value : V ) -> Option < V > {
286- self . map . insert ( key, value)
335+ fn set ( & mut self , key : K , value : V , _meta : Option < Self :: Meta > ) -> Result < Option < V > , BackingError > {
336+ Ok ( self . map . insert ( key, value) )
287337 }
288338
289- fn remove ( & mut self , key : & K ) -> Option < V > {
290- self . map . remove ( key)
339+ fn remove ( & mut self , key : & K ) -> Result < Option < V > , BackingError > {
340+ Ok ( self . map . remove ( key) )
291341 }
292342
293- fn contains_key ( & self , key : & K ) -> bool {
294- self . map . contains_key ( key)
343+ fn contains_key ( & self , key : & K ) -> Result < bool , BackingError > {
344+ Ok ( self . map . contains_key ( key) )
295345 }
296346
297- fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send > ) {
347+ fn remove_if ( & mut self , predicate : Box < dyn Fn ( ( & K , & V ) ) -> bool + Send > ) -> Result < ( ) , BackingError > {
298348 self . map . retain ( |k, v| !predicate ( ( k, v) ) ) ;
349+ Ok ( ( ) )
299350 }
300351
301- fn clear ( & mut self ) {
352+ fn clear ( & mut self ) -> Result < ( ) , BackingError > {
302353 self . map . clear ( ) ;
354+ Ok ( ( ) )
303355 }
304356}
305357
0 commit comments