Skip to main content

linkrs_metrics/manager/
metric_value.rs

1//! Atomic counter primitive with last-update timestamp.
2
3use dashmap::DashMap;
4use std::sync::atomic::{AtomicU64, Ordering};
5use std::sync::Arc;
6
7use super::metric_type::MetricType;
8
9/// Space metrics type alias
10pub(crate) type SpaceMetrics = Arc<DashMap<MetricType, Arc<MetricValue>>>;
11
12/// metric
13#[derive(Debug)]
14pub struct MetricValue {
15    pub value: AtomicU64,
16    pub timestamp: AtomicU64,
17}
18
19impl MetricValue {
20    pub fn new(value: u64) -> Self {
21        let timestamp_secs = std::time::SystemTime::now()
22            .duration_since(std::time::UNIX_EPOCH)
23            .unwrap_or_default()
24            .as_secs();
25        Self {
26            value: AtomicU64::new(value),
27            timestamp: AtomicU64::new(timestamp_secs),
28        }
29    }
30
31    pub fn increment(&self) {
32        self.value.fetch_add(1, Ordering::Relaxed);
33        self.update_timestamp();
34    }
35
36    pub fn add(&self, amount: u64) {
37        self.value.fetch_add(amount, Ordering::Relaxed);
38        self.update_timestamp();
39    }
40
41    pub fn decrement(&self) {
42        let _ = self
43            .value
44            .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |v| {
45                if v > 0 {
46                    Some(v - 1)
47                } else {
48                    Some(0)
49                }
50            });
51        self.update_timestamp();
52    }
53
54    pub fn set(&self, value: u64) {
55        self.value.store(value, Ordering::Relaxed);
56        self.update_timestamp();
57    }
58
59    pub fn get(&self) -> u64 {
60        self.value.load(Ordering::Relaxed)
61    }
62
63    pub fn get_timestamp(&self) -> u64 {
64        self.timestamp.load(Ordering::Relaxed)
65    }
66
67    fn update_timestamp(&self) {
68        let timestamp_secs = std::time::SystemTime::now()
69            .duration_since(std::time::UNIX_EPOCH)
70            .unwrap_or_default()
71            .as_secs();
72        self.timestamp.store(timestamp_secs, Ordering::Relaxed);
73    }
74}