8
8
//! # Examples
9
9
//!
10
10
//! ```
11
- //! use liblumen_alloc::stats::define_histogram;
12
- //!
13
- //! define_histogram!(10);
11
+ //! use liblumen_alloc::stats::Histogram;
12
+ //!
13
+ //! mod stats {
14
+ //! use liblumen_alloc::define_histogram;
15
+ //! define_histogram!(10);
16
+ //! }
14
17
//! # fn main() {
15
18
//! // Create a histogram that will spread the given range over
16
19
//! // the 10 buckets the `Histogram` type was defined with.
17
- //! let mut histogram = Histogram::with_const_width(0, 10_000);
20
+ //! let mut histogram = stats:: Histogram::with_const_width(0, 10_000);
18
21
//!
19
22
//! // Adds some samples to the histogram.
20
23
//! for sample in 0..100 {
56
59
//! // ```
57
60
//! # }
58
61
//! ```
59
- #![ deny( missing_docs) ]
60
62
#![ deny( unsafe_code) ]
61
63
62
64
use core:: fmt;
@@ -65,7 +67,7 @@ pub use defaults::Histogram as DefaultHistogram;
65
67
66
68
/// This trait represents the bare minimum functionality needed
67
69
/// to interact with an implementation by a mutator
68
- pub trait Histogram : Clone + Default + fmt:: Display {
70
+ pub trait Histogram : fmt:: Display {
69
71
/// Add a sample to the histogram.
70
72
///
71
73
/// Fails if the sample is out of range of the histogram.
@@ -219,9 +221,36 @@ macro_rules! define_histogram {
219
221
pub fn range_max( & self ) -> u64 {
220
222
self . range[ Self :: LEN ]
221
223
}
224
+
225
+ /// Return the minimum value observed so far
226
+ #[ inline]
227
+ pub fn min( & self ) -> u64 {
228
+ self . minmax. min( ) . copied( ) . unwrap_or( 0 )
229
+ }
230
+
231
+ /// Return the maximum value observed so far
232
+ #[ inline]
233
+ pub fn max( & self ) -> u64 {
234
+ self . minmax. max( ) . copied( ) . unwrap_or( 0 )
235
+ }
236
+
237
+ #[ inline]
238
+ pub fn mean( & self ) -> f64 {
239
+ self . stats. mean( )
240
+ }
241
+
242
+ #[ inline]
243
+ pub fn stddev( & self ) -> f64 {
244
+ self . stats. stddev( )
245
+ }
246
+
247
+ #[ inline]
248
+ pub fn variance( & self ) -> f64 {
249
+ self . stats. variance( )
250
+ }
222
251
}
223
252
224
- impl $crate:: stats:: histogram :: Histogram for Histogram {
253
+ impl $crate:: stats:: Histogram for Histogram {
225
254
/// Add a sample to the histogram.
226
255
///
227
256
/// Fails if the sample is out of range of the histogram.
@@ -274,6 +303,9 @@ macro_rules! define_histogram {
274
303
use core:: cmp;
275
304
use core:: fmt:: Write ;
276
305
306
+ #[ cfg( not( test) ) ]
307
+ use alloc:: string:: String ;
308
+
277
309
let num_samples: u64 = self . bins( ) . iter( ) . sum( ) ;
278
310
writeln!( f, "# Number of samples = {}" , num_samples) ?;
279
311
if num_samples == 0 {
@@ -357,71 +389,79 @@ mod defaults {
357
389
// This histogram will spread all allocations across 100 buckets
358
390
define_histogram ! ( 100 ) ;
359
391
// Provide a default implementation which will focus on the main sizes of concern
360
- impl Default for Histogram {
392
+ impl Default for self :: Histogram {
361
393
fn default ( ) -> Self {
362
- let mut ranges = Vec :: with_capacity ( 100 ) ;
394
+ use heapless:: Vec ;
395
+ use heapless:: consts:: U100 ;
396
+ let mut ranges = Vec :: < _ , U100 > :: new ( ) ;
363
397
// Use the fibonnaci sequence up to 1TB
364
398
let mut n: u64 = 1 ;
365
399
let mut m: u64 = 2 ;
366
- ranges. push ( m) ;
400
+ ranges. push ( m) . unwrap ( ) ;
367
401
for _ in 1 ..57u64 {
368
402
let new_m = n + m;
369
403
n = m;
370
- ranges. push ( new_m) ;
404
+ ranges. push ( new_m) . unwrap ( ) ;
371
405
m = new_m;
372
406
}
373
407
// Grow by 20% afterwards
374
408
for _ in 57 ..99u64 {
375
409
let new_m = m + ( m as f64 * 0.2 ) . ceil ( ) as u64 ;
376
- ranges. push ( new_m) ;
410
+ ranges. push ( new_m) . unwrap ( ) ;
377
411
m = new_m;
378
412
}
379
413
// Add one final range that covers the remaining address space
380
- ranges. push ( u64:: max_value ( ) ) ;
381
- Self :: from_ranges ( ranges. as_slice ( ) . iter ( ) . cloned ( ) ) . unwrap ( )
414
+ ranges. push ( u64:: max_value ( ) ) . unwrap ( ) ;
415
+ Self :: from_ranges ( ranges. iter ( ) . cloned ( ) ) . unwrap ( )
382
416
}
383
417
}
384
418
}
385
419
386
420
#[ cfg( test) ]
387
421
mod tests {
388
- use super :: * ;
422
+ mod defaults {
423
+ use crate :: define_histogram;
424
+
425
+ define_histogram ! ( 10 ) ;
426
+ }
389
427
390
- define_histogram ! ( 10 ) ;
428
+ use super :: Histogram ;
429
+ use self :: defaults:: Histogram as DefaultHistogram ;
391
430
392
431
#[ test]
393
- fn with_const_width_test ( ) {
394
- let mut h = Histogram :: with_const_width ( 0 , 100 ) ;
432
+ fn histogram_with_const_width_test ( ) {
433
+ let mut h = DefaultHistogram :: with_const_width ( 0 , 100 ) ;
395
434
for i in 0 ..100 {
396
- h. add ( i) ;
435
+ h. add ( i) . ok ( ) ;
397
436
}
398
437
assert_eq ! ( h. max( ) , 99 ) ;
399
438
assert_eq ! ( h. min( ) , 0 ) ;
400
- assert_eq ! ( h. mean( ) , 50 ) ;
401
- assert_eq ! ( h. bins( ) , & [ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 9 ] )
439
+ assert_eq ! ( h. mean( ) , 49.5 ) ;
440
+ assert_eq ! ( h. bins( ) , & [ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 ] )
402
441
}
403
442
404
443
#[ test]
405
- fn from_ranges_test ( ) {
406
- let ranges = [
407
- ( 2 , 4 ) ,
408
- ( 4 , 8 ) ,
409
- ( 8 , 16 ) ,
410
- ( 16 , 32 ) ,
411
- ( 32 , 64 ) ,
412
- ( 64 , 128 ) ,
413
- ( 128 , 256 ) ,
414
- ( 256 , 512 ) ,
415
- ( 512 , 1024 ) ,
416
- ( 1024 , 2048 ) ,
444
+ fn histogram_from_ranges_test ( ) {
445
+ let ranges: [ u64 ; 11 ] = [
446
+ 2 ,
447
+ 4 ,
448
+ 8 ,
449
+ 16 ,
450
+ 32 ,
451
+ 64 ,
452
+ 128 ,
453
+ 256 ,
454
+ 512 ,
455
+ 1024 ,
456
+ 2048
417
457
] ;
418
- let mut h = Histogram :: from_ranges ( & ranges) ;
458
+ let mut h = DefaultHistogram :: from_ranges ( ranges. iter ( ) . copied ( ) ) . unwrap ( ) ;
419
459
for i in 2 ..2048 {
420
- h. add ( i) ;
460
+ h. add ( i) . ok ( ) ;
421
461
}
422
462
assert_eq ! ( h. max( ) , 2047 ) ;
423
463
assert_eq ! ( h. min( ) , 2 ) ;
424
- assert_eq ! ( h. mean( ) , 50 ) ;
425
- assert_eq ! ( h. bins( ) , & [ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 9 ] )
464
+ assert_eq ! ( h. mean( ) , 1024.5 ) ;
465
+ assert_eq ! ( h. bins( ) , & [ 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 ] )
426
466
}
427
467
}
0 commit comments