分布式订单生成

#![allow(dead_code)]

macro_rules! MAX_FOR_BIT {
    ($bit:expr) => {
        !(u64::MAX << $bit)
    };
}

use std::sync::atomic::{AtomicU64, Ordering};

use chrono::{ Utc, DateTime};

trait GenValue {
    fn gen_value(&self, bit:u8) -> u64;
}

struct StaticVar(u64);
impl GenValue for StaticVar {
    fn gen_value(&self, bit:u8) -> u64 {
        self.0 
    }
}

struct TimeVar(DateTime<Utc>);
impl GenValue for TimeVar {
    fn gen_value(&self, bit:u8) -> u64 {
        let max = MAX_FOR_BIT!(bit);
        let now = Utc::now()-self.0;
        now.num_milliseconds() as u64 & max
    }
}

struct Cycle(AtomicU64);
impl GenValue for Cycle{
    fn gen_value(&self, bit:u8) -> u64 {
        let max = MAX_FOR_BIT!(bit);
        self.0.fetch_add(1, Ordering::SeqCst) & max
    }
}

struct Padding{
    var: Box<dyn GenValue + Sync + Send>,
    bit: u8
}

struct Snowflake{
    paddings: Vec<Padding> 
}

impl Snowflake {
    fn build() ->SnowflakeBuild{
        SnowflakeBuild::new()
    }
    fn gen(&self) ->u64{
        let mut ret = 0;
        let mut sum_bit = 0;
        self.paddings.iter().for_each(|item|{
            ret |= item.var.gen_value(item.bit) << sum_bit;
            sum_bit += item.bit as u64;
        });
        return ret;
    }
}

struct SnowflakeBuild{
    sum_bit: u8,
    paddings: Vec<Padding>,
}

impl SnowflakeBuild {
    fn new() ->SnowflakeBuild {
        SnowflakeBuild{ sum_bit:0, paddings:Vec::new() }
    }
    fn build(mut self) -> Snowflake{
        self.paddings.reverse();
        Snowflake{paddings: self.paddings}
    }
    fn with_padding(mut self, pad:Padding)-> Self{
        self.sum_bit = self.sum_bit + pad.bit;
        if self.sum_bit > 64{
            panic!("The bit is too long.")
        }
        self.paddings.push(pad);
        return self;
    }
    fn with_static(self, value:u64, bit:u8) -> Self{
        let max = MAX_FOR_BIT!(bit);
        self.with_padding(Padding { var: Box::new(StaticVar(value & max)), bit })
    }

    fn with_time(self, base:DateTime<Utc>, bit:u8) -> Self{
        self.with_padding(Padding { var: Box::new(TimeVar(base)), bit })
    }

    fn with_cycle(self, bit:u8) ->Self{
        self.with_padding(Padding{var:Box::new(Cycle(AtomicU64::new(0))), bit})
    }

}



#[cfg(test)]
mod test{
    use std::{thread::{self}, sync::Arc};

    use chrono::{Utc, TimeZone};

    #[allow(unused_imports)]
    use super::{StaticVar, GenValue,Snowflake};

    #[test]
    fn test(){
        let base = Utc.ymd(2022, 1, 1).and_hms(0, 0, 0);
        let snowflake = Snowflake::build()
            .with_static(20, 8)
            .with_time(base, 48)
            .with_cycle(8)
            .build();

        let snowflake = Arc::new(snowflake);
        let gen = Arc::clone(&snowflake);


        let t1 = thread::spawn(move ||{
            for _ in 0..10000{
                println!("{}", gen.gen())
            }
        });
        let gen = Arc::clone(&snowflake);
        let t2 = thread::spawn(move ||{
            for _ in 0..10000{
                println!("{}", gen.gen())
            }
        });
        let gen = Arc::clone(&snowflake);
        let t3 = thread::spawn(move ||{
            for _ in 0..10000{
                println!("{}", gen.gen())
            }
        });
        let gen = Arc::clone(&snowflake);
        let t4 = thread::spawn(move ||{
            for _ in 0..10000{
                println!("{}", gen.gen())
            }
        });

        t1.join().expect("Thread1 Error");t2.join().expect("Thread2 Error");
        t3.join().expect("Thread3 Error");t4.join().expect("Thread4 Error");

    }

}



本作品采用《CC 协议》,转载必须注明作者和本文链接
謎麟
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!