bitcasky_common/
clock.rs

1use std::{
2    fmt::Debug,
3    ops::{Deref, DerefMut},
4    sync::{
5        atomic::{AtomicU64, Ordering},
6        Arc,
7    },
8    time::{SystemTime, UNIX_EPOCH},
9};
10
11pub trait Clock {
12    fn now(&self) -> u64;
13}
14
15#[derive(Debug)]
16pub struct SystemClock {}
17
18impl Clock for SystemClock {
19    fn now(&self) -> u64 {
20        SystemTime::now()
21            .duration_since(UNIX_EPOCH)
22            .unwrap()
23            .as_millis() as u64
24    }
25}
26
27#[derive(Debug)]
28pub struct DebugClock {
29    time: AtomicU64,
30}
31
32impl DebugClock {
33    pub fn new(time: u64) -> DebugClock {
34        DebugClock {
35            time: AtomicU64::new(time),
36        }
37    }
38
39    pub fn set(&self, time: u64) {
40        self.time.store(time, Ordering::Release);
41    }
42}
43
44impl Clock for DebugClock {
45    fn now(&self) -> u64 {
46        self.time.load(Ordering::Acquire)
47    }
48}
49
50#[derive(Debug)]
51pub enum ClockImpl {
52    System(SystemClock),
53    Debug(Arc<DebugClock>),
54}
55
56impl Clock for ClockImpl {
57    fn now(&self) -> u64 {
58        match self {
59            ClockImpl::System(c) => c.now(),
60            ClockImpl::Debug(c) => c.now(),
61        }
62    }
63}
64
65#[derive(Debug)]
66pub struct BitcaskyClock {
67    pub clock: ClockImpl,
68}
69
70impl Clock for BitcaskyClock {
71    fn now(&self) -> u64 {
72        self.clock.now()
73    }
74}
75
76impl Deref for BitcaskyClock {
77    type Target = ClockImpl;
78
79    fn deref(&self) -> &Self::Target {
80        &self.clock
81    }
82}
83
84impl DerefMut for BitcaskyClock {
85    fn deref_mut(&mut self) -> &mut Self::Target {
86        &mut self.clock
87    }
88}
89
90impl Default for BitcaskyClock {
91    fn default() -> Self {
92        Self {
93            clock: ClockImpl::System(SystemClock {}),
94        }
95    }
96}