Browse Source

commitRust

tags/v1.0.0
zhouzj 4 years ago
parent
commit
691d80a513
15 changed files with 592 additions and 2 deletions
  1. +1
    -2
      Rust/source/.gitignore
  2. +98
    -0
      Rust/source/Cargo.lock
  3. +12
    -0
      Rust/source/Cargo.toml
  4. +51
    -0
      Rust/source/src/main.rs
  5. +7
    -0
      Rust/source/src/yitgen/contract/i_snow_worker.rs
  6. +42
    -0
      Rust/source/src/yitgen/contract/id_generator_options.rs
  7. +13
    -0
      Rust/source/src/yitgen/contract/mod.rs
  8. +12
    -0
      Rust/source/src/yitgen/contract/over_cost_action_arg.rs
  9. +10
    -0
      Rust/source/src/yitgen/core/mod.rs
  10. +263
    -0
      Rust/source/src/yitgen/core/snow_worker_m1.rs
  11. +9
    -0
      Rust/source/src/yitgen/core/snow_worker_m2.rs
  12. +25
    -0
      Rust/source/src/yitgen/gen/default_id_generator.rs
  13. +9
    -0
      Rust/source/src/yitgen/gen/mod.rs
  14. +37
    -0
      Rust/source/src/yitgen/gen/yit_id_helper.rs
  15. +3
    -0
      Rust/source/src/yitgen/mod.rs

+ 1
- 2
Rust/source/.gitignore View File

@@ -39,7 +39,6 @@ TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
@@ -252,7 +251,7 @@ paket-files/
# JetBrains Rider
.idea/
*.sln.iml
target/

# macOS
.DS_Store

+ 98
- 0
Rust/source/Cargo.lock View File

@@ -0,0 +1,98 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "RS-SnowF"
version = "0.1.0"
dependencies = [
"chrono",
"lazy_static",
]

[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"

[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]

[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"

[[package]]
name = "libc"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"

[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]

[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]

[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]

[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"

[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]

[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"

[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

+ 12
- 0
Rust/source/Cargo.toml View File

@@ -0,0 +1,12 @@
[package]
name = "RS-SnowF"
version = "0.1.0"
authors = ["zhouzj <zhouzj@zhouzj.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
chrono = "0.4.10"
lazy_static = "1.4.0"


+ 51
- 0
Rust/source/src/main.rs View File

@@ -0,0 +1,51 @@
mod yitgen;

use yitgen::contract::*;
use yitgen::gen::*;
use std::thread;
use chrono::Utc;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::ops::Deref;

fn main() {
println!("Hello, world! Rust");

// 全局设置一次运行参数
let mut options = IdGeneratorOptions::New(1);
options.WorkerId = 1;
options.WorkerIdBitLength = 1;
options.SeqBitLength = 6;
//... 可以继续设置其它 options 参数
YitIdHelper::SetIdGenerator(options);

// 以下开始测试生成数据,默认5W,单线程,可以修改 multiThread=true 启用多线程。
loop {
let mut i = 0;
let mut id: i64 = 0;
let multiThread = false;
let start = Utc::now().timestamp_millis();

while i < 50000 {
i += 1;
if multiThread { // 这是多线程
thread::spawn(move || {
id = YitIdHelper::NextId();
println!("{}, id: {}", i, id);
});
} else { // 这是单线程
id = YitIdHelper::NextId();
}
}

println!("最后生成的id: {}", id);
if !multiThread {
// 多线程情况下,时间统计不准确
let end = Utc::now().timestamp_millis();
println!("单线程用时 {} ms", end - start);
}

thread::sleep(std::time::Duration::from_millis(1000));
}
}


+ 7
- 0
Rust/source/src/yitgen/contract/i_snow_worker.rs View File

@@ -0,0 +1,7 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
pub trait ISnowWorker {
fn NextId(&self) -> u64;
}

+ 42
- 0
Rust/source/src/yitgen/contract/id_generator_options.rs View File

@@ -0,0 +1,42 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
use std::{thread, time};
use std::net::UdpSocket;
use std::sync::{Arc, Mutex};
use chrono::Utc;

pub struct IdGeneratorOptions {
/// 雪花计算方法,(1-漂移算法|2-传统算法),默认1
pub Method: u8,
/// 基础时间,不能超过当前系统时间
pub BaseTime: i64,
/// 机器码,与 WorkerIdBitLength 有关系
pub WorkerId: u16,
/// 机器码位长,范围:1-21(要求:序列数位长+机器码位长不超过22)
pub WorkerIdBitLength: u8,
/// 序列数位长,范围:2-21(要求:序列数位长+机器码位长不超过22)
pub SeqBitLength: u8,
/// 最大序列数(含),(由 SeqBitLength 计算的最大值)
pub MaxSeqNumber: u32,
/// 最小序列数(含),默认5,不小于1,不大于 MaxSeqNumber
pub MinSeqNumber: u32,
/// 最大漂移次数(含),默认2000,推荐范围 500-20000(与计算能力有关)
pub TopOverCostCount: u32,
}

impl IdGeneratorOptions {
pub fn New(workerId: u16) -> IdGeneratorOptions {
return IdGeneratorOptions {
Method: 1,
WorkerId: workerId,
BaseTime: 1582136402000,
WorkerIdBitLength: 6,
SeqBitLength: 6,
MaxSeqNumber: 0,
MinSeqNumber: 5,
TopOverCostCount: 2000,
};
}
}

+ 13
- 0
Rust/source/src/yitgen/contract/mod.rs View File

@@ -0,0 +1,13 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
mod id_generator_options;
mod i_snow_worker;
mod over_cost_action_arg;
pub use id_generator_options::IdGeneratorOptions;
pub use i_snow_worker::ISnowWorker;
pub use over_cost_action_arg::OverCostActionArg;

+ 12
- 0
Rust/source/src/yitgen/contract/over_cost_action_arg.rs View File

@@ -0,0 +1,12 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
pub struct OverCostActionArg {
ActionType: u32,
TimeTick: u64,
WorkerId: u16,
OverCostCountInOneTerm: u32,
GenCountInOneTerm: u32,
TermIndex: u32,
}

+ 10
- 0
Rust/source/src/yitgen/core/mod.rs View File

@@ -0,0 +1,10 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
mod snow_worker_m1;
mod snow_worker_m2;
pub use snow_worker_m1::SnowWorkerM1;
pub use snow_worker_m2::SnowWorkerM2;

+ 263
- 0
Rust/source/src/yitgen/core/snow_worker_m1.rs View File

@@ -0,0 +1,263 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
use super::super::contract::*;
use std::{thread};
use chrono::Utc;
use std::sync::Mutex;
use std::sync::Arc;
use std::ops::Add;
use std::thread::sleep;
use std::sync::mpsc::channel;
use lazy_static::lazy_static;
pub struct SnowWorkerM1 {
///基础时间
pub BaseTime: i64,
///机器码
pub WorkerId: u16,
///机器码位长
pub WorkerIdBitLength: u8,
///自增序列数位长
pub SeqBitLength: u8,
///最大序列数(含)
pub MaxSeqNumber: u32,
///最小序列数(含)
pub MinSeqNumber: u32,
///最大漂移次数
pub TopOverCostCount: u32,
_TimestampShift: u8,
_CurrentSeqNumber: u32,
_LastTimeTick: i64,
_TurnBackTimeTick: i64,
_TurnBackIndex: u8,
_IsOverCost: bool,
_OverCostCountInOneTerm: u32,
_GenCountInOneTerm: u32,
_TermIndex: u32,
}
impl SnowWorkerM1 {
pub fn Default() -> SnowWorkerM1 {
let options = IdGeneratorOptions::New(1);
return SnowWorkerM1::New(options);
}
pub fn SetOptions(&mut self, options: IdGeneratorOptions) {
// BaseTime
if options.BaseTime == 0 {
self.BaseTime = 1582136402000;
} else if options.BaseTime < 631123200000 || options.BaseTime > Utc::now().timestamp_millis() {
panic!("BaseTime error.")
} else {
self.BaseTime = options.BaseTime;
}
// WorkerIdBitLength
if options.WorkerIdBitLength <= 0
{
panic!("WorkerIdBitLength error.(range:[1, 21])");
}
if options.SeqBitLength + options.WorkerIdBitLength > 22 {
panic!("error:WorkerIdBitLength + SeqBitLength <= 22")
} else {
self.WorkerIdBitLength = options.WorkerIdBitLength;
// self.WorkerIdBitLength = if options.WorkerIdBitLength == 0 { 6 } else { options.WorkerIdBitLength };
}
// WorkerId
let maxWorkerIdNumber = (2 as u16).pow(options.WorkerIdBitLength as u32) - 1;
if options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber {
panic!("WorkerId error. (range:[0, {} ]", if maxWorkerIdNumber <= 0 { 63 } else { maxWorkerIdNumber })
} else {
self.WorkerId = options.WorkerId;
}
// SeqBitLength
if options.SeqBitLength < 2 || options.SeqBitLength > 21 {
panic!("SeqBitLength error. (range:[2, 21])")
} else {
self.SeqBitLength = options.SeqBitLength;
// self.SeqBitLength = if options.SeqBitLength == 0 { 6 } else { options.SeqBitLength };
}
// MaxSeqNumber
let maxSeqNumber = (2 as u32).pow(options.SeqBitLength as u32) - 1;
if options.MaxSeqNumber > maxSeqNumber {
panic!("MaxSeqNumber error. (range:[1, {}]", maxSeqNumber)
} else {
self.MaxSeqNumber = if options.MaxSeqNumber <= 0 { (2 as u32).pow(options.SeqBitLength as u32) - 1 } else { options.MaxSeqNumber };
}
// MinSeqNumber
if options.MinSeqNumber > maxSeqNumber {
panic!("MinSeqNumber error. (range:[1, {}]", maxSeqNumber)
} else {
self.MinSeqNumber = options.MinSeqNumber;
}
self.TopOverCostCount = if options.TopOverCostCount == 0 { 2000 } else { options.TopOverCostCount };
self._TimestampShift = options.WorkerIdBitLength + options.SeqBitLength;
self._CurrentSeqNumber = options.MinSeqNumber;
if options.Method == 1 {
sleep(std::time::Duration::from_millis(500))
}
}
pub fn New(options: IdGeneratorOptions) -> SnowWorkerM1 {
let mut worker = SnowWorkerM1 {
BaseTime: 1582136402000,
WorkerId: 0,
WorkerIdBitLength: 0,
SeqBitLength: 0,
MaxSeqNumber: 0,
MinSeqNumber: 0,
TopOverCostCount: 0,
_TimestampShift: 0,
_CurrentSeqNumber: 0,
_LastTimeTick: 0,
_TurnBackTimeTick: 0,
_TurnBackIndex: 0,
_IsOverCost: false,
_OverCostCountInOneTerm: 0,
_GenCountInOneTerm: 0,
_TermIndex: 0,
};
worker.SetOptions(options);
return worker;
}
pub fn NextId(&mut self) -> i64 {
if self._IsOverCost { self.NextOverCostId() } else { self.NextNormalId() }
}
fn DoGenIdAction(&self, arg: OverCostActionArg) {}
fn BeginOverCostAction(&self, useTimeTick: i64) {}
fn EndOverCostAction(&mut self, useTimeTick: i64) {
if self._TermIndex > 10000 {
self._TermIndex = 0;
}
}
fn BeginTurnBackAction(&self, useTimeTick: i64) {}
fn EndTurnBackAction(&self, useTimeTick: i64) {}
fn NextOverCostId(&mut self) -> i64 {
let currentTimeTick = self.GetCurrentTimeTick();
if currentTimeTick > self._LastTimeTick {
self.EndOverCostAction(currentTimeTick);
self._LastTimeTick = currentTimeTick;
self._CurrentSeqNumber = self.MinSeqNumber;
self._IsOverCost = false;
self._OverCostCountInOneTerm = 0;
self._GenCountInOneTerm = 0;
return self.CalcId(self._LastTimeTick);
}
if self._OverCostCountInOneTerm >= self.TopOverCostCount {
self.EndOverCostAction(currentTimeTick);
self._LastTimeTick = self.GetNextTimeTick();
self._CurrentSeqNumber = self.MinSeqNumber;
self._IsOverCost = false;
self._OverCostCountInOneTerm = 0;
self._GenCountInOneTerm = 0;
return self.CalcId(self._LastTimeTick);
}
if self._CurrentSeqNumber > self.MaxSeqNumber {
self._LastTimeTick += 1;
self._CurrentSeqNumber = self.MinSeqNumber;
self._IsOverCost = true;
self._OverCostCountInOneTerm += 1;
self._GenCountInOneTerm += 1;
return self.CalcId(self._LastTimeTick);
}
self._GenCountInOneTerm += 1;
return self.CalcId(self._LastTimeTick);
}
fn NextNormalId(&mut self) -> i64 {
let currentTimeTick = self.GetCurrentTimeTick();
if currentTimeTick < self._LastTimeTick {
if self._TurnBackTimeTick < 1 {
self._TurnBackTimeTick = self._LastTimeTick - 1;
self._TurnBackIndex += 1;
// 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
// 最多4次回拨(防止回拨重叠)
if self._TurnBackIndex > 4 {
self._TurnBackIndex = 1;
}
self.BeginTurnBackAction(self._TurnBackTimeTick);
}
thread::sleep(std::time::Duration::from_millis(10));
return self.CalcTurnBackId(self._TurnBackTimeTick);
}
// 时间追平时,_TurnBackTimeTick清零
if self._TurnBackTimeTick > 0 {
self.EndTurnBackAction(self._TurnBackTimeTick);
self._TurnBackTimeTick = 0;
}
if currentTimeTick > self._LastTimeTick {
self._LastTimeTick = currentTimeTick;
self._CurrentSeqNumber = self.MinSeqNumber;
return self.CalcId(self._LastTimeTick);
}
if self._CurrentSeqNumber > self.MaxSeqNumber {
self.BeginOverCostAction(currentTimeTick);
self._TermIndex += 1;
self._LastTimeTick += 1;
self._CurrentSeqNumber = self.MinSeqNumber;
self._IsOverCost = true;
self._OverCostCountInOneTerm = 1;
self._GenCountInOneTerm = 1;
return self.CalcId(self._LastTimeTick);
}
return self.CalcId(self._LastTimeTick);
}
fn CalcId(&mut self, useTimeTick: i64) -> i64 {
let result = (useTimeTick << self._TimestampShift) + (self.WorkerId << self.SeqBitLength) as i64 + (self._CurrentSeqNumber) as i64;
self._CurrentSeqNumber += 1;
return result;
}
fn CalcTurnBackId(&mut self, useTimeTick: i64) -> i64 {
let result = (useTimeTick << self._TimestampShift) + (self.WorkerId << self.SeqBitLength) as i64 + (self._TurnBackIndex) as i64;
self._TurnBackTimeTick -= 1;
return result;
}
fn GetCurrentTimeTick(&self) -> i64 {
return Utc::now().timestamp_millis() - self.BaseTime;
}
fn GetNextTimeTick(&self) -> i64 {
let mut tempTimeTicker = self.GetCurrentTimeTick();
while tempTimeTicker <= self._LastTimeTick {
tempTimeTicker = self.GetCurrentTimeTick();
}
return tempTimeTicker;
}
}

+ 9
- 0
Rust/source/src/yitgen/core/snow_worker_m2.rs View File

@@ -0,0 +1,9 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
use super::super::contract::ISnowWorker;
pub struct SnowWorkerM2 {
}

+ 25
- 0
Rust/source/src/yitgen/gen/default_id_generator.rs View File

@@ -0,0 +1,25 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
use std::{thread, time};
use std::net::UdpSocket;
use chrono::Utc;
use super::super::contract::*;
use super::super::core::*;
use super::*;
use std::sync::Mutex;
use std::sync::Arc;
use std::borrow::BorrowMut;

static mut instance2: Option<Arc<Mutex<SnowWorkerM1>>> = None;

pub struct DefaultIdGenerator {
pub Worker: SnowWorkerM1,
}

impl DefaultIdGenerator {
pub fn Default() -> DefaultIdGenerator {
DefaultIdGenerator { Worker: SnowWorkerM1::Default() }
}
}

+ 9
- 0
Rust/source/src/yitgen/gen/mod.rs View File

@@ -0,0 +1,9 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
mod default_id_generator;
mod yit_id_helper;
pub use yit_id_helper::YitIdHelper;
pub use default_id_generator::DefaultIdGenerator;

+ 37
- 0
Rust/source/src/yitgen/gen/yit_id_helper.rs View File

@@ -0,0 +1,37 @@
/*
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://gitee.com/yitter/idgenerator
*/
use super::super::contract::*;
use super::super::core::*;
use super::*;
use std::sync::Mutex;
use std::sync::Arc;
use lazy_static::lazy_static;
pub struct YitIdHelper;
static mut idGenInstance: Option<Arc<Mutex<DefaultIdGenerator>>> = None;
impl YitIdHelper {
fn IdGenInstance() -> Arc<Mutex<DefaultIdGenerator>> {
unsafe {
idGenInstance.get_or_insert_with(|| {
Arc::new(Mutex::new(DefaultIdGenerator::Default()))
}).clone()
}
}
pub fn SetIdGenerator(options: IdGeneratorOptions) {
let mut idgenArc = YitIdHelper::IdGenInstance();
let mut idgen = idgenArc.lock().unwrap();
idgen.Worker.SetOptions(options);
}
pub fn NextId() -> i64 {
let mut idgenArc = YitIdHelper::IdGenInstance();
let mut idgen = idgenArc.lock().unwrap();
idgen.Worker.NextId()
}
}

+ 3
- 0
Rust/source/src/yitgen/mod.rs View File

@@ -0,0 +1,3 @@
pub mod contract;
pub mod core;
pub mod gen;

Loading…
Cancel
Save