@@ -243,15 +243,25 @@ pub struct Histogram<T: Counter> {
243
243
/// Errors that can occur when creating a histogram.
244
244
#[ derive( Debug , Eq , PartialEq , Clone , Copy ) ]
245
245
pub enum CreationError {
246
- /// Lowest discernible value must be >= 1
247
- LowTooSmall ,
248
- /// Lowest discernible value must be <= u64::max_value() / 2
249
- LowTooBig ,
250
- /// Highest trackable value must be >= 2 * lowest discernible value
246
+ /// Lowest discernible value must be >= 1.
247
+ LowIsZero ,
248
+ /// Lowest discernible value must be <= `u64::max_value() / 2` because the highest value is
249
+ /// a `u64` and the lowest value must be no bigger than half the highest.
250
+ LowExceedsMax ,
251
+ /// Highest trackable value must be >= 2 * lowest discernible value for some internal
252
+ /// calculations to work out. In practice, high is typically much higher than 2 * low.
251
253
HighLessThanTwiceLow ,
252
- /// Number of significant digits must be between 0 and 5
253
- SigFigTooBig ,
254
- /// Cannot represent sigfig worth of values beyond low
254
+ /// Number of significant digits must be in the range `[0, 5]`. It is capped at 5 because 5
255
+ /// significant digits is already more than almost anyone needs, and memory usage scales
256
+ /// exponentially as this increases.
257
+ SigFigExceedsMax ,
258
+ /// Cannot represent sigfig worth of values beyond the lowest discernible value. Decrease the
259
+ /// significant figures, lowest discernible value, or both.
260
+ ///
261
+ /// This could happen if low is very large (like 2^60) and sigfigs is 5, which requires 18
262
+ /// additional bits, which would then require more bits than will fit in a u64. Specifically,
263
+ /// the exponent of the largest power of two that is smaller than the lowest value and the bits
264
+ /// needed to represent the requested significant figures must sum to 63 or less.
255
265
CannotRepresentSigFigBeyondLow
256
266
}
257
267
@@ -586,9 +596,9 @@ impl<T: Counter> Histogram<T> {
586
596
/// auto-adjusting highest trackable value. Can auto-resize up to track values up to
587
597
/// `(i64::max_value() / 2)`.
588
598
///
589
- /// `sigfig` specifies the number of significant value digits to preserve in the recorded data .
590
- /// This is the number of significant decimal digits to which the histogram will maintain value
591
- /// resolution and separation. Must be a non-negative integer between 0 and 5.
599
+ /// See [`new_with_bounds`] for info on `sigfig` .
600
+ ///
601
+ /// [`new_with_bounds`]: #method.new_with_bounds
592
602
pub fn new ( sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
593
603
let mut h = Self :: new_with_bounds ( 1 , 2 , sigfig) ;
594
604
if let Ok ( ref mut h) = h {
@@ -601,41 +611,45 @@ impl<T: Counter> Histogram<T> {
601
611
/// significant decimal digits. The histogram will be constructed to implicitly track
602
612
/// (distinguish from 0) values as low as 1. Auto-resizing will be disabled.
603
613
///
604
- /// `high` is the highest value to be tracked by the histogram, and must be a positive integer
605
- /// that is >= 2. `sigfig` specifies the number of significant figures to maintain. This is the
606
- /// number of significant decimal digits to which the histogram will maintain value resolution
607
- /// and separation. Must be a non-negative integer between 0 and 5.
614
+ /// See [`new_with_bounds`] for info on `high` and `sigfig`.
615
+ ///
616
+ /// [`new_with_bounds`]: #method.new_with_bounds
608
617
pub fn new_with_max ( high : u64 , sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
609
618
Self :: new_with_bounds ( 1 , high, sigfig)
610
619
}
611
620
612
621
/// Construct a `Histogram` with known upper and lower bounds for recorded sample values.
613
- /// Providing a lowest discernible value (`low`) is useful is situations where the units used
614
- /// for the histogram's values are much smaller that the minimal accuracy required. E.g. when
615
- /// tracking time values stated in nanosecond units, where the minimal accuracy required is a
616
- /// microsecond, the proper value for `low` would be 1000.
617
622
///
618
623
/// `low` is the lowest value that can be discerned (distinguished from 0) by the histogram,
619
624
/// and must be a positive integer that is >= 1. It may be internally rounded down to nearest
620
- /// power of 2. `high` is the highest value to be tracked by the histogram, and must be a
621
- /// positive integer that is `>= (2 * low)`. `sigfig` Specifies the number of significant
622
- /// figures to maintain. This is the number of significant decimal digits to which the
623
- /// histogram will maintain value resolution and separation. Must be a non-negative integer
624
- /// between 0 and 5.
625
+ /// power of 2. Providing a lowest discernible value (`low`) is useful is situations where the
626
+ /// units used for the histogram's values are much smaller that the minimal accuracy required.
627
+ /// E.g. when tracking time values stated in nanosecond units, where the minimal accuracy
628
+ /// required is a microsecond, the proper value for `low` would be 1000. If you're not sure,
629
+ /// use 1.
630
+ ///
631
+ /// `high` is the highest value to be tracked by the histogram, and must be a
632
+ /// positive integer that is `>= (2 * low)`. If you're not sure, use `u64::max_value()`.
633
+ ///
634
+ /// `sigfig` Specifies the number of significant figures to maintain. This is the number of
635
+ /// significant decimal digits to which the histogram will maintain value resolution and
636
+ /// separation. Must be in the range [0, 5]. If you're not sure, use 3. As `sigfig` increases,
637
+ /// memory usage grows exponentially, so choose carefully if there will be many histograms in
638
+ /// memory at once or if storage is otherwise a concern.
625
639
pub fn new_with_bounds ( low : u64 , high : u64 , sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
626
640
// Verify argument validity
627
641
if low < 1 {
628
- return Err ( CreationError :: LowTooSmall ) ;
642
+ return Err ( CreationError :: LowIsZero ) ;
629
643
}
630
644
if low > u64:: max_value ( ) / 2 {
631
645
// avoid overflow in 2 * low
632
- return Err ( CreationError :: LowTooBig )
646
+ return Err ( CreationError :: LowExceedsMax )
633
647
}
634
648
if high < 2 * low {
635
649
return Err ( CreationError :: HighLessThanTwiceLow ) ;
636
650
}
637
651
if sigfig > 5 {
638
- return Err ( CreationError :: SigFigTooBig ) ;
652
+ return Err ( CreationError :: SigFigExceedsMax ) ;
639
653
}
640
654
641
655
// Given a 3 decimal point accuracy, the expectation is obviously for "+/- 1 unit at 1000".
0 commit comments