8
8
use core:: fmt;
9
9
use std:: collections:: hash_map:: Entry ;
10
10
use std:: collections:: HashMap ;
11
- use std:: mem:: replace ;
11
+ use std:: mem:: swap ;
12
12
use std:: ops:: { Add , AddAssign , DerefMut , Sub } ;
13
13
use std:: sync:: atomic:: { AtomicBool , AtomicI64 , AtomicU64 , Ordering } ;
14
14
use std:: sync:: { Arc , Mutex , RwLock } ;
66
66
sorted_attribs : Mutex < HashMap < Vec < KeyValue > , Arc < A > > > ,
67
67
/// Configuration for an Aggregator
68
68
config : A :: InitConfig ,
69
+ /// Swap with `sorted_attribs` on every `collect_and_reset`.
70
+ for_collect_after_reset : Mutex < HashMap < Vec < KeyValue > , Arc < A > > > ,
69
71
}
70
72
71
73
impl < A > ValueMap < A >
78
80
tracker : A :: create ( & config) ,
79
81
is_set : AtomicBool :: new ( false ) ,
80
82
} ,
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 ( ) ) ,
83
85
config,
86
+ for_collect_after_reset : Mutex :: new ( Default :: default ( ) ) ,
84
87
}
85
88
}
86
89
@@ -170,11 +173,14 @@ where
170
173
where
171
174
MapFn : FnMut ( Vec < KeyValue > , A ) -> Res ,
172
175
{
176
+ let mut to_collect = self
177
+ . for_collect_after_reset
178
+ . lock ( )
179
+ . unwrap_or_else ( |err| err. into_inner ( ) ) ;
173
180
// 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 ( ) ) ;
178
184
}
179
185
Err ( _) => return ,
180
186
} ;
@@ -184,7 +190,7 @@ where
184
190
Err ( _) => return ,
185
191
} ;
186
192
187
- prepare_data ( dest, trackers . len ( ) ) ;
193
+ prepare_data ( dest, to_collect . len ( ) ) ;
188
194
189
195
if self . no_attribs . is_set . swap ( false , Ordering :: AcqRel ) {
190
196
dest. push ( map_fn (
@@ -193,7 +199,7 @@ where
193
199
) ) ;
194
200
}
195
201
196
- for ( attrs, tracker) in trackers . into_iter ( ) {
202
+ for ( attrs, tracker) in to_collect . drain ( ) {
197
203
let tracker = Arc :: into_inner ( tracker) . expect ( "the only instance" ) ;
198
204
dest. push ( map_fn ( attrs, tracker) ) ;
199
205
}
0 commit comments