@@ -122,6 +122,30 @@ pub fn exponential_buckets(start: f64, factor: f64, length: u16) -> impl Iterato
122
122
. take ( length. into ( ) )
123
123
}
124
124
125
+ /// Exponential bucket distribution within a range
126
+ ///
127
+ /// Creates `length` buckets, where the lowest bucket is `min` and the highest bucket is `max`.
128
+ ///
129
+ /// If `length` is less than 1, or `min` is less than or equal to 0, an empty iterator is returned.
130
+ pub fn exponential_buckets_range ( min : f64 , max : f64 , length : u16 ) -> impl Iterator < Item = f64 > {
131
+ let mut len_observed = length;
132
+ let mut min_bucket = min;
133
+ // length needs a positive length and min needs to be greater than 0
134
+ // set len_observed to 0 and min_bucket to 1.0
135
+ // this will return an empty iterator in the result
136
+ if length < 1 || min <= 0.0 {
137
+ len_observed = 0 ;
138
+ min_bucket = 1.0 ;
139
+ }
140
+ // We know max/min and highest bucket. Solve for growth_factor.
141
+ let growth_factor = ( max / min_bucket) . powf ( 1.0 / ( len_observed as f64 - 1.0 ) ) ;
142
+
143
+ iter:: repeat ( ( ) )
144
+ . enumerate ( )
145
+ . map ( move |( i, _) | min_bucket * growth_factor. powf ( i as f64 ) )
146
+ . take ( len_observed. into ( ) )
147
+ }
148
+
125
149
/// Linear bucket distribution.
126
150
pub fn linear_buckets ( start : f64 , width : f64 , length : u16 ) -> impl Iterator < Item = f64 > {
127
151
iter:: repeat ( ( ) )
@@ -166,4 +190,21 @@ mod tests {
166
190
linear_buckets( 0.0 , 1.0 , 10 ) . collect:: <Vec <_>>( )
167
191
) ;
168
192
}
193
+
194
+ #[ test]
195
+ fn exponential_range ( ) {
196
+ assert_eq ! (
197
+ vec![ 1.0 , 2.0 , 4.0 , 8.0 , 16.0 , 32.0 ] ,
198
+ exponential_buckets_range( 1.0 , 32.0 , 6 ) . collect:: <Vec <_>>( )
199
+ ) ;
200
+ }
201
+
202
+ #[ test]
203
+ fn exponential_range_incorrect ( ) {
204
+ let res = exponential_buckets_range ( 1.0 , 32.0 , 0 ) . collect :: < Vec < _ > > ( ) ;
205
+ assert ! ( res. is_empty( ) ) ;
206
+
207
+ let res = exponential_buckets_range ( 0.0 , 32.0 , 6 ) . collect :: < Vec < _ > > ( ) ;
208
+ assert ! ( res. is_empty( ) ) ;
209
+ }
169
210
}
0 commit comments