@@ -7,6 +7,7 @@ use super::counter::Counter;
77use super :: gauge:: Gauge ;
88use super :: label_set:: LabelSet ;
99use super :: metric:: Metric ;
10+ use super :: sample:: Sample ;
1011use super :: MetricName ;
1112use crate :: metrics:: sample_collection:: SampleCollection ;
1213use crate :: DurationSinceUnixEpoch ;
@@ -182,13 +183,30 @@ impl<T> MetricKindCollection<T> {
182183}
183184
184185impl MetricKindCollection < Counter > {
186+ /// # Panics
187+ ///
188+ /// Panics if the metric name already exists in the collection.
185189 pub fn increment ( & mut self , name : & MetricName , labels : & LabelSet , time : DurationSinceUnixEpoch ) {
186- if let Some ( metric) = self . metrics . get_mut ( name) {
187- if let Some ( sample) = metric. samples . get_mut ( labels) {
188- sample. value . increment ( 1 ) ;
189- sample. update_at = time;
190- }
190+ // Create the metric if it doesn't exist
191+ if !self . metrics . contains_key ( name) {
192+ let new_metric = Metric {
193+ name : name. clone ( ) ,
194+ samples : SampleCollection { samples : HashMap :: new ( ) } ,
195+ } ;
196+ self . metrics . insert ( name. clone ( ) , new_metric) ;
191197 }
198+
199+ let metric = self . metrics . get_mut ( name) . unwrap ( ) ;
200+
201+ // Use entry API to handle existing or new sample
202+ let sample = metric. samples . samples . entry ( labels. clone ( ) ) . or_insert_with ( || Sample {
203+ value : Counter :: new ( 0 ) ,
204+ update_at : time,
205+ labels : labels. clone ( ) ,
206+ } ) ;
207+
208+ sample. value . increment ( 1 ) ;
209+ sample. update_at = time;
192210 }
193211
194212 #[ must_use]
@@ -201,13 +219,35 @@ impl MetricKindCollection<Counter> {
201219}
202220
203221impl MetricKindCollection < Gauge > {
222+ /// # Panics
223+ ///
224+ /// Panics if the metric name already exists in the collection.
204225 pub fn set ( & mut self , name : & MetricName , labels : & LabelSet , value : f64 , time : DurationSinceUnixEpoch ) {
205- if let Some ( metric) = self . metrics . get_mut ( name) {
206- // Direct hashmap lookup
207- if let Some ( sample) = metric. samples . get_mut ( labels) {
226+ // Create the metric if it doesn't exist
227+ if !self . metrics . contains_key ( name) {
228+ let new_metric = Metric {
229+ name : name. clone ( ) ,
230+ samples : SampleCollection { samples : HashMap :: new ( ) } ,
231+ } ;
232+ self . metrics . insert ( name. clone ( ) , new_metric) ;
233+ }
234+
235+ let metric = self . metrics . get_mut ( name) . unwrap ( ) ;
236+
237+ // Use entry API to handle existing or new sample
238+ match metric. samples . samples . entry ( labels. clone ( ) ) {
239+ std:: collections:: hash_map:: Entry :: Occupied ( mut entry) => {
240+ let sample = entry. get_mut ( ) ;
208241 sample. value . set ( value) ;
209242 sample. update_at = time;
210243 }
244+ std:: collections:: hash_map:: Entry :: Vacant ( entry) => {
245+ entry. insert ( Sample {
246+ value : Gauge :: new ( value) ,
247+ update_at : time,
248+ labels : labels. clone ( ) ,
249+ } ) ;
250+ }
211251 }
212252 }
213253
0 commit comments