@@ -242,6 +242,42 @@ pub struct Histogram<T: Counter> {
242
242
counts : Vec < T > ,
243
243
}
244
244
245
+ /// Errors that can occur when creating a histogram.
246
+ #[ derive( Debug , Eq , PartialEq , Clone , Copy ) ]
247
+ pub enum CreationError {
248
+ /// Lowest discernible value must be >= 1
249
+ LowTooSmall ,
250
+ /// Lowest discernible value must be <= u64::max_value() / 2
251
+ LowTooBig ,
252
+ /// Highest trackable value must be >= 2 * lowest discernible value
253
+ HighLessThanTwiceLow ,
254
+ /// Number of significant digits must be between 0 and 5
255
+ SigFigTooBig ,
256
+ /// Cannot represent sigfig worth of values beyond low
257
+ CannotRepresentSigFigBeyondLow
258
+ }
259
+
260
+ /// Errors that can occur when adding another histogram.
261
+ #[ derive( Debug , Eq , PartialEq , Clone , Copy ) ]
262
+ pub enum AdditionError {
263
+ /// The other histogram includes values that do not fit in this histogram's range.
264
+ /// Only possible when auto resize is disabled.
265
+ OtherAddendValuesExceedRange
266
+ }
267
+
268
+ /// Errors that can occur when subtracting another histogram.
269
+ #[ derive( Debug , Eq , PartialEq , Clone , Copy ) ]
270
+ pub enum SubtractionError {
271
+ /// The other histogram includes values that do not fit in this histogram's range.
272
+ /// Only possible when auto resize is disabled.
273
+ SubtrahendValuesExceedMinuendRange ,
274
+ /// The other histogram includes counts that are higher than the current count for a value, and
275
+ /// counts cannot go negative. The subtraction may have been partially applied to some counts as
276
+ /// this error is returned when the first impossible subtraction is detected.
277
+ SubtrahendCountExceedsMinuendCount
278
+ }
279
+
280
+
245
281
/// Module containing the implementations of all `Histogram` iterators.
246
282
pub mod iterators;
247
283
@@ -360,7 +396,7 @@ impl<T: Counter> Histogram<T> {
360
396
361
397
/// Overwrite this histogram with the given histogram. All data and statistics in this
362
398
/// histogram will be overwritten.
363
- pub fn set_to < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , & ' static str > {
399
+ pub fn set_to < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , AdditionError > {
364
400
self . reset ( ) ;
365
401
self . add ( source. borrow ( ) )
366
402
}
@@ -384,15 +420,14 @@ impl<T: Counter> Histogram<T> {
384
420
///
385
421
/// May fail if values in the other histogram are higher than `.high()`, and auto-resize is
386
422
/// disabled.
387
- pub fn add < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , & ' static str > {
423
+ pub fn add < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , AdditionError > {
388
424
let source = source. borrow ( ) ;
389
425
390
426
// make sure we can take the values in source
391
427
let top = self . highest_equivalent ( self . value_for ( self . last ( ) ) ) ;
392
428
if top < source. max ( ) {
393
429
if !self . auto_resize {
394
- return Err ( "The other histogram includes values that do not fit in this \
395
- histogram's range.") ;
430
+ return Err ( AdditionError :: OtherAddendValuesExceedRange ) ;
396
431
}
397
432
self . resize ( source. max ( ) ) ;
398
433
}
@@ -484,15 +519,14 @@ impl<T: Counter> Histogram<T> {
484
519
/// disabled. Or, if the count for a given value in the other histogram is higher than that of
485
520
/// this histogram. In the latter case, some of the counts may still have been updated, which
486
521
/// may cause data corruption.
487
- pub fn subtract < B : Borrow < Histogram < T > > > ( & mut self , other : B ) -> Result < ( ) , & ' static str > {
522
+ pub fn subtract < B : Borrow < Histogram < T > > > ( & mut self , other : B ) -> Result < ( ) , SubtractionError > {
488
523
let other = other. borrow ( ) ;
489
524
490
525
// make sure we can take the values in source
491
526
let top = self . highest_equivalent ( self . value_for ( self . last ( ) ) ) ;
492
527
if top < other. max ( ) {
493
528
if !self . auto_resize {
494
- return Err ( "The other histogram includes values that do not fit in this \
495
- histogram's range.") ;
529
+ return Err ( SubtractionError :: SubtrahendValuesExceedMinuendRange ) ;
496
530
}
497
531
self . resize ( other. max ( ) ) ;
498
532
}
@@ -502,8 +536,7 @@ impl<T: Counter> Histogram<T> {
502
536
if other_count != T :: zero ( ) {
503
537
let other_value = other. value_for ( i) ;
504
538
if self . count_at ( other_value) . unwrap ( ) < other_count {
505
- return Err ( "The other histogram includes counts that are higher than the \
506
- current count for that value.") ;
539
+ return Err ( SubtractionError :: SubtrahendCountExceedsMinuendCount ) ;
507
540
}
508
541
self . alter_n ( other_value, other_count, false ) . expect ( "value should fit by now" ) ;
509
542
}
@@ -560,7 +593,7 @@ impl<T: Counter> Histogram<T> {
560
593
/// `sigfig` specifies the number of significant value digits to preserve in the recorded data.
561
594
/// This is the number of significant decimal digits to which the histogram will maintain value
562
595
/// resolution and separation. Must be a non-negative integer between 0 and 5.
563
- pub fn new ( sigfig : u8 ) -> Result < Histogram < T > , & ' static str > {
596
+ pub fn new ( sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
564
597
let mut h = Self :: new_with_bounds ( 1 , 2 , sigfig) ;
565
598
if let Ok ( ref mut h) = h {
566
599
h. auto_resize = true ;
@@ -576,7 +609,7 @@ impl<T: Counter> Histogram<T> {
576
609
/// that is >= 2. `sigfig` specifies the number of significant figures to maintain. This is the
577
610
/// number of significant decimal digits to which the histogram will maintain value resolution
578
611
/// and separation. Must be a non-negative integer between 0 and 5.
579
- pub fn new_with_max ( high : u64 , sigfig : u8 ) -> Result < Histogram < T > , & ' static str > {
612
+ pub fn new_with_max ( high : u64 , sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
580
613
Self :: new_with_bounds ( 1 , high, sigfig)
581
614
}
582
615
@@ -593,20 +626,20 @@ impl<T: Counter> Histogram<T> {
593
626
/// figures to maintain. This is the number of significant decimal digits to which the
594
627
/// histogram will maintain value resolution and separation. Must be a non-negative integer
595
628
/// between 0 and 5.
596
- pub fn new_with_bounds ( low : u64 , high : u64 , sigfig : u8 ) -> Result < Histogram < T > , & ' static str > {
629
+ pub fn new_with_bounds ( low : u64 , high : u64 , sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
597
630
// Verify argument validity
598
631
if low < 1 {
599
- return Err ( "lowest discernible value must be >= 1" ) ;
632
+ return Err ( CreationError :: LowTooSmall ) ;
600
633
}
601
634
if low > u64:: max_value ( ) / 2 {
602
635
// avoid overflow in 2 * low
603
- return Err ( "lowest discernible value must be <= u64::max_value() / 2" )
636
+ return Err ( CreationError :: LowTooBig )
604
637
}
605
638
if high < 2 * low {
606
- return Err ( "highest trackable value must be >= 2 * lowest discernible value" ) ;
639
+ return Err ( CreationError :: HighLessThanTwiceLow ) ;
607
640
}
608
641
if sigfig > 5 {
609
- return Err ( "number of significant digits must be between 0 and 5" ) ;
642
+ return Err ( CreationError :: SigFigTooBig ) ;
610
643
}
611
644
612
645
// Given a 3 decimal point accuracy, the expectation is obviously for "+/- 1 unit at 1000".
@@ -638,7 +671,7 @@ impl<T: Counter> Histogram<T> {
638
671
// histogram vs ones whose magnitude here fits in 63 bits is debatable, and it makes
639
672
// it harder to work through the logic. Sums larger than 64 are totally broken as
640
673
// leading_zero_count_base would go negative.
641
- return Err ( "Cannot represent sigfig worth of values beyond low" ) ;
674
+ return Err ( CreationError :: CannotRepresentSigFigBeyondLow ) ;
642
675
} ;
643
676
644
677
let sub_bucket_half_count = sub_bucket_count / 2 ;
0 commit comments