rust_algorithms/
snowflake.rs

1use std::time::{SystemTime,UNIX_EPOCH};
2use std::sync::Mutex;
3
4pub struct SnowflakeWorker {
5    last: Mutex<u64>,
6    datacenter_id: u8,
7    worker_id: u8,
8    sequence_id: u16,
9}
10
11impl SnowflakeWorker {
12     fn now() -> u64 {
13         let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
14         now.as_millis() as u64
15     }
16
17     pub fn gen(&mut self) -> u64 {
18        let mut last = self.last.lock().unwrap();
19        let now = SnowflakeWorker::now();
20        if *last == now {
21            self.sequence_id += 1;
22        } else if *last < now {
23            *last = now;
24            self.sequence_id = 0;
25        }
26        SnowflakeWorker::format(&last, &self.datacenter_id, &self.worker_id, &self.sequence_id)
27    }
28
29    fn format(last: &u64, datacenter_id: &u8, worker_id: &u8, sequence_id: &u16) -> u64 {
30        last << 22 | (datacenter_id.clone() as u64) << 17 | (worker_id.clone() as u64) << 12 | sequence_id.clone() as u64
31    }
32
33    pub fn new(datacenter_id: u8, worker_id: u8) -> SnowflakeWorker {
34        SnowflakeWorker { last: Mutex::new(0), datacenter_id: datacenter_id, worker_id: worker_id, sequence_id: 0 }
35    }
36}