refactor(irtt-stats): extract rolling event storage
This commit is contained in:
1 file changed
+51
-30
@@ -57,19 +57,15 @@ pub enum SampleMode {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct StatsCollector {
|
pub struct StatsCollector {
|
||||||
config: StatsConfig,
|
|
||||||
cumulative: CoreStats,
|
cumulative: CoreStats,
|
||||||
rolling_count: Option<VecDeque<StatsEvent>>,
|
rolling: RollingEvents,
|
||||||
rolling_time: Option<VecDeque<StatsEvent>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatsCollector {
|
impl StatsCollector {
|
||||||
pub fn new(config: StatsConfig) -> Self {
|
pub fn new(config: StatsConfig) -> Self {
|
||||||
Self {
|
Self {
|
||||||
config,
|
|
||||||
cumulative: CoreStats::new(config.samples),
|
cumulative: CoreStats::new(config.samples),
|
||||||
rolling_count: config.rolling_count.map(|_| VecDeque::new()),
|
rolling: RollingEvents::new(config),
|
||||||
rolling_time: config.rolling_time.map(|_| VecDeque::new()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,28 +75,7 @@ impl StatsCollector {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let update = self.cumulative.apply(stats_event.clone());
|
let update = self.cumulative.apply(stats_event.clone());
|
||||||
|
self.rolling.push(stats_event);
|
||||||
if let (Some(limit), Some(window)) =
|
|
||||||
(self.config.rolling_count, self.rolling_count.as_mut())
|
|
||||||
{
|
|
||||||
window.push_back(stats_event.clone());
|
|
||||||
while window.len() > limit {
|
|
||||||
window.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (Some(duration), Some(window)) =
|
|
||||||
(self.config.rolling_time, self.rolling_time.as_mut())
|
|
||||||
{
|
|
||||||
let cutoff = stats_event.at().checked_sub(duration);
|
|
||||||
window.push_back(stats_event);
|
|
||||||
if let Some(cutoff) = cutoff {
|
|
||||||
while window.front().is_some_and(|event| event.at() < cutoff) {
|
|
||||||
window.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +84,57 @@ impl StatsCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn rolling_count(&self) -> Option<Snapshot> {
|
pub fn rolling_count(&self) -> Option<Snapshot> {
|
||||||
self.rolling_count.as_ref().map(snapshot_window)
|
self.rolling.count_snapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rolling_time(&self) -> Option<Snapshot> {
|
pub fn rolling_time(&self) -> Option<Snapshot> {
|
||||||
self.rolling_time.as_ref().map(snapshot_window)
|
self.rolling.time_snapshot()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
struct RollingEvents {
|
||||||
|
count_limit: Option<usize>,
|
||||||
|
time_limit: Option<Duration>,
|
||||||
|
count_events: Option<VecDeque<StatsEvent>>,
|
||||||
|
time_events: Option<VecDeque<StatsEvent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RollingEvents {
|
||||||
|
fn new(config: StatsConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
count_limit: config.rolling_count,
|
||||||
|
time_limit: config.rolling_time,
|
||||||
|
count_events: config.rolling_count.map(|_| VecDeque::new()),
|
||||||
|
time_events: config.rolling_time.map(|_| VecDeque::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, event: StatsEvent) {
|
||||||
|
if let (Some(limit), Some(window)) = (self.count_limit, self.count_events.as_mut()) {
|
||||||
|
window.push_back(event.clone());
|
||||||
|
while window.len() > limit {
|
||||||
|
window.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let (Some(duration), Some(window)) = (self.time_limit, self.time_events.as_mut()) {
|
||||||
|
let cutoff = event.at().checked_sub(duration);
|
||||||
|
window.push_back(event);
|
||||||
|
if let Some(cutoff) = cutoff {
|
||||||
|
while window.front().is_some_and(|event| event.at() < cutoff) {
|
||||||
|
window.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_snapshot(&self) -> Option<Snapshot> {
|
||||||
|
self.count_events.as_ref().map(snapshot_window)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn time_snapshot(&self) -> Option<Snapshot> {
|
||||||
|
self.time_events.as_ref().map(snapshot_window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user