Skip to main content

raphtory_core/entities/graph/
timer.rs

1use serde::{Deserialize, Serialize};
2use std::sync::atomic::{AtomicI64, Ordering};
3
4pub trait TimeCounterTrait {
5    fn cmp(a: i64, b: i64) -> bool;
6    fn counter(&self) -> &AtomicI64;
7
8    fn update(&self, new_value: i64) {
9        let mut current_value = self.get();
10        while Self::cmp(new_value, current_value) {
11            match self.counter().compare_exchange_weak(
12                current_value,
13                new_value,
14                Ordering::Relaxed,
15                Ordering::Relaxed,
16            ) {
17                Ok(_) => break,
18                Err(value) => current_value = value,
19            }
20        }
21    }
22    #[inline(always)]
23    fn get(&self) -> i64 {
24        self.counter().load(Ordering::Relaxed)
25    }
26}
27
28#[derive(Serialize, Deserialize, Debug)]
29pub struct MinCounter {
30    counter: AtomicI64,
31}
32
33impl Default for MinCounter {
34    fn default() -> Self {
35        Self::new()
36    }
37}
38
39impl MinCounter {
40    pub fn new() -> Self {
41        Self {
42            counter: AtomicI64::new(i64::MAX),
43        }
44    }
45}
46
47impl TimeCounterTrait for MinCounter {
48    fn cmp(new_value: i64, current_value: i64) -> bool {
49        new_value < current_value
50    }
51
52    #[inline(always)]
53    fn counter(&self) -> &AtomicI64 {
54        &self.counter
55    }
56}
57
58#[derive(Serialize, Deserialize, Debug)]
59pub struct MaxCounter {
60    counter: AtomicI64,
61}
62
63impl Default for MaxCounter {
64    fn default() -> Self {
65        Self::new()
66    }
67}
68
69impl MaxCounter {
70    pub fn new() -> Self {
71        Self {
72            counter: AtomicI64::new(i64::MIN),
73        }
74    }
75}
76
77impl TimeCounterTrait for MaxCounter {
78    fn cmp(a: i64, b: i64) -> bool {
79        a > b
80    }
81    #[inline(always)]
82    fn counter(&self) -> &AtomicI64 {
83        &self.counter
84    }
85}
86
87#[cfg(test)]
88mod test {
89
90    use super::*;
91
92    #[test]
93    fn min_counter() {
94        let counter = MinCounter::new();
95        counter.update(0);
96        assert_eq!(counter.get(), 0);
97        counter.update(1);
98        assert_eq!(counter.get(), 0);
99        counter.update(0);
100        assert_eq!(counter.get(), 0);
101        counter.update(-1);
102        assert_eq!(counter.get(), -1);
103    }
104
105    #[test]
106    fn max_counter() {
107        let counter = MaxCounter::new();
108        counter.update(0);
109        assert_eq!(counter.get(), 0);
110        counter.update(-1);
111        assert_eq!(counter.get(), 0);
112        counter.update(0);
113        assert_eq!(counter.get(), 0);
114        counter.update(1);
115        assert_eq!(counter.get(), 1);
116    }
117}