@@ -14,8 +14,11 @@ use chrono::Utc;
1414use futures:: StreamExt ;
1515use futures:: future:: join_all;
1616use futures:: stream:: FuturesUnordered ;
17+ use tokio:: sync:: oneshot:: error:: RecvError ;
18+
1719use std:: sync:: Arc ;
1820use std:: sync:: atomic:: AtomicU64 ;
21+
1922use std:: { hash:: Hasher , iter:: Zip } ;
2023use tokio:: sync:: oneshot:: Sender ;
2124use tokio:: task:: JoinHandle ;
@@ -169,27 +172,43 @@ impl CacheManager {
169172 }
170173
171174 pub ( crate ) async fn route_delete ( & self , keys : Vec < String > ) -> Result < u64 > {
175+ let closure = |key, callback| -> CacheCommand { CacheCommand :: Delete { key, callback } } ;
172176 // Create futures for all delete operations at once
173- let results = FuturesUnordered :: from_iter ( keys. into_iter ( ) . map ( |key| {
174- let ( tx, rx) = tokio:: sync:: oneshot:: channel ( ) ;
175- async move {
176- let _ =
177- self . select_shard ( & key) . send ( CacheCommand :: Delete { key, callback : tx } ) . await ;
178- rx. await
179- }
180- } ) )
181- . collect :: < Vec < _ > > ( )
182- . await ;
177+ let results = self . send_selectively ( keys, closure) . await ;
183178
184179 let deleted = results. into_iter ( ) . filter_map ( |r| r. ok ( ) . filter ( |& success| success) ) . count ( ) ;
185-
186180 Ok ( deleted as u64 )
187181 }
182+ pub ( crate ) async fn route_exists ( & self , keys : Vec < String > ) -> Result < u64 > {
183+ let closure = |key, callback| -> CacheCommand { CacheCommand :: Exists { key, callback } } ;
184+ // Create futures for all delete operations at once
185+ let results = self . send_selectively ( keys, closure) . await ;
186+
187+ let found = results. into_iter ( ) . filter_map ( |r| r. ok ( ) . filter ( |& success| success) ) . count ( ) ;
188+ Ok ( found as u64 )
189+ }
190+
188191 pub ( crate ) fn select_shard ( & self , key : & str ) -> & CacheCommandSender {
189192 let shard_key = self . take_shard_key_from_str ( key) ;
190193 & self . inboxes [ shard_key]
191194 }
192195
196+ async fn send_selectively < T > (
197+ & self ,
198+ keys : Vec < String > ,
199+ func : fn ( String , Sender < T > ) -> CacheCommand ,
200+ ) -> Vec < Result < T , RecvError > > {
201+ FuturesUnordered :: from_iter ( keys. into_iter ( ) . map ( |key| {
202+ let ( tx, rx) = tokio:: sync:: oneshot:: channel ( ) ;
203+ async move {
204+ let _ = self . select_shard ( & key) . send ( func ( key, tx) ) . await ;
205+ rx. await
206+ }
207+ } ) )
208+ . collect :: < Vec < _ > > ( )
209+ . await
210+ }
211+
193212 fn take_shard_key_from_str ( & self , s : & str ) -> usize {
194213 let mut hasher = std:: hash:: DefaultHasher :: new ( ) ;
195214 std:: hash:: Hash :: hash ( & s, & mut hasher) ;
0 commit comments