hyperflake_rs/
snowflake.rs1use crate::helper::{get_valid_node_id, wait_until_next_timestamp, defaults};
2
3pub struct SnowflakeId {
4 node_id_bits: i32,
5 sequence_bits: i32,
6 epoch: u64,
7 last_timestamp: i64,
8 sequence: u32,
9 node_id: i32,
10 max_sequence: u32,
11}
12
13impl SnowflakeId {
14 pub fn new() -> Self {
15 let worker_id = defaults::WORKER_ID;
16 let node_id_bits = defaults::NODE_ID_BITS;
17 let sequence_bits = defaults::SEQUENCE_BITS;
18 let epoch = defaults::EPOCH;
19
20 let last_timestamp = -1;
21 let sequence = 0;
22 let node_id = get_valid_node_id(worker_id as f64, node_id_bits);
23 let max_sequence = (1 << sequence_bits) - 1;
24
25 SnowflakeId {
26 node_id_bits,
27 sequence_bits,
28 epoch,
29 last_timestamp,
30 sequence,
31 node_id,
32 max_sequence,
33 }
34 }
35
36 pub fn generate(&mut self) -> String {
37 let timestamp: i64 = std::time::SystemTime::now()
38 .duration_since(std::time::UNIX_EPOCH)
39 .unwrap()
40 .as_millis() as i64;
41
42 if timestamp < self.last_timestamp {
43 panic!("Clock is moving backwards!");
44 }
45
46 if timestamp == self.last_timestamp {
47 self.sequence = (self.sequence + 1) & self.max_sequence;
48 if self.sequence == 0 {
49 let new_timestamp = wait_until_next_timestamp(timestamp as u64);
50 self.last_timestamp = new_timestamp as i64;
51 }
52 } else {
53 self.sequence = 0;
54 }
55
56 self.last_timestamp = timestamp;
57
58 let high = ((timestamp - self.epoch as i64) << (self.node_id_bits + self.sequence_bits))
59 | ((self.node_id as i64) << self.sequence_bits)
60 | self.sequence as i64;
61
62 let snowflake_id = high;
63
64 snowflake_id.to_string()
65 }
66
67 pub fn decode(&self, hfid: &str) -> u64 {
68 let high = hfid.parse::<i64>().unwrap();
69 let timestamp = ((high >> (self.node_id_bits + self.sequence_bits)) + self.epoch as i64) as u64;
70 timestamp
71 }
72}