@@ -240,6 +240,42 @@ pub struct Histogram<T: Counter> {
240
240
counts : Vec < T > ,
241
241
}
242
242
243
+ /// Errors that can occur when creating a histogram.
244
+ #[ derive( Debug , Eq , PartialEq , Clone , Copy ) ]
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
251
+ HighLessThanTwiceLow ,
252
+ /// Number of significant digits must be between 0 and 5
253
+ SigFigTooBig ,
254
+ /// Cannot represent sigfig worth of values beyond low
255
+ CannotRepresentSigFigBeyondLow
256
+ }
257
+
258
+ /// Errors that can occur when adding another histogram.
259
+ #[ derive( Debug , Eq , PartialEq , Clone , Copy ) ]
260
+ pub enum AdditionError {
261
+ /// The other histogram includes values that do not fit in this histogram's range.
262
+ /// Only possible when auto resize is disabled.
263
+ OtherAddendValuesExceedRange
264
+ }
265
+
266
+ /// Errors that can occur when subtracting another histogram.
267
+ #[ derive( Debug , Eq , PartialEq , Clone , Copy ) ]
268
+ pub enum SubtractionError {
269
+ /// The other histogram includes values that do not fit in this histogram's range.
270
+ /// Only possible when auto resize is disabled.
271
+ SubtrahendValuesExceedMinuendRange ,
272
+ /// The other histogram includes counts that are higher than the current count for a value, and
273
+ /// counts cannot go negative. The subtraction may have been partially applied to some counts as
274
+ /// this error is returned when the first impossible subtraction is detected.
275
+ SubtrahendCountExceedsMinuendCount
276
+ }
277
+
278
+
243
279
/// Module containing the implementations of all `Histogram` iterators.
244
280
pub mod iterators;
245
281
@@ -356,7 +392,7 @@ impl<T: Counter> Histogram<T> {
356
392
357
393
/// Overwrite this histogram with the given histogram. All data and statistics in this
358
394
/// histogram will be overwritten.
359
- pub fn set_to < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , & ' static str > {
395
+ pub fn set_to < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , AdditionError > {
360
396
self . reset ( ) ;
361
397
self . add ( source. borrow ( ) )
362
398
}
@@ -380,15 +416,14 @@ impl<T: Counter> Histogram<T> {
380
416
///
381
417
/// May fail if values in the other histogram are higher than `.high()`, and auto-resize is
382
418
/// disabled.
383
- pub fn add < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , & ' static str > {
419
+ pub fn add < B : Borrow < Histogram < T > > > ( & mut self , source : B ) -> Result < ( ) , AdditionError > {
384
420
let source = source. borrow ( ) ;
385
421
386
422
// make sure we can take the values in source
387
423
let top = self . highest_equivalent ( self . value_for ( self . last ( ) ) ) ;
388
424
if top < source. max ( ) {
389
425
if !self . auto_resize {
390
- return Err ( "The other histogram includes values that do not fit in this \
391
- histogram's range.") ;
426
+ return Err ( AdditionError :: OtherAddendValuesExceedRange ) ;
392
427
}
393
428
self . resize ( source. max ( ) ) ;
394
429
}
@@ -480,15 +515,14 @@ impl<T: Counter> Histogram<T> {
480
515
/// disabled. Or, if the count for a given value in the other histogram is higher than that of
481
516
/// this histogram. In the latter case, some of the counts may still have been updated, which
482
517
/// may cause data corruption.
483
- pub fn subtract < B : Borrow < Histogram < T > > > ( & mut self , other : B ) -> Result < ( ) , & ' static str > {
518
+ pub fn subtract < B : Borrow < Histogram < T > > > ( & mut self , other : B ) -> Result < ( ) , SubtractionError > {
484
519
let other = other. borrow ( ) ;
485
520
486
521
// make sure we can take the values in source
487
522
let top = self . highest_equivalent ( self . value_for ( self . last ( ) ) ) ;
488
523
if top < other. max ( ) {
489
524
if !self . auto_resize {
490
- return Err ( "The other histogram includes values that do not fit in this \
491
- histogram's range.") ;
525
+ return Err ( SubtractionError :: SubtrahendValuesExceedMinuendRange ) ;
492
526
}
493
527
self . resize ( other. max ( ) ) ;
494
528
}
@@ -498,8 +532,7 @@ impl<T: Counter> Histogram<T> {
498
532
if other_count != T :: zero ( ) {
499
533
let other_value = other. value_for ( i) ;
500
534
if self . count_at ( other_value) . unwrap ( ) < other_count {
501
- return Err ( "The other histogram includes counts that are higher than the \
502
- current count for that value.") ;
535
+ return Err ( SubtractionError :: SubtrahendCountExceedsMinuendCount ) ;
503
536
}
504
537
self . alter_n ( other_value, other_count, false ) . expect ( "value should fit by now" ) ;
505
538
}
@@ -556,7 +589,7 @@ impl<T: Counter> Histogram<T> {
556
589
/// `sigfig` specifies the number of significant value digits to preserve in the recorded data.
557
590
/// This is the number of significant decimal digits to which the histogram will maintain value
558
591
/// resolution and separation. Must be a non-negative integer between 0 and 5.
559
- pub fn new ( sigfig : u8 ) -> Result < Histogram < T > , & ' static str > {
592
+ pub fn new ( sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
560
593
let mut h = Self :: new_with_bounds ( 1 , 2 , sigfig) ;
561
594
if let Ok ( ref mut h) = h {
562
595
h. auto_resize = true ;
@@ -572,7 +605,7 @@ impl<T: Counter> Histogram<T> {
572
605
/// that is >= 2. `sigfig` specifies the number of significant figures to maintain. This is the
573
606
/// number of significant decimal digits to which the histogram will maintain value resolution
574
607
/// and separation. Must be a non-negative integer between 0 and 5.
575
- pub fn new_with_max ( high : u64 , sigfig : u8 ) -> Result < Histogram < T > , & ' static str > {
608
+ pub fn new_with_max ( high : u64 , sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
576
609
Self :: new_with_bounds ( 1 , high, sigfig)
577
610
}
578
611
@@ -589,20 +622,20 @@ impl<T: Counter> Histogram<T> {
589
622
/// figures to maintain. This is the number of significant decimal digits to which the
590
623
/// histogram will maintain value resolution and separation. Must be a non-negative integer
591
624
/// between 0 and 5.
592
- pub fn new_with_bounds ( low : u64 , high : u64 , sigfig : u8 ) -> Result < Histogram < T > , & ' static str > {
625
+ pub fn new_with_bounds ( low : u64 , high : u64 , sigfig : u8 ) -> Result < Histogram < T > , CreationError > {
593
626
// Verify argument validity
594
627
if low < 1 {
595
- return Err ( "lowest discernible value must be >= 1" ) ;
628
+ return Err ( CreationError :: LowTooSmall ) ;
596
629
}
597
630
if low > u64:: max_value ( ) / 2 {
598
631
// avoid overflow in 2 * low
599
- return Err ( "lowest discernible value must be <= u64::max_value() / 2" )
632
+ return Err ( CreationError :: LowTooBig )
600
633
}
601
634
if high < 2 * low {
602
- return Err ( "highest trackable value must be >= 2 * lowest discernible value" ) ;
635
+ return Err ( CreationError :: HighLessThanTwiceLow ) ;
603
636
}
604
637
if sigfig > 5 {
605
- return Err ( "number of significant digits must be between 0 and 5" ) ;
638
+ return Err ( CreationError :: SigFigTooBig ) ;
606
639
}
607
640
608
641
// Given a 3 decimal point accuracy, the expectation is obviously for "+/- 1 unit at 1000".
@@ -634,7 +667,7 @@ impl<T: Counter> Histogram<T> {
634
667
// histogram vs ones whose magnitude here fits in 63 bits is debatable, and it makes
635
668
// it harder to work through the logic. Sums larger than 64 are totally broken as
636
669
// leading_zero_count_base would go negative.
637
- return Err ( "Cannot represent sigfig worth of values beyond low" ) ;
670
+ return Err ( CreationError :: CannotRepresentSigFigBeyondLow ) ;
638
671
} ;
639
672
640
673
let sub_bucket_half_count = sub_bucket_count / 2 ;
0 commit comments