diff --git a/C#.NET/source/Yitter.IdGenTest/GenTest.cs b/C#.NET/source/Yitter.IdGenTest/GenTest.cs index 8113467301007664934eb716d55f0a088f310660..b5383c42f7b01d97f859f895284085305919c006 100644 --- a/C#.NET/source/Yitter.IdGenTest/GenTest.cs +++ b/C#.NET/source/Yitter.IdGenTest/GenTest.cs @@ -42,7 +42,7 @@ namespace Yitter.OrgSystem.TestA } DateTime end = DateTime.Now; - Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++WorkerId: {WorkerId}, total: {(end - start).TotalSeconds} s"); + Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++WorkerId: {WorkerId}, total: {(end - start).TotalMilliseconds} ms"); Interlocked.Increment(ref Program.Count); } } diff --git a/C#.NET/source/Yitter.IdGenTest/Program.cs b/C#.NET/source/Yitter.IdGenTest/Program.cs index 5106efd64cea2aef1b54022d31eff87706da6ca6..aff8cb5c79a3480fcf7eedeb0cdae962efe32efd 100644 --- a/C#.NET/source/Yitter.IdGenTest/Program.cs +++ b/C#.NET/source/Yitter.IdGenTest/Program.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading; using Yitter.IdGenerator; @@ -25,23 +26,24 @@ namespace Yitter.OrgSystem.TestA static void Main(string[] args) { + Console.WriteLine("Hello World! C#"); + var options = new IdGeneratorOptions() { Method = method, WorkerId = 1, - //TopOverCostCount = 2000, - //WorkerIdBitLength = 1, - //SeqBitLength = 2, + WorkerIdBitLength = 6, + SeqBitLength = 6, + TopOverCostCount = 2000, //MinSeqNumber = 1, - // MaxSeqNumber = 200, // BaseTime = DateTime.Now.AddYears(-10), }; - IIdGenerator IdGen = new DefaultIdGenerator(options); + IdGen = new DefaultIdGenerator(options); GenTest genTest = new GenTest(IdGen, genIdCount, options.WorkerId); // 首先测试一下 IdHelper 方法,获取单个Id @@ -52,10 +54,44 @@ namespace Yitter.OrgSystem.TestA while (true) { - Go(options); - Thread.Sleep(1000); // 每隔3秒执行一次Go - Console.WriteLine("Hello World! C#"); + RunSingle(); + // Go(options); + // RustDll(); + Thread.Sleep(1000); // 每隔1秒执行一次Go + } + } + + [DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)] + public static extern long NextId(); + + private static void RustDll() + { + int i = 0; + long id = 0; + DateTime start = DateTime.Now; + + while (i < 50000) + { + id = NextId(); + i++; + } + DateTime end = DateTime.Now; + Console.WriteLine("id:" + id); + Console.WriteLine($"+++++++++++C# call rust dll, gen 5W, total: {(end - start).TotalMilliseconds} ms"); + } + + private static void RunSingle() + { + DateTime start = DateTime.Now; + + for (int i = 0; i < genIdCount; i++) + { + var id = IdGen.NewLong(); } + + DateTime end = DateTime.Now; + Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++, total: {(end - start).TotalMilliseconds} ms"); + Interlocked.Increment(ref Program.Count); } private static void Go(IdGeneratorOptions options) diff --git a/C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs b/C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs index 80186787199b8f61b779defc8358ff08a75b1992..96b011bd5696408082ef2b4fd01ba2ac89797ada 100644 --- a/C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs +++ b/C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs @@ -332,7 +332,7 @@ namespace Yitter.IdGenerator public virtual long NextId() { - lock (_SyncLock) + lock (_SyncLock) { return _IsOverCost ? NextOverCostId() : NextNormalId(); } diff --git a/Java/source/src/main/java/com/yitter/test/GenTest.java b/Java/source/src/main/java/com/yitter/test/GenTest.java index c7d85f61f39b94fcdcccdb854af077921078f833..6a4647ce808c8332553ef3d0339836db4fa8f371 100644 --- a/Java/source/src/main/java/com/yitter/test/GenTest.java +++ b/Java/source/src/main/java/com/yitter/test/GenTest.java @@ -20,7 +20,6 @@ public class GenTest { public void GenStart() { long start = System.currentTimeMillis(); - long id = 0; for (int i = 0; i < GenIdCount; i++) { diff --git a/Java/source/src/main/java/com/yitter/test/StartUp.java b/Java/source/src/main/java/com/yitter/test/StartUp.java index 49f2a12598df43825d56a54ded4030888b503e47..248c25ddc6c93214fdd5aaadc5c44fab3a847ce8 100644 --- a/Java/source/src/main/java/com/yitter/test/StartUp.java +++ b/Java/source/src/main/java/com/yitter/test/StartUp.java @@ -22,11 +22,9 @@ public class StartUp { public static void main(String[] args) { IdGeneratorOptions options = new IdGeneratorOptions(); - - // options.TopOverCostCount = 10000; - - options.WorkerIdBitLength = 6; - options.SeqBitLength = 6; +// options.WorkerIdBitLength = 6; +// options.SeqBitLength = 6; +// options.TopOverCostCount = 2000; // options.MinSeqNumber = 5; // options.MaxSeqNumber = 200; diff --git a/Rust/source/Cargo.lock b/Rust/source/Cargo.lock index f67902a45f61922b0e25452b735031893658b4c5..6a8c0af06fc40455c843ae566e52ca2feb76a55e 100644 --- a/Rust/source/Cargo.lock +++ b/Rust/source/Cargo.lock @@ -1,13 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "RS-SnowF" -version = "1.0.0" -dependencies = [ - "chrono", - "lazy_static", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -96,3 +88,11 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "yitidgen" +version = "1.0.0" +dependencies = [ + "chrono", + "lazy_static", +] diff --git a/Rust/source/Cargo.toml b/Rust/source/Cargo.toml index e96c958ca29d7622ed2f8128b91007c9051eefbf..8664c2f47b50b6679e279a4193d4633cb5dcbcbe 100644 --- a/Rust/source/Cargo.toml +++ b/Rust/source/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "RS-SnowF" +name = "yitidgen" version = "1.0.0" authors = ["yitter "] edition = "2018" @@ -10,3 +10,7 @@ edition = "2018" chrono = "0.4.10" lazy_static = "1.4.0" +[lib] +name = "yitidgen" +path = "./src/lib.rs" +crate-type = ["cdylib"] diff --git a/Rust/source/src/lib.rs b/Rust/source/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..0924daedd96dbf27bbfd0daa2b7f7ab360a54d36 --- /dev/null +++ b/Rust/source/src/lib.rs @@ -0,0 +1,15 @@ +mod yitgen; +use yitgen::gen::YitIdHelper; +use yitgen::contract::*; + +// #[export_name = "SetIdGenerator"] +#[no_mangle] +pub extern "C" fn SetIdGenerator(options: IdGeneratorOptions) { + YitIdHelper::SetIdGenerator(options); +} + +#[no_mangle] +pub extern "C" fn NextId() -> i64 { + YitIdHelper::NextId() +} + diff --git a/Rust/source/src/main.rs b/Rust/source/src/main.rs index 7261534d3188f456033761518daa8e4b4f2f8fc8..88ab0ff56d6c97cd712fa49a0e6ef276f027870e 100644 --- a/Rust/source/src/main.rs +++ b/Rust/source/src/main.rs @@ -4,13 +4,17 @@ 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 times = 50000; + + // 是否启用多线程测试 + let multiThread = false; + // 全局设置一次运行参数 let mut options = IdGeneratorOptions::New(1); options.WorkerIdBitLength = 6; @@ -22,10 +26,9 @@ fn main() { loop { let mut i = 0; let mut id: i64 = 0; - let multiThread = false; let start = Utc::now().timestamp_millis(); - while i < 50000 { + while i < times { i += 1; if multiThread { // 这是多线程 thread::spawn(move || { @@ -44,7 +47,7 @@ fn main() { println!("单线程用时 {} ms", end - start); } - thread::sleep(std::time::Duration::from_millis(1000)); + thread::sleep(std::time::Duration::from_millis(2000)); } } diff --git a/Rust/source/src/yitgen/contract/id_generator_options.rs b/Rust/source/src/yitgen/contract/id_generator_options.rs index 164ec830670cc2e3e0eecc02094a49ef140d4683..ee47c1138ed567e527203a47488190a073fef5be 100644 --- a/Rust/source/src/yitgen/contract/id_generator_options.rs +++ b/Rust/source/src/yitgen/contract/id_generator_options.rs @@ -2,10 +2,6 @@ * 版权属于: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 @@ -13,7 +9,7 @@ pub struct IdGeneratorOptions { /// 基础时间,不能超过当前系统时间 pub BaseTime: i64, /// 机器码,与 WorkerIdBitLength 有关系 - pub WorkerId: u16, + pub WorkerId: u32, /// 机器码位长,范围:1-21(要求:序列数位长+机器码位长不超过22) pub WorkerIdBitLength: u8, /// 序列数位长,范围:2-21(要求:序列数位长+机器码位长不超过22) @@ -27,7 +23,7 @@ pub struct IdGeneratorOptions { } impl IdGeneratorOptions { - pub fn New(workerId: u16) -> IdGeneratorOptions { + pub fn New(workerId: u32) -> IdGeneratorOptions { return IdGeneratorOptions { Method: 1, WorkerId: workerId, diff --git a/Rust/source/src/yitgen/core/snow_worker_m1.rs b/Rust/source/src/yitgen/core/snow_worker_m1.rs index acfcda7cb4338787437a9b42df3f4a507c28796b..832c3249d2311f377130c979aa9831a643f4211c 100644 --- a/Rust/source/src/yitgen/core/snow_worker_m1.rs +++ b/Rust/source/src/yitgen/core/snow_worker_m1.rs @@ -5,18 +5,14 @@ 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 WorkerId: u32, ///机器码位长 pub WorkerIdBitLength: u8, ///自增序列数位长 @@ -69,7 +65,7 @@ impl SnowWorkerM1 { } // WorkerId - let maxWorkerIdNumber = (2 as u16).pow(options.WorkerIdBitLength as u32) - 1; + let maxWorkerIdNumber = (2 as u32).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 { @@ -133,6 +129,7 @@ impl SnowWorkerM1 { } pub fn NextId(&mut self) -> i64 { + // println!("SeqBitLength: {}", self.SeqBitLength); if self._IsOverCost { self.NextOverCostId() } else { self.NextNormalId() } } @@ -155,6 +152,7 @@ impl SnowWorkerM1 { if currentTimeTick > self._LastTimeTick { self.EndOverCostAction(currentTimeTick); + self._LastTimeTick = currentTimeTick; self._CurrentSeqNumber = self.MinSeqNumber; self._IsOverCost = false; @@ -166,6 +164,7 @@ impl SnowWorkerM1 { if self._OverCostCountInOneTerm >= self.TopOverCostCount { self.EndOverCostAction(currentTimeTick); + self._LastTimeTick = self.GetNextTimeTick(); self._CurrentSeqNumber = self.MinSeqNumber; self._IsOverCost = false; @@ -196,6 +195,7 @@ impl SnowWorkerM1 { if self._TurnBackTimeTick < 1 { self._TurnBackTimeTick = self._LastTimeTick - 1; self._TurnBackIndex += 1; + // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 // 最多4次回拨(防止回拨重叠) if self._TurnBackIndex > 4 { @@ -217,11 +217,13 @@ impl SnowWorkerM1 { 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; @@ -236,13 +238,17 @@ impl SnowWorkerM1 { } fn CalcId(&mut self, useTimeTick: i64) -> i64 { - let result = (useTimeTick << self._TimestampShift) + (self.WorkerId << self.SeqBitLength) as i64 + (self._CurrentSeqNumber) as 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; + let result = (useTimeTick << self._TimestampShift) + + (self.WorkerId << self.SeqBitLength) as i64 + + (self._TurnBackIndex) as i64; self._TurnBackTimeTick -= 1; return result; } diff --git a/Rust/source/src/yitgen/gen/yit_id_helper.rs b/Rust/source/src/yitgen/gen/yit_id_helper.rs index 24642a1688a8b0f9012a98302dccbd80725a501e..19bd4030d5b53948b9313ebb468ab07d6336f5d5 100644 --- a/Rust/source/src/yitgen/gen/yit_id_helper.rs +++ b/Rust/source/src/yitgen/gen/yit_id_helper.rs @@ -7,14 +7,13 @@ 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>> = None; impl YitIdHelper { + fn IdGenInstance() -> Arc> { unsafe { idGenInstance.get_or_insert_with(|| { @@ -23,14 +22,12 @@ impl YitIdHelper { } } - pub fn SetIdGenerator(options: IdGeneratorOptions) { let mut idgenArc = YitIdHelper::IdGenInstance(); let mut idgen = idgenArc.lock().unwrap(); idgen.Worker.SetOptions(options); } - #[no_mangle] pub fn NextId() -> i64 { let mut idgenArc = YitIdHelper::IdGenInstance(); let mut idgen = idgenArc.lock().unwrap(); diff --git a/tester/csharp_call_rust.png b/tester/csharp_call_rust.png new file mode 100644 index 0000000000000000000000000000000000000000..c5ae5b518f725d37b36c498ca2a2f1ece822f8c9 Binary files /dev/null and b/tester/csharp_call_rust.png differ