Skip to main content

entrenar/monitor/storage/
in_memory.rs

1//! In-memory metrics store implementation
2
3use super::error::StorageResult;
4use super::traits::MetricsStore;
5use crate::monitor::{Metric, MetricRecord, MetricStats};
6
7/// In-memory metrics store (always available, no feature flag)
8#[derive(Debug, Default)]
9pub struct InMemoryStore {
10    pub(crate) records: Vec<MetricRecord>,
11}
12
13impl InMemoryStore {
14    /// Create a new in-memory store
15    pub fn new() -> Self {
16        Self { records: Vec::new() }
17    }
18
19    /// Get all records
20    pub fn all_records(&self) -> &[MetricRecord] {
21        &self.records
22    }
23}
24
25impl MetricsStore for InMemoryStore {
26    fn write_batch(&mut self, records: &[MetricRecord]) -> StorageResult<()> {
27        self.records.extend(records.iter().cloned());
28        Ok(())
29    }
30
31    fn query_range(
32        &self,
33        metric: &Metric,
34        start_ts: u64,
35        end_ts: u64,
36    ) -> StorageResult<Vec<MetricRecord>> {
37        Ok(self
38            .records
39            .iter()
40            .filter(|r| &r.metric == metric && r.timestamp >= start_ts && r.timestamp <= end_ts)
41            .cloned()
42            .collect())
43    }
44
45    fn query_all(&self, metric: &Metric) -> StorageResult<Vec<MetricRecord>> {
46        Ok(self.records.iter().filter(|r| &r.metric == metric).cloned().collect())
47    }
48
49    fn query_stats(&self, metric: &Metric) -> StorageResult<Option<MetricStats>> {
50        let values: Vec<f64> =
51            self.records.iter().filter(|r| &r.metric == metric).map(|r| r.value).collect();
52
53        if values.is_empty() {
54            return Ok(None);
55        }
56
57        let count = values.len();
58        let sum: f64 = values.iter().sum();
59        let mean = sum / count as f64;
60        let min = values.iter().copied().fold(f64::INFINITY, f64::min);
61        let max = values.iter().copied().fold(f64::NEG_INFINITY, f64::max);
62
63        let variance = if count > 1 {
64            values.iter().map(|v| (v - mean).powi(2)).sum::<f64>() / (count - 1) as f64
65        } else {
66            0.0
67        };
68        let std = variance.sqrt();
69
70        let has_nan = values.iter().any(|v| v.is_nan());
71        let has_inf = values.iter().any(|v| v.is_infinite());
72
73        Ok(Some(MetricStats { count, mean, std, min, max, sum, has_nan, has_inf }))
74    }
75
76    fn count(&self) -> StorageResult<usize> {
77        Ok(self.records.len())
78    }
79
80    fn flush(&mut self) -> StorageResult<()> {
81        Ok(())
82    }
83}