use std::time::{SystemTime,UNIX_EPOCH};
use std::sync::Mutex;
pub struct SnowflakeWorker {
last: Mutex<u64>,
datacenter_id: u8,
worker_id: u8,
sequence_id: u16,
}
impl SnowflakeWorker {
fn now() -> u64 {
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
now.as_millis() as u64
}
pub fn gen(&mut self) -> u64 {
let mut last = self.last.lock().unwrap();
let now = SnowflakeWorker::now();
if *last == now {
self.sequence_id += 1;
} else if *last < now {
*last = now;
self.sequence_id = 0;
}
SnowflakeWorker::format(&last, &self.datacenter_id, &self.worker_id, &self.sequence_id)
}
fn format(last: &u64, datacenter_id: &u8, worker_id: &u8, sequence_id: &u16) -> u64 {
last << 22 | (datacenter_id.clone() as u64) << 17 | (worker_id.clone() as u64) << 12 | sequence_id.clone() as u64
}
pub fn new(datacenter_id: u8, worker_id: u8) -> SnowflakeWorker {
SnowflakeWorker { last: Mutex::new(0), datacenter_id: datacenter_id, worker_id: worker_id, sequence_id: 0 }
}
}