raphtory_core/entities/graph/
timer.rs1use 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 From<i64> for MinCounter {
40 fn from(value: i64) -> Self {
41 let counter = AtomicI64::new(value);
42 Self { counter }
43 }
44}
45
46impl MinCounter {
47 pub fn new() -> Self {
48 Self {
49 counter: AtomicI64::new(i64::MAX),
50 }
51 }
52}
53
54impl TimeCounterTrait for MinCounter {
55 fn cmp(new_value: i64, current_value: i64) -> bool {
56 new_value < current_value
57 }
58
59 #[inline(always)]
60 fn counter(&self) -> &AtomicI64 {
61 &self.counter
62 }
63}
64
65#[derive(Serialize, Deserialize, Debug)]
66pub struct MaxCounter {
67 counter: AtomicI64,
68}
69
70impl From<i64> for MaxCounter {
71 fn from(value: i64) -> Self {
72 let counter = AtomicI64::new(value);
73 Self { counter }
74 }
75}
76
77impl Default for MaxCounter {
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83impl MaxCounter {
84 pub fn new() -> Self {
85 Self {
86 counter: AtomicI64::new(i64::MIN),
87 }
88 }
89}
90
91impl TimeCounterTrait for MaxCounter {
92 fn cmp(a: i64, b: i64) -> bool {
93 a > b
94 }
95 #[inline(always)]
96 fn counter(&self) -> &AtomicI64 {
97 &self.counter
98 }
99}
100
101#[cfg(test)]
102mod test {
103
104 use super::*;
105
106 #[test]
107 fn min_counter() {
108 let counter = MinCounter::new();
109 counter.update(0);
110 assert_eq!(counter.get(), 0);
111 counter.update(1);
112 assert_eq!(counter.get(), 0);
113 counter.update(0);
114 assert_eq!(counter.get(), 0);
115 counter.update(-1);
116 assert_eq!(counter.get(), -1);
117 }
118
119 #[test]
120 fn max_counter() {
121 let counter = MaxCounter::new();
122 counter.update(0);
123 assert_eq!(counter.get(), 0);
124 counter.update(-1);
125 assert_eq!(counter.get(), 0);
126 counter.update(0);
127 assert_eq!(counter.get(), 0);
128 counter.update(1);
129 assert_eq!(counter.get(), 1);
130 }
131}