@@ -39,7 +39,6 @@ TestResult.xml | |||||
# Build Results of an ATL Project | # Build Results of an ATL Project | ||||
[Dd]ebugPS/ | [Dd]ebugPS/ | ||||
[Rr]eleasePS/ | [Rr]eleasePS/ | ||||
dlldata.c | |||||
# DNX | # DNX | ||||
project.lock.json | project.lock.json | ||||
@@ -252,7 +251,7 @@ paket-files/ | |||||
# JetBrains Rider | # JetBrains Rider | ||||
.idea/ | .idea/ | ||||
*.sln.iml | *.sln.iml | ||||
target/ | |||||
# macOS | # macOS | ||||
.DS_Store | .DS_Store |
@@ -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" |
@@ -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" | |||||
@@ -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)); | |||||
} | |||||
} | |||||
@@ -0,0 +1,7 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
pub trait ISnowWorker { | |||||
fn NextId(&self) -> u64; | |||||
} |
@@ -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, | |||||
}; | |||||
} | |||||
} |
@@ -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; | |||||
@@ -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, | |||||
} |
@@ -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; | |||||
@@ -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; | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
use super::super::contract::ISnowWorker; | |||||
pub struct SnowWorkerM2 { | |||||
} |
@@ -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() } | |||||
} | |||||
} |
@@ -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; |
@@ -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() | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
pub mod contract; | |||||
pub mod core; | |||||
pub mod gen; |