use std::fmt;
use chrono::{DateTime, Local};
#[inline]
pub
fn get_current_timestamp() -> DateTime<Local>
{
return chrono::offset::Local::now();
}
#[cfg(target_has_atomic = "64")]
static ORD_ID: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);
#[cfg(not(target_has_atomic = "64"))]
static ORD_ID: std::sync::Mutex<u32> = std::sync::Mutex::new(0);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TimerDequeId
{
pub(crate) timestamp: i64,
pub(crate) timestamp_ns: u32,
pub(crate) ran_id: u32,
}
impl fmt::Display for TimerDequeId
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "{:X}/{:X}/{:X}", self.timestamp, self.timestamp_ns, self.ran_id)
}
}
impl TimerDequeId
{
#[cfg(target_has_atomic = "64")]
fn generate_ord_numer() -> u32
{
use std::sync::atomic::{Ordering};
let mut last = ORD_ID.load(Ordering::Relaxed);
loop
{
let seq_id =
match last.checked_add(1)
{
Some(id) => id,
None =>
{
0
}
};
match ORD_ID.compare_exchange_weak(last, seq_id, Ordering::Relaxed, Ordering::Relaxed)
{
Ok(_) =>
return seq_id,
Err(id) =>
last = id,
}
}
}
#[cfg(not(target_has_atomic = "64"))]
fn generate_sequence_num() -> u32
{
let mut seq_id_cnt =
ORD_ID.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
let seq_id =
match seq_id_cnt.checked_add(1)
{
Some(id) => id,
None =>
{
0
}
};
*seq_id_cnt = seq_id;
drop(seq_id_cnt);
return seq_id;
}
pub(crate)
fn new() -> Self
{
let ts = get_current_timestamp();
let ord_num = Self::generate_ord_numer();
return
Self
{
timestamp:
ts.timestamp(),
timestamp_ns:
ts.timestamp_subsec_nanos(),
ran_id:
ord_num,
};
}
}