wd_sonyflake/
sonyflake.rs

1//! Sonyflake 雪花算法
2//! 结构
3//! |--闲置位--|--时间戳(ms)--|--标志--|--序号--|
4//! |-- 1位 --|---- 41位 -----|--10位--|--12位--|
5//!
6
7use std::sync::atomic::{AtomicU64, AtomicU32,Ordering};
8use chrono::Utc;
9use std::net::UdpSocket;
10
11pub struct SonyFlakeEntity{
12    time_stamp:AtomicU64,
13    counter:AtomicU32,
14    node_id:u16,
15}
16
17impl SonyFlakeEntity{
18    pub fn new(nodeid:u16)->Self{
19        SonyFlakeEntity{
20            time_stamp:AtomicU64::new(0),
21            counter:AtomicU32::new(0),
22            node_id:nodeid,
23        }
24    }
25    /// 根据ip地址设置节点id,如果获取失败则设置为1
26    pub fn new_default()->Self{
27        let mut nodeid = 1;
28        if let Some(s)=get_ip(){
29            let ips:Vec<_> = s.split('.').collect();
30            let a = ips[2].parse::<u8>().unwrap();
31            let b = ips[3].parse::<u8>().unwrap();
32            nodeid = u16::from_be_bytes([a,b]);
33        }
34        SonyFlakeEntity{
35            time_stamp:AtomicU64::new(0),
36            counter:AtomicU32::new(0),
37            node_id:nodeid,
38        }
39    }
40
41    pub fn get_id(&self)->i64{
42        let (ts,sid) = self.get_ts_sid();
43        return Self::generate_id(ts,sid,self.node_id);
44    }
45
46    #[allow(unused_assignments)]
47    fn get_ts_sid(&self)->(u64,u32){
48        let mut timestamp = 0;
49        let mut sequence:u32 = 0;
50        let ntime = Utc::now().timestamp_millis() as u64;
51        let otime = self.time_stamp.load(Ordering::Acquire);
52        if ntime <= otime{
53            sequence = self.counter.fetch_add(1,Ordering::Relaxed);
54            timestamp = otime; //self.time_stamp.load(Ordering::Release);
55        }else{
56            self.counter.store(1,Ordering::Relaxed);
57            timestamp = ntime;
58            self.time_stamp.store(ntime,Ordering::Release);
59        }
60        return (timestamp,sequence);
61    }
62    fn generate_id(ts:u64,sid:u32,nid:u16)->i64{
63        let mut res:Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0];
64        let ts = ts << 22;
65        let vts = Vec::from(ts.to_be_bytes());
66        for i in 0..6{
67            res[i] = res[i] | vts[i];
68        }
69        res[0] = res[0]&0x7F;
70        // let nid = nid << 4;
71        let mut vnid = Vec::from(nid.to_be_bytes());
72        vnid[0] = vnid[0] & 0x03;
73        res[5] = res[5]|vnid[0];
74        res[6] = res[6]|vnid[1];
75        let mut vsid = Vec::from(sid.to_be_bytes());
76        vsid[2] = vsid[2]&0x0F;
77        res[6] = res[6]|vsid[2];
78        res[7] = res[7]|vsid[3];
79        i64::from_be_bytes([res[0],res[1],res[2],res[3],res[4],res[5],res[6],res[7]])
80    }
81}
82
83pub fn get_ip() -> Option<String> {
84    let socket = match UdpSocket::bind("0.0.0.0:0") {
85        Ok(s) => s,
86        Err(_) => return None,
87    };
88
89    match socket.connect("8.8.8.8:80") {
90        Ok(()) => (),
91        Err(_) => return None,
92    };
93
94    match socket.local_addr() {
95        Ok(addr) => return Some(addr.ip().to_string()),
96        Err(_) => return None,
97    };
98}