@@ -115,7 +115,7 @@ pub struct EvictingMap<T: LenEntry + Debug, I: InstantWrapper> {
115
115
116
116
impl < T , I > EvictingMap < T , I >
117
117
where
118
- T : LenEntry + Debug + Clone + Send + Sync ,
118
+ T : LenEntry + Debug + Clone + Send + Sync + ' static ,
119
119
I : InstantWrapper ,
120
120
{
121
121
pub fn new ( config : & EvictionPolicy , anchor_time : I ) -> Self {
@@ -168,7 +168,7 @@ where
168
168
) ;
169
169
}
170
170
// Just in case we allow for some cleanup (eg: old items).
171
- self . evict_items ( state. deref_mut ( ) ) . await ;
171
+ self . evict_items ( state. deref_mut ( ) ) ;
172
172
}
173
173
174
174
fn should_evict ( & self , lru_len : usize , peek_entry : & EvictionItem < T > , sum_store_size : u64 , evicting : bool ) -> bool {
@@ -184,13 +184,10 @@ where
184
184
185
185
let is_over_count = self . max_count != 0 && ( lru_len as u64 ) > self . max_count ;
186
186
187
- if is_over_size || old_item_exists || is_over_count {
188
- return true ;
189
- }
190
- false
187
+ is_over_size || old_item_exists || is_over_count
191
188
}
192
189
193
- async fn evict_items ( & self , state : & mut State < T > ) {
190
+ fn evict_items ( & self , state : & mut State < T > ) {
194
191
let mut peek_entry = if let Some ( ( _, entry) ) = state. lru . peek_lru ( ) {
195
192
entry
196
193
} else {
@@ -201,8 +198,13 @@ where
201
198
evicting = true ;
202
199
let ( key, eviction_item) = state. lru . pop_lru ( ) . expect ( "Tried to peek() then pop() but failed" ) ;
203
200
state. sum_store_size -= eviction_item. data . len ( ) as u64 ;
204
- eviction_item. data . unref ( ) . await ;
205
- log:: info!( "\x1b [0;31mevicting map\x1b [0m: Evicting {:?}" , key) ;
201
+
202
+ // Perform the eviction in a separate greenlet because this function
203
+ // cannot be async otherwise the lock Send trait does not hold.
204
+ tokio:: spawn ( async move {
205
+ eviction_item. data . unref ( ) . await ;
206
+ log:: info!( "\x1b [0;31mevicting map\x1b [0m: Evicting {:?}" , key) ;
207
+ } ) ;
206
208
207
209
peek_entry = if let Some ( ( _, entry) ) = state. lru . peek_lru ( ) {
208
210
entry
@@ -212,28 +214,31 @@ where
212
214
}
213
215
}
214
216
215
- pub async fn size_for_key ( & self , digest : & DigestInfo ) -> Option < usize > {
217
+ async fn get_item_for_key ( & self , digest : & DigestInfo ) -> Option < T > {
216
218
let mut state = self . state . lock ( ) . await ;
217
219
if let Some ( mut entry) = state. lru . get_mut ( digest) {
218
220
entry. seconds_since_anchor = self . anchor_time . elapsed ( ) . as_secs ( ) as i32 ;
219
- let data = entry. data . clone ( ) ;
220
- drop ( state) ;
221
- data. touch ( ) . await ;
222
- return Some ( data. len ( ) ) ;
221
+ Some ( entry. data . clone ( ) )
222
+ } else {
223
+ None
224
+ }
225
+ }
226
+
227
+ pub async fn size_for_key ( & self , digest : & DigestInfo ) -> Option < usize > {
228
+ match self . get ( digest) . await {
229
+ Some ( data) => Some ( data. len ( ) ) ,
230
+ None => None ,
223
231
}
224
- None
225
232
}
226
233
227
234
pub async fn get ( & self , digest : & DigestInfo ) -> Option < T > {
228
- let mut state = self . state . lock ( ) . await ;
229
- if let Some ( mut entry) = state. lru . get_mut ( digest) {
230
- entry. seconds_since_anchor = self . anchor_time . elapsed ( ) . as_secs ( ) as i32 ;
231
- let data = entry. data . clone ( ) ;
232
- drop ( state) ;
233
- data. touch ( ) . await ;
234
- return Some ( data) ;
235
+ match self . get_item_for_key ( digest) . await {
236
+ Some ( data) => {
237
+ data. touch ( ) . await ;
238
+ Some ( data)
239
+ }
240
+ None => None ,
235
241
}
236
- None
237
242
}
238
243
239
244
/// Returns the replaced item if any.
@@ -264,7 +269,7 @@ where
264
269
None
265
270
} ;
266
271
state. sum_store_size += new_item_size;
267
- self . evict_items ( state. deref_mut ( ) ) . await ;
272
+ self . evict_items ( state. deref_mut ( ) ) ;
268
273
maybe_old_item
269
274
}
270
275
0 commit comments