1
1
use std:: {
2
- collections:: HashMap ,
2
+ collections:: { hash_map :: Entry , HashMap } ,
3
3
sync:: { Arc , Mutex } ,
4
4
time:: SystemTime ,
5
5
} ;
@@ -9,8 +9,9 @@ use crate::metrics::{
9
9
aggregation,
10
10
data:: { self , Aggregation } ,
11
11
} ;
12
+ use opentelemetry_api:: { global, metrics:: MetricsError } ;
12
13
13
- use super :: { Aggregator , Number } ;
14
+ use super :: { aggregator :: STREAM_OVERFLOW_ATTRIBUTE_SET , Aggregator , Number } ;
14
15
15
16
#[ derive( Default ) ]
16
17
struct Buckets < T > {
@@ -78,22 +79,38 @@ where
78
79
Ok ( guard) => guard,
79
80
Err ( _) => return ,
80
81
} ;
81
-
82
- let b = values. entry ( attrs) . or_insert_with ( || {
83
- // N+1 buckets. For example:
84
- //
85
- // bounds = [0, 5, 10]
86
- //
87
- // Then,
88
- //
89
- // buckets = (-∞, 0], (0, 5.0], (5.0, 10.0], (10.0, +∞)
90
- let mut b = Buckets :: new ( self . bounds . len ( ) + 1 ) ;
91
- // Ensure min and max are recorded values (not zero), for new buckets.
92
- ( b. min , b. max ) = ( measurement, measurement) ;
93
-
94
- b
95
- } ) ;
96
- b. bin ( idx, measurement)
82
+ let size = values. len ( ) ;
83
+
84
+ match values. entry ( attrs) {
85
+ Entry :: Occupied ( mut occupied_entry) => occupied_entry. get_mut ( ) . bin ( idx, measurement) ,
86
+ Entry :: Vacant ( vacant_entry) => {
87
+ if self . is_under_cardinality_limit ( size) {
88
+ // N+1 buckets. For example:
89
+ //
90
+ // bounds = [0, 5, 10]
91
+ //
92
+ // Then,
93
+ //
94
+ // buckets = (-∞, 0], (0, 5.0], (5.0, 10.0], (10.0, +∞)
95
+ let mut b = Buckets :: new ( self . bounds . len ( ) + 1 ) ;
96
+ // Ensure min and max are recorded values (not zero), for new buckets.
97
+ ( b. min , b. max ) = ( measurement, measurement) ;
98
+ b. bin ( idx, measurement) ;
99
+ vacant_entry. insert ( b) ;
100
+ } else {
101
+ values
102
+ . entry ( STREAM_OVERFLOW_ATTRIBUTE_SET . clone ( ) )
103
+ . and_modify ( |val| val. bin ( idx, measurement) )
104
+ . or_insert_with ( || {
105
+ let mut b = Buckets :: new ( self . bounds . len ( ) + 1 ) ;
106
+ ( b. min , b. max ) = ( measurement, measurement) ;
107
+ b. bin ( idx, measurement) ;
108
+ b
109
+ } ) ;
110
+ global:: handle_error ( MetricsError :: Other ( "Warning: Maximum data points for metric stream exceeded. Entry added to overflow." . into ( ) ) ) ;
111
+ }
112
+ }
113
+ }
97
114
}
98
115
99
116
fn aggregation ( & self ) -> Option < Box < dyn Aggregation > > {
0 commit comments