@@ -80,6 +80,34 @@ fn coalesce_batch_keys(keys: &[CacheKey]) -> (Vec<CacheKey>, Vec<(usize, usize)>
8080 ( unique_keys, requested_positions)
8181}
8282
83+ fn coalesce_batch_positions ( keys : & [ CacheKey ] ) -> Vec < ( CacheKey , Vec < usize > ) > {
84+ let mut positions_by_key = Vec :: < ( CacheKey , Vec < usize > ) > :: new ( ) ;
85+ if keys. len ( ) <= SMALL_BATCH_DEDUP_LIMIT {
86+ for ( position, key) in keys. iter ( ) . enumerate ( ) {
87+ if let Some ( ( _, positions) ) = positions_by_key
88+ . iter_mut ( )
89+ . find ( |( existing, _) | existing == key)
90+ {
91+ positions. push ( position) ;
92+ } else {
93+ positions_by_key. push ( ( key. clone ( ) , vec ! [ position] ) ) ;
94+ }
95+ }
96+ return positions_by_key;
97+ }
98+
99+ let mut unique_positions = HashMap :: < CacheKey , usize > :: new ( ) ;
100+ for ( position, key) in keys. iter ( ) . cloned ( ) . enumerate ( ) {
101+ if let Some ( unique_position) = unique_positions. get ( & key) . copied ( ) {
102+ positions_by_key[ unique_position] . 1 . push ( position) ;
103+ } else {
104+ unique_positions. insert ( key. clone ( ) , positions_by_key. len ( ) ) ;
105+ positions_by_key. push ( ( key, vec ! [ position] ) ) ;
106+ }
107+ }
108+ positions_by_key
109+ }
110+
83111/// The byte-valued cache interface, implemented by every cache in this crate.
84112///
85113/// Implemented by [`MultiLayerCache`], [`ShardedMultiLayerCache`],
@@ -3241,16 +3269,7 @@ impl MultiLayerCache {
32413269 return Ok ( results) ;
32423270 }
32433271
3244- let mut positions_by_key = Vec :: < ( CacheKey , Vec < usize > ) > :: new ( ) ;
3245- let mut unique_positions = HashMap :: < CacheKey , usize > :: new ( ) ;
3246- for ( position, key) in keys. iter ( ) . cloned ( ) . enumerate ( ) {
3247- if let Some ( unique_position) = unique_positions. get ( & key) . copied ( ) {
3248- positions_by_key[ unique_position] . 1 . push ( position) ;
3249- } else {
3250- unique_positions. insert ( key. clone ( ) , positions_by_key. len ( ) ) ;
3251- positions_by_key. push ( ( key, vec ! [ position] ) ) ;
3252- }
3253- }
3272+ let positions_by_key = coalesce_batch_positions ( keys) ;
32543273
32553274 let now_millis = CoarseClock :: now_millis ( ) ;
32563275 let mut expired_keys = Vec :: new ( ) ;
@@ -3388,16 +3407,7 @@ impl MultiLayerCache {
33883407 return Ok ( results) ;
33893408 }
33903409
3391- let mut positions_by_key = Vec :: < ( CacheKey , Vec < usize > ) > :: new ( ) ;
3392- let mut unique_positions = HashMap :: < CacheKey , usize > :: new ( ) ;
3393- for ( position, key) in keys. iter ( ) . cloned ( ) . enumerate ( ) {
3394- if let Some ( unique_position) = unique_positions. get ( & key) . copied ( ) {
3395- positions_by_key[ unique_position] . 1 . push ( position) ;
3396- } else {
3397- unique_positions. insert ( key. clone ( ) , positions_by_key. len ( ) ) ;
3398- positions_by_key. push ( ( key, vec ! [ position] ) ) ;
3399- }
3400- }
3410+ let positions_by_key = coalesce_batch_positions ( keys) ;
34013411
34023412 let mut remaining = Vec :: < ( CacheKey , Vec < usize > ) > :: new ( ) ;
34033413 let mut exclusive_work = Vec :: < ( CacheKey , HitOutcome , usize ) > :: new ( ) ;
0 commit comments