@@ -383,49 +383,51 @@ where
383383 // to be able to borrow a `Q`.
384384 R : Borrow < Q > + Send ,
385385 {
386- let mut state = self . state . lock ( ) ;
386+ let ( mut callbacks, data_to_unref) = {
387+ let mut state = self . state . lock ( ) ;
387388
388- let lru_len = state. lru . len ( ) ;
389- let mut data_to_unref = Vec :: new ( ) ;
390- let mut removal_futures = Vec :: new ( ) ;
391- for ( key, result) in keys. into_iter ( ) . zip ( results. iter_mut ( ) ) {
392- let maybe_entry = if peek {
393- state. lru . peek_mut ( key. borrow ( ) )
394- } else {
395- state. lru . get_mut ( key. borrow ( ) )
396- } ;
397- match maybe_entry {
398- Some ( entry) => {
399- // Note: We need to check eviction because the item might be expired
400- // based on the current time. In such case, we remove the item while
401- // we are here.
402- if self . should_evict ( lru_len, entry, 0 , u64:: MAX ) {
403- * result = None ;
404- if let Some ( ( key, eviction_item) ) = state. lru . pop_entry ( key. borrow ( ) ) {
405- info ! ( ?key, "Item expired, evicting" ) ;
406- let ( data, futures) = state. remove ( key. borrow ( ) , & eviction_item, false ) ;
407- // Store data for later unref - we can't drop state here as we're still iterating
408- data_to_unref. push ( data) ;
409- removal_futures. extend ( futures. into_iter ( ) ) ;
389+ let lru_len = state. lru . len ( ) ;
390+ let mut data_to_unref = Vec :: new ( ) ;
391+ let mut removal_futures = Vec :: new ( ) ;
392+ for ( key, result) in keys. into_iter ( ) . zip ( results. iter_mut ( ) ) {
393+ let maybe_entry = if peek {
394+ state. lru . peek_mut ( key. borrow ( ) )
395+ } else {
396+ state. lru . get_mut ( key. borrow ( ) )
397+ } ;
398+ match maybe_entry {
399+ Some ( entry) => {
400+ // Note: We need to check eviction because the item might be expired
401+ // based on the current time. In such case, we remove the item while
402+ // we are here.
403+ if self . should_evict ( lru_len, entry, 0 , u64:: MAX ) {
404+ * result = None ;
405+ if let Some ( ( key, eviction_item) ) = state. lru . pop_entry ( key. borrow ( ) ) {
406+ info ! ( ?key, "Item expired, evicting" ) ;
407+ let ( data, futures) =
408+ state. remove ( key. borrow ( ) , & eviction_item, false ) ;
409+ // Store data for later unref - we can't drop state here as we're still iterating
410+ data_to_unref. push ( data) ;
411+ removal_futures. extend ( futures. into_iter ( ) ) ;
412+ }
413+ } else {
414+ if !peek {
415+ entry. seconds_since_anchor =
416+ self . anchor_time . elapsed ( ) . as_secs ( ) as i32 ;
417+ }
418+ * result = Some ( entry. data . len ( ) ) ;
410419 }
411- } else {
412- if !peek {
413- entry. seconds_since_anchor =
414- self . anchor_time . elapsed ( ) . as_secs ( ) as i32 ;
415- }
416- * result = Some ( entry. data . len ( ) ) ;
417420 }
421+ None => * result = None ,
418422 }
419- None => * result = None ,
420423 }
421- }
424+ let callbacks: FuturesUnordered < _ > = removal_futures. into_iter ( ) . collect ( ) ;
425+ ( callbacks, data_to_unref)
426+ } ;
422427
423- // Drop the state and perform the async callbacks.
424- drop ( state) ;
425- let mut callbacks: FuturesUnordered < _ > = removal_futures. into_iter ( ) . collect ( ) ;
426428 while callbacks. next ( ) . await . is_some ( ) { }
427429 let mut callbacks: FuturesUnordered < _ > =
428- data_to_unref. iter ( ) . map ( |item| item . unref ( ) ) . collect ( ) ;
430+ data_to_unref. iter ( ) . map ( LenEntry :: unref) . collect ( ) ;
429431 while callbacks. next ( ) . await . is_some ( ) { }
430432 }
431433
@@ -455,7 +457,7 @@ where
455457 let mut callbacks: FuturesUnordered < _ > = removal_futures. into_iter ( ) . collect ( ) ;
456458 while callbacks. next ( ) . await . is_some ( ) { }
457459 let mut callbacks: FuturesUnordered < _ > =
458- items_to_unref. iter ( ) . map ( |item| item . unref ( ) ) . collect ( ) ;
460+ items_to_unref. iter ( ) . map ( LenEntry :: unref) . collect ( ) ;
459461 while callbacks. next ( ) . await . is_some ( ) { }
460462 }
461463
@@ -567,11 +569,11 @@ where
567569
568570 // Perform eviction after all insertions
569571 let ( items_to_unref, futures) = self . evict_items ( state) ;
570- removal_futures. extend ( futures. into_iter ( ) ) ;
572+ removal_futures. extend ( futures) ;
571573
572574 // Note: We cannot drop the state lock here since we're borrowing it,
573575 // but the caller will handle unreffing these items after releasing the lock
574- replaced_items. extend ( items_to_unref. into_iter ( ) ) ;
576+ replaced_items. extend ( items_to_unref) ;
575577
576578 ( replaced_items, removal_futures)
577579 }
@@ -600,7 +602,7 @@ where
600602
601603 // Unref evicted items outside of lock
602604 let mut callbacks: FuturesUnordered < _ > =
603- items_to_unref. iter ( ) . map ( |item| item . unref ( ) ) . collect ( ) ;
605+ items_to_unref. iter ( ) . map ( LenEntry :: unref) . collect ( ) ;
604606 while callbacks. next ( ) . await . is_some ( ) { }
605607
606608 // Unref removed item if any
@@ -618,41 +620,44 @@ where
618620 where
619621 F : FnOnce ( & T ) -> bool + Send ,
620622 {
621- let mut state = self . state . lock ( ) ;
622- if let Some ( entry) = state. lru . get ( key. borrow ( ) ) {
623- if !cond ( & entry. data ) {
624- return false ;
625- }
626- // First perform eviction
627- let ( evicted_items, mut removal_futures) = self . evict_items ( & mut state) ;
628-
629- // Then try to remove the requested item
630- let removed_item = if let Some ( entry) = state. lru . pop ( key. borrow ( ) ) {
631- let ( item, more_removal_futures) = state. remove ( key, & entry, false ) ;
632- removal_futures. extend ( more_removal_futures. into_iter ( ) ) ;
633- Some ( item)
623+ let ( evicted_items, mut removal_futures, removed_item) = {
624+ let mut state = self . state . lock ( ) ;
625+ if let Some ( entry) = state. lru . get ( key. borrow ( ) ) {
626+ if !cond ( & entry. data ) {
627+ return false ;
628+ }
629+ // First perform eviction
630+ let ( evicted_items, mut removal_futures) = self . evict_items ( & mut state) ;
631+
632+ // Then try to remove the requested item
633+ let removed_item = if let Some ( entry) = state. lru . pop ( key. borrow ( ) ) {
634+ let ( item, more_removal_futures) = state. remove ( key, & entry, false ) ;
635+ removal_futures. extend ( more_removal_futures. into_iter ( ) ) ;
636+ Some ( item)
637+ } else {
638+ None
639+ } ;
640+
641+ let removal_futures: FuturesUnordered < Pin < Box < dyn Future < Output = ( ) > + Send > > > =
642+ removal_futures. into_iter ( ) . collect ( ) ;
643+
644+ ( evicted_items, removal_futures, removed_item)
634645 } else {
635- None
636- } ;
637-
638- // Drop the lock before unref operations
639- drop ( state) ;
646+ ( vec ! [ ] , vec ! [ ] . into_iter ( ) . collect ( ) , None )
647+ }
648+ } ;
640649
641- let mut removal_futures: FuturesUnordered < _ > = removal_futures. into_iter ( ) . collect ( ) ;
642- while removal_futures. next ( ) . await . is_some ( ) { }
650+ while removal_futures. next ( ) . await . is_some ( ) { }
643651
644- // Unref evicted items
645- let mut callbacks: FuturesUnordered < _ > =
646- evicted_items. iter ( ) . map ( |item| item . unref ( ) ) . collect ( ) ;
647- while callbacks. next ( ) . await . is_some ( ) { }
652+ // Unref evicted items
653+ let mut callbacks: FuturesUnordered < _ > =
654+ evicted_items. iter ( ) . map ( LenEntry :: unref) . collect ( ) ;
655+ while callbacks. next ( ) . await . is_some ( ) { }
648656
649- // Unref removed item if any
650- if let Some ( item) = removed_item {
651- item. unref ( ) . await ;
652- true
653- } else {
654- false
655- }
657+ // Unref removed item if any
658+ if let Some ( item) = removed_item {
659+ item. unref ( ) . await ;
660+ true
656661 } else {
657662 false
658663 }
0 commit comments