11use std:: collections:: hash_map:: Iter ;
22use std:: collections:: { HashMap , HashSet } ;
3+ use std:: fmt:: Write as _;
34
45use serde:: { de, Deserialize , Deserializer , Serialize , Serializer } ;
56use torrust_tracker_primitives:: DurationSinceUnixEpoch ;
@@ -9,28 +10,26 @@ use super::gauge::Gauge;
910use super :: label:: LabelSet ;
1011use super :: prometheus:: PrometheusSerializable ;
1112use super :: sample:: Sample ;
13+ use crate :: sample:: Measurement ;
1214
1315#[ derive( Debug , Clone , Default , PartialEq ) ]
1416pub struct SampleCollection < T > {
15- samples : HashMap < LabelSet , Sample < T > > ,
17+ samples : HashMap < LabelSet , Measurement < T > > ,
1618}
1719
1820impl < T > SampleCollection < T > {
19- // IMPORTANT: It should never allow mutation of the samples because it would
20- // break the invariants. If the sample's `LabelSet` is changed, it can
21- // create duplicate `LabelSet`s even if the `LabelSet` in the `HashMap` key
22- // is unique.
23-
2421 /// # Panics
2522 ///
2623 /// Panics if there are duplicate `LabelSets` in the provided samples.
2724 #[ must_use]
2825 pub fn new ( samples : Vec < Sample < T > > ) -> Self {
29- let mut map = HashMap :: with_capacity ( samples. len ( ) ) ;
26+ let mut map: HashMap < LabelSet , Measurement < T > > = HashMap :: with_capacity ( samples. len ( ) ) ;
3027
3128 for sample in samples {
29+ let ( label_set, sample_data) : ( LabelSet , Measurement < T > ) = sample. into ( ) ;
30+
3231 assert ! (
33- map. insert( sample . labels ( ) . clone ( ) , sample ) . is_none( ) ,
32+ map. insert( label_set , sample_data ) . is_none( ) ,
3433 "Duplicate LabelSet found in SampleCollection"
3534 ) ;
3635 }
@@ -39,7 +38,7 @@ impl<T> SampleCollection<T> {
3938 }
4039
4140 #[ must_use]
42- pub fn get ( & self , label : & LabelSet ) -> Option < & Sample < T > > {
41+ pub fn get ( & self , label : & LabelSet ) -> Option < & Measurement < T > > {
4342 self . samples . get ( label)
4443 }
4544
@@ -55,7 +54,7 @@ impl<T> SampleCollection<T> {
5554
5655 #[ must_use]
5756 #[ allow( clippy:: iter_without_into_iter) ]
58- pub fn iter ( & self ) -> Iter < ' _ , LabelSet , Sample < T > > {
57+ pub fn iter ( & self ) -> Iter < ' _ , LabelSet , Measurement < T > > {
5958 self . samples . iter ( )
6059 }
6160}
@@ -65,7 +64,7 @@ impl SampleCollection<Counter> {
6564 let sample = self
6665 . samples
6766 . entry ( label_set. clone ( ) )
68- . or_insert_with ( || Sample :: new ( Counter :: default ( ) , time, label_set . clone ( ) ) ) ;
67+ . or_insert_with ( || Measurement :: new ( Counter :: default ( ) , time) ) ;
6968
7069 sample. increment ( time) ;
7170 }
@@ -76,7 +75,7 @@ impl SampleCollection<Gauge> {
7675 let sample = self
7776 . samples
7877 . entry ( label_set. clone ( ) )
79- . or_insert_with ( || Sample :: new ( Gauge :: default ( ) , time, label_set . clone ( ) ) ) ;
78+ . or_insert_with ( || Measurement :: new ( Gauge :: default ( ) , time) ) ;
8079
8180 sample. set ( value, time) ;
8281 }
@@ -87,7 +86,12 @@ impl<T: Serialize> Serialize for SampleCollection<T> {
8786 where
8887 S : Serializer ,
8988 {
90- let samples: Vec < & Sample < T > > = self . samples . values ( ) . collect ( ) ;
89+ let mut samples: Vec < Sample < & T > > = vec ! [ ] ;
90+
91+ for ( label_set, sample_data) in & self . samples {
92+ samples. push ( Sample :: new ( sample_data. value ( ) , sample_data. update_at ( ) , label_set. clone ( ) ) ) ;
93+ }
94+
9195 samples. serialize ( serializer)
9296 }
9397}
@@ -121,8 +125,8 @@ impl<T: PrometheusSerializable> PrometheusSerializable for SampleCollection<T> {
121125 fn to_prometheus ( & self ) -> String {
122126 let mut output = String :: new ( ) ;
123127
124- for sample in self . samples . values ( ) {
125- output. push_str ( & sample . to_prometheus ( ) ) ;
128+ for ( label_set , sample_data ) in & self . samples {
129+ let _ = write ! ( output, "{} {}" , label_set . to_prometheus ( ) , sample_data . to_prometheus( ) ) ;
126130 }
127131
128132 output
@@ -165,7 +169,7 @@ mod tests {
165169
166170 let retrieved = collection. get ( & label_set) ;
167171
168- assert_eq ! ( retrieved. unwrap( ) , & sample) ;
172+ assert_eq ! ( retrieved. unwrap( ) , sample. measurement ( ) ) ;
169173 }
170174
171175 #[ test]
@@ -179,10 +183,10 @@ mod tests {
179183 let collection = SampleCollection :: new ( vec ! [ sample_1. clone( ) , sample_2. clone( ) ] ) ;
180184
181185 let retrieved = collection. get ( & label_set_1) ;
182- assert_eq ! ( retrieved. unwrap( ) , & sample_1) ;
186+ assert_eq ! ( retrieved. unwrap( ) , sample_1. measurement ( ) ) ;
183187
184188 let retrieved = collection. get ( & label_set_2) ;
185- assert_eq ! ( retrieved. unwrap( ) , & sample_2) ;
189+ assert_eq ! ( retrieved. unwrap( ) , sample_2. measurement ( ) ) ;
186190 }
187191
188192 #[ test]
0 commit comments