1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; use std::thread; use std::thread::JoinHandle; use std::time::SystemTime;
const EPOCH: u64 = 1735689600000; const DATA_CENTER_ID_BITS: u64 = 5; const MACHINE_ID_BITS: u64 = 5; const SEQUENCE_BITS: u64 = 12;
const MAX_DATA_CENTER_ID: u64 = (1 << DATA_CENTER_ID_BITS) - 1; const MAX_MACHINE_ID: u64 = (1 << MACHINE_ID_BITS) - 1; const MAX_SEQUENCE: u64 = (1 << SEQUENCE_BITS) - 1;
const MACHINE_ID_SHIFT: u64 = SEQUENCE_BITS; const DATA_CENTER_ID_SHIFT: u64 = SEQUENCE_BITS + MACHINE_ID_BITS; const TIMESTAMP_SHIFT: u64 = SEQUENCE_BITS + MACHINE_ID_BITS + DATA_CENTER_ID_BITS;
struct Snowflake { last_timestamp: AtomicU64, data_center_id: u64, machine_id: u64, sequence: AtomicU64, }
impl Snowflake { pub fn new(data_center_id: u64, machine_id: u64) -> Snowflake { if data_center_id > MAX_DATA_CENTER_ID { panic!("Data center ID exceeds the maximum value!"); } if machine_id > MAX_MACHINE_ID { panic!("Machine ID exceeds the maximum value!"); }
Snowflake { last_timestamp: AtomicU64::new(0), data_center_id, machine_id, sequence: AtomicU64::new(0), } }
pub fn next_id(&self) -> u64 { let mut timestamp = current_millis();
let last_timestamp = self.last_timestamp.load(Ordering::Relaxed);
if timestamp < last_timestamp { eprintln!( "Clock moved backwards. Refusing to generate ID for {} milliseconds.", last_timestamp - timestamp ); timestamp = last_timestamp; }
if timestamp == last_timestamp { let seq = self.sequence.fetch_add(1, Ordering::Relaxed) & MAX_SEQUENCE; if seq == 0 { timestamp = wait_next_millis(last_timestamp); self.sequence.store(0, Ordering::Relaxed); } } else { self.sequence.store(0, Ordering::Relaxed); }
self.last_timestamp.store(timestamp, Ordering::Relaxed);
((timestamp - EPOCH) << TIMESTAMP_SHIFT) | (self.data_center_id << DATA_CENTER_ID_SHIFT) | (self.machine_id << MACHINE_ID_SHIFT) | self.sequence.load(Ordering::Relaxed) } }
fn current_millis() -> u64 { SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap() .as_millis() as u64 }
fn wait_next_millis(last_timestamp: u64) -> u64 { let mut timestamp = current_millis(); while timestamp <= last_timestamp { timestamp = current_millis(); } timestamp }
fn main() { let snowflake = Arc::new(Snowflake::new(1, 1));
let handlers: Vec<_> = (0..10) .map(|_| { let snowflake = snowflake.clone(); thread::spawn(move || { for _ in 0..10 { let id = snowflake.next_id(); println!("Generate ID: {}", id); } }) }) .collect(); for h in handlers { h.join().unwrap(); } }
|