use crate::{
aggregatable::{Aggregatable, Algorithm},
fixed_frequency::storage::{Level, LevelMeta, Storage},
};
use alloc::vec::Vec;
use core::{marker::PhantomData, time::Duration};
#[derive(Debug)]
#[allow(dead_code)]
enum TransInfo {
LevelCount {
level_count: usize,
relative_downsample: usize,
algo: Algorithm,
},
TimeRelative(Duration, usize, Algorithm),
TimeAbsolute(Duration, usize, Algorithm),
}
#[derive(Default)]
pub struct Builder<T> {
#[allow(dead_code)]
frequency: usize,
raw_count: usize,
level: Vec<TransInfo>,
_data: PhantomData<T>,
}
impl<T> Builder<T> {
pub fn new(frequency: usize, raw_count: usize) -> Builder<T> {
Builder {
frequency,
raw_count,
_data: Default::default(),
level: Vec::new(),
}
}
pub fn build(self) -> Storage<T>
where
T: Default,
{
let mut level = Vec::new();
let mut start = 0;
let mut end;
let mut last_count = self.raw_count;
for l in self.level {
let (count, downsample, algorithm) = match l {
TransInfo::LevelCount {
level_count,
relative_downsample,
algo,
} => {
let result = (last_count + relative_downsample, relative_downsample, algo);
last_count = level_count;
result
},
_ => unimplemented!(""),
};
end = start + count;
let meta = LevelMeta::new(start..end, downsample, algorithm);
level.push(Level::build(meta));
start = end;
}
end = start + last_count;
let meta = LevelMeta::new(start..end, 0, Algorithm::Average);
level.push(Level::build(meta));
let mut data = Vec::with_capacity(end);
for _ in 0..end {
data.push(T::default())
}
Storage { data, level }
}
pub fn level<const A: Algorithm>(mut self, level_count: usize, relative_downsample: usize) -> Self
where
T: Aggregatable<{ A }>,
{
debug_assert!(relative_downsample != 0);
self.level.push(TransInfo::LevelCount {
level_count,
relative_downsample,
algo: A,
});
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Algorithm;
#[test]
fn construct_simple() {
let s: Storage<f32> = Builder::new(100, 100)
.level::<{ Algorithm::Average }>(59, 100)
.level::<{ Algorithm::Average }>(59, 60)
.level::<{ Algorithm::Average }>(23, 60)
.build();
assert_eq!(s.level.len(), 4);
assert_eq!(s.level[0].0, LevelMeta::new(0..200, 100, Algorithm::Average));
assert_eq!(s.level[1].0, LevelMeta::new(200..319, 60, Algorithm::Average));
assert_eq!(s.level[2].0, LevelMeta::new(319..438, 60, Algorithm::Average));
assert_eq!(s.level[3].0, LevelMeta::new(438..461, 0, Algorithm::Average));
}
#[test]
fn construct_use_simple() {
let mut s: Storage<f32> = Builder::new(100, 100)
.level::<{ Algorithm::Average }>(59, 100)
.level::<{ Algorithm::Average }>(59, 60)
.level::<{ Algorithm::Average }>(23, 60)
.build();
for _ in 0..1000 {
s.push(0.0);
}
}
}