1use std::fmt;
19
20use chrono::{DateTime, Local};
21
22
23#[inline]
25pub
26fn get_current_timestamp() -> DateTime<Local>
27{
28 return chrono::offset::Local::now();
29}
30
31#[cfg(target_has_atomic = "64")]
34static ORD_ID: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);
35
36#[cfg(not(target_has_atomic = "64"))]
39static ORD_ID: std::sync::Mutex<u32> = std::sync::Mutex::new(0);
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
44pub struct TimerDequeId
45{
46 pub(crate) timestamp: i64,
48
49 pub(crate) timestamp_ns: u32,
51
52 pub(crate) ran_id: u32,
54}
55
56
57impl fmt::Display for TimerDequeId
58{
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
60 {
61 write!(f, "{:X}/{:X}/{:X}", self.timestamp, self.timestamp_ns, self.ran_id)
62 }
63}
64
65impl TimerDequeId
66{
67 #[cfg(target_has_atomic = "64")]
68 fn generate_ord_numer() -> u32
69 {
70 use std::sync::atomic::{Ordering};
71
72 let mut last = ORD_ID.load(Ordering::Relaxed);
73
74 loop
75 {
76 let seq_id =
77 match last.checked_add(1)
78 {
79 Some(id) => id,
80 None =>
81 {
82 0
83 }
84 };
85
86 match ORD_ID.compare_exchange_weak(last, seq_id, Ordering::Relaxed, Ordering::Relaxed)
87 {
88 Ok(_) =>
89 return seq_id,
90 Err(id) =>
91 last = id,
92 }
93 }
94 }
95
96 #[cfg(not(target_has_atomic = "64"))]
97 fn generate_sequence_num() -> u32
98 {
99 let mut seq_id_cnt =
100 ORD_ID.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
101
102 let seq_id =
103 match seq_id_cnt.checked_add(1)
104 {
105 Some(id) => id,
106 None =>
107 {
108 0
109 }
110 };
111
112 *seq_id_cnt = seq_id;
113 drop(seq_id_cnt);
114
115 return seq_id;
116 }
117
118 pub(crate)
119 fn new() -> Self
120 {
121 let ts = get_current_timestamp();
122 let ord_num = Self::generate_ord_numer();
123
124 return
125 Self
126 {
127 timestamp:
128 ts.timestamp(),
129 timestamp_ns:
130 ts.timestamp_subsec_nanos(),
131 ran_id:
132 ord_num,
133 };
134 }
135}
136