1#![allow(dead_code)]
2use std::hint::spin_loop;
5use std::ops::Deref;
6use std::sync::atomic::{AtomicI16, AtomicI64, Ordering};
7
8use std::time::{SystemTime, UNIX_EPOCH};
9
10use serde::de::Visitor;
11use serde::{de, Serialize, Serializer};
12
13#[derive(Debug)]
14pub struct NumericalUniqueIdGenerator {
15 epoch: SystemTime,
17
18 pub datacenter_id: i32,
22 pub machine_id: i32,
23
24 timestamp: AtomicI64,
27
28 sequence_num: AtomicI16,
30}
31
32#[derive(Debug)]
33pub struct NumericalUniqueIdBucket {
34 snowflake_id_generator: NumericalUniqueIdGenerator,
36
37 bucket: Vec<i64>,
39}
40
41impl NumericalUniqueIdGenerator {
42 pub fn new(datacenter_id: i32, machine_id: i32) -> NumericalUniqueIdGenerator {
52 Self::with_epoch(datacenter_id, machine_id, UNIX_EPOCH)
53 }
54
55 pub fn with_epoch(datacenter_id: i32, machine_id: i32, epoch: SystemTime) -> NumericalUniqueIdGenerator {
68 let timestamp = current_time_in_milli(epoch);
70
71 NumericalUniqueIdGenerator {
72 epoch,
73 timestamp: AtomicI64::new(timestamp),
74 datacenter_id,
75 machine_id,
76 sequence_num: AtomicI16::new(0),
77 }
78 }
79
80 fn get_snowflake(&self) -> i64 {
86 self.timestamp.load(Ordering::Relaxed) << 22 | ((self.datacenter_id << 17) as i64) | ((self.machine_id << 12) as i64) | (self.sequence_num.load(Ordering::Relaxed) as i64)
87 }
88
89 pub fn generate(&self) -> i64 {
105 self.sequence_num.store((self.sequence_num.load(Ordering::Relaxed) + 1) % 4096, Ordering::Relaxed);
106
107 let mut now_millis = current_time_in_milli(self.epoch);
108
109 if self.timestamp.load(Ordering::Relaxed) == now_millis {
113 if self.sequence_num.load(Ordering::Relaxed) == 0 {
115 now_millis = race_next_milli(self.timestamp.load(Ordering::Relaxed), self.epoch);
116 self.timestamp.store(now_millis, Ordering::Relaxed);
117 }
118 } else {
119 self.timestamp.store(now_millis, Ordering::Relaxed);
120 self.sequence_num.store(0, Ordering::Relaxed);
121 }
122
123 self.get_snowflake()
124 }
125}
126
127impl NumericalUniqueIdBucket {
129 pub fn new(datacenter_id: i32, machine_id: i32) -> Self {
140 Self::with_epoch(datacenter_id, machine_id, UNIX_EPOCH)
141 }
142
143 pub fn with_epoch(datacenter_id: i32, machine_id: i32, epoch: SystemTime) -> Self {
157 let snowflake_id_generator = NumericalUniqueIdGenerator::with_epoch(datacenter_id, machine_id, epoch);
158 let bucket = Vec::new();
159
160 NumericalUniqueIdBucket { snowflake_id_generator, bucket }
161 }
162
163 pub fn get_id(&mut self) -> i64 {
173 if self.bucket.is_empty() {
177 self.fill_bucket();
178 }
179 self.bucket.pop().unwrap()
180 }
181
182 fn fill_bucket(&mut self) {
183 for _ in 0..4091 {
187 self.bucket.push(self.snowflake_id_generator.generate());
188 }
189 }
190}
191
192#[inline(always)]
193pub fn current_time_in_milli(epoch: SystemTime) -> i64 {
195 SystemTime::now().duration_since(epoch).expect("System Time Error!").as_millis() as i64
196}
197
198#[inline(always)]
199fn race_next_milli(timestamp: i64, epoch: SystemTime) -> i64 {
201 let mut latest_time_millis: i64;
202 loop {
203 latest_time_millis = current_time_in_milli(epoch);
204 if latest_time_millis > timestamp {
205 return latest_time_millis;
206 }
207 spin_loop();
208 }
209}
210
211static ID_GENERATOR: std::sync::LazyLock<NumericalUniqueIdGenerator> = std::sync::LazyLock::new(|| {
212 NumericalUniqueIdGenerator::new(
213 std::env::var("DATACENTER_ID").unwrap_or("1".to_string()).parse::<i32>().expect("Parsing Failed!"),
214 std::env::var("MACHINE_ID").unwrap_or("1".to_string()).parse::<i32>().expect("Parsing Failed!"),
215 )
216});
217
218#[derive(Clone, Hash, PartialEq, Debug, Eq, Ord, PartialOrd, Copy, Default)]
219pub struct SnowFlake(pub i64);
220impl SnowFlake {
221 pub fn generate() -> Self {
222 ID_GENERATOR.generate().into()
223 }
224}
225
226impl Deref for SnowFlake {
227 type Target = i64;
228
229 fn deref(&self) -> &Self::Target {
230 &self.0
231 }
232}
233
234impl From<i64> for SnowFlake {
235 fn from(value: i64) -> Self {
236 Self(value)
237 }
238}
239
240impl From<SnowFlake> for String {
241 fn from(value: SnowFlake) -> Self {
242 value.0.to_string()
243 }
244}
245
246impl From<SnowFlake> for i64 {
247 fn from(value: SnowFlake) -> Self {
248 value.0
249 }
250}
251
252impl std::fmt::Display for SnowFlake {
253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 write!(f, "{}", self.0)
255 }
256}
257
258impl<'de> serde::Deserialize<'de> for SnowFlake {
259 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
260 where
261 D: serde::Deserializer<'de>,
262 {
263 struct SnowflakeVisitor;
264
265 impl<'de> Visitor<'de> for SnowflakeVisitor {
266 type Value = SnowFlake;
267
268 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
269 f.write_str("Snowflake as a number or string")
270 }
271
272 fn visit_i64<E>(self, id: i64) -> Result<Self::Value, E>
273 where
274 E: de::Error,
275 {
276 Ok(SnowFlake(id))
277 }
278
279 fn visit_u64<E>(self, id: u64) -> Result<Self::Value, E>
280 where
281 E: de::Error,
282 {
283 if id < i64::MAX as u64 {
284 Ok(SnowFlake(id.try_into().unwrap()))
285 } else {
286 Err(E::custom(format!("Snowflake out of range: {}", id)))
287 }
288 }
289
290 fn visit_str<E>(self, id: &str) -> Result<Self::Value, E>
291 where
292 E: de::Error,
293 {
294 match id.parse::<u64>() {
295 Ok(val) => self.visit_u64(val),
296 Err(_) => Err(E::custom("Failed to parse snowflake")),
297 }
298 }
299 }
300
301 deserializer.deserialize_any(SnowflakeVisitor)
302 }
303}
304
305impl Serialize for SnowFlake {
306 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307 where
308 S: Serializer,
309 {
310 let s = self.0.to_string();
312
313 serializer.serialize_str(&s)
315 }
316}
317
318#[test]
319fn test_generate() {
320 let id_generator = NumericalUniqueIdGenerator::new(1, 2);
321 let mut ids = Vec::with_capacity(10000);
322
323 for _ in 0..99 {
324 for _ in 0..10000 {
325 ids.push(id_generator.generate());
326 }
327
328 ids.sort();
329 ids.dedup();
330
331 assert_eq!(10000, ids.len());
332
333 ids.clear();
334 }
335}
336#[test]
337fn test_generate_not_sequential_value_when_sleep() {
338 let id_generator = NumericalUniqueIdGenerator::new(1, 2);
339 let first = id_generator.generate();
340
341 std::thread::sleep(std::time::Duration::from_millis(1));
342 let second = id_generator.generate();
343
344 assert!(first < second);
345 assert_ne!(first + 1, second);
346}
347
348#[test]
349fn test_singleton_generate() {
350 let id_generator = &ID_GENERATOR;
351 let mut ids = Vec::with_capacity(1000000);
352
353 for _ in 0..99 {
354 for _ in 0..1000000 {
355 ids.push(id_generator.generate());
356 }
357
358 assert_eq!(1000000, ids.len());
359 assert!(ids.first().unwrap() < ids.last().unwrap());
360 assert!(ids.get(999998).unwrap() < ids.get(999999).unwrap());
361
362 ids.clear();
363 }
364}