88use core:: fmt;
99use std:: collections:: hash_map:: Entry ;
1010use std:: collections:: HashMap ;
11- use std:: mem:: replace ;
11+ use std:: mem:: swap ;
1212use std:: ops:: { Add , AddAssign , DerefMut , Sub } ;
1313use std:: sync:: atomic:: { AtomicBool , AtomicI64 , AtomicU64 , Ordering } ;
1414use std:: sync:: { Arc , Mutex , RwLock } ;
6666 sorted_attribs : Mutex < HashMap < Vec < KeyValue > , Arc < A > > > ,
6767 /// Configuration for an Aggregator
6868 config : A :: InitConfig ,
69+ /// Swap with `sorted_attribs` on every `collect_and_reset`.
70+ for_collect_after_reset : Mutex < HashMap < Vec < KeyValue > , Arc < A > > > ,
6971}
7072
7173impl < A > ValueMap < A >
7880 tracker : A :: create ( & config) ,
7981 is_set : AtomicBool :: new ( false ) ,
8082 } ,
81- all_attribs : RwLock :: new ( HashMap :: new ( ) ) ,
82- sorted_attribs : Mutex :: new ( HashMap :: new ( ) ) ,
83+ all_attribs : RwLock :: new ( Default :: default ( ) ) ,
84+ sorted_attribs : Mutex :: new ( Default :: default ( ) ) ,
8385 config,
86+ for_collect_after_reset : Mutex :: new ( Default :: default ( ) ) ,
8487 }
8588 }
8689
@@ -170,11 +173,14 @@ where
170173 where
171174 MapFn : FnMut ( Vec < KeyValue > , A ) -> Res ,
172175 {
176+ let mut to_collect = self
177+ . for_collect_after_reset
178+ . lock ( )
179+ . unwrap_or_else ( |err| err. into_inner ( ) ) ;
173180 // reset sorted trackers so new attributes set will be written into new hashmap
174- let trackers = match self . sorted_attribs . lock ( ) {
175- Ok ( mut trackers) => {
176- let new = HashMap :: with_capacity ( trackers. len ( ) ) ;
177- replace ( trackers. deref_mut ( ) , new)
181+ match self . sorted_attribs . lock ( ) {
182+ Ok ( mut trackers) => {
183+ swap ( trackers. deref_mut ( ) , to_collect. deref_mut ( ) ) ;
178184 }
179185 Err ( _) => return ,
180186 } ;
@@ -184,7 +190,7 @@ where
184190 Err ( _) => return ,
185191 } ;
186192
187- prepare_data ( dest, trackers . len ( ) ) ;
193+ prepare_data ( dest, to_collect . len ( ) ) ;
188194
189195 if self . no_attribs . is_set . swap ( false , Ordering :: AcqRel ) {
190196 dest. push ( map_fn (
@@ -193,7 +199,7 @@ where
193199 ) ) ;
194200 }
195201
196- for ( attrs, tracker) in trackers . into_iter ( ) {
202+ for ( attrs, tracker) in to_collect . drain ( ) {
197203 let tracker = Arc :: into_inner ( tracker) . expect ( "the only instance" ) ;
198204 dest. push ( map_fn ( attrs, tracker) ) ;
199205 }
0 commit comments