add SummaryStats util type to tidepool
This commit is contained in:
parent
517a64156a
commit
8b60c03232
|
@ -34,6 +34,95 @@ pub struct Profile {
|
|||
// TODO: histograms about selected nodes
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct SummaryStats<T: Copy> {
|
||||
count: usize,
|
||||
min: Option<T>,
|
||||
max: Option<T>,
|
||||
sum: Option<T>,
|
||||
}
|
||||
|
||||
impl<T: Copy> Default for SummaryStats<T> {
|
||||
fn default() -> Self {
|
||||
SummaryStats {
|
||||
count: 0,
|
||||
min: None,
|
||||
max: None,
|
||||
sum: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> SummaryStats<T> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn count(&self) -> usize {
|
||||
self.count
|
||||
}
|
||||
|
||||
pub fn min(&self) -> Option<T> {
|
||||
self.min
|
||||
}
|
||||
|
||||
pub fn max(&self) -> Option<T> {
|
||||
self.max
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SummaryStats<T>
|
||||
where
|
||||
T: Ord + Copy + std::ops::Add<T, Output = T>,
|
||||
{
|
||||
pub fn insert(&mut self, x: T) {
|
||||
self.count += 1;
|
||||
self.min = Some(self.min.map_or(x, |y| x.min(y)));
|
||||
self.max = Some(self.max.map_or(x, |y| x.max(y)));
|
||||
self.sum = Some(self.sum.map_or(x, |y| x + y));
|
||||
}
|
||||
}
|
||||
|
||||
impl SummaryStats<f64> {
|
||||
pub fn insert_f64(&mut self, x: f64) {
|
||||
self.count += 1;
|
||||
self.min = Some(self.min.map_or(x, |y| x.min(y)));
|
||||
self.max = Some(self.max.map_or(x, |y| x.max(y)));
|
||||
self.sum = Some(self.sum.map_or(x, |y| x + y));
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SummaryStats<T>
|
||||
where
|
||||
T: Copy + std::ops::Div<usize, Output = T>,
|
||||
{
|
||||
pub fn avg(&self) -> Option<T> {
|
||||
self.sum.map(|x| x / self.count)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SummaryStats<T>
|
||||
where
|
||||
T: Copy,
|
||||
f64: From<T>,
|
||||
{
|
||||
pub fn avg_f64(&self) -> Option<f64> {
|
||||
self.sum.map(|x| f64::from(x) / self.count as f64)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Serialize for SummaryStats<T>
|
||||
where
|
||||
T: Serialize + Copy + std::ops::Div<usize, Output = T>,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
ser::summary_stats(self, serializer)
|
||||
}
|
||||
}
|
||||
|
||||
mod ser {
|
||||
use super::*;
|
||||
|
||||
|
@ -78,4 +167,27 @@ mod ser {
|
|||
{
|
||||
dur.as_secs_f64().serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn summary_stats<S, T>(stats: &SummaryStats<T>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
T: Serialize + Copy + std::ops::Div<usize, Output = T>,
|
||||
S: serde::Serializer,
|
||||
{
|
||||
#[derive(Serialize)]
|
||||
struct Stats<T> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
min: Option<T>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
max: Option<T>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
avg: Option<T>,
|
||||
}
|
||||
|
||||
Stats {
|
||||
min: stats.min,
|
||||
max: stats.max,
|
||||
avg: stats.avg(),
|
||||
}
|
||||
.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue