| @@ -12,7 +12,7 @@ namespace Yitter.OrgSystem.TestA | |||
| class Program | |||
| { | |||
| // 测试参数(默认配置下,最佳性能是10W/s) | |||
| static int genIdCount = 50000;//5000; // 计算ID数量(如果要验证50W效率,请将TopOverCostCount设置为2000或适当增加SeqBitLength) | |||
| static int genIdCount = 500000;//5000; // 计算ID数量(如果要验证50W效率,请将TopOverCostCount设置为2000或适当增加SeqBitLength) | |||
| static short method = 1; // 1-漂移算法,2-传统算法 | |||
| @@ -139,7 +139,7 @@ namespace Yitter.OrgSystem.TestA | |||
| Method = 1, | |||
| WorkerId = 1, | |||
| //WorkerIdBitLength = 6, | |||
| WorkerIdBitLength = 6, | |||
| SeqBitLength = 6, | |||
| //TopOverCostCount = 2000, | |||
| @@ -153,7 +153,7 @@ namespace Yitter.OrgSystem.TestA | |||
| //IdGen = new DefaultIdGenerator(options); | |||
| YitIdHelper.SetIdGenerator(options); | |||
| genIdCount = 50000; | |||
| while (true) | |||
| { | |||
| DateTime start = DateTime.Now; | |||
| @@ -165,7 +165,7 @@ namespace Yitter.OrgSystem.TestA | |||
| } | |||
| DateTime end = DateTime.Now; | |||
| Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++, total: {(end - start).TotalMilliseconds} ms"); | |||
| Console.WriteLine($"GenCount: {genIdCount}, TimeLength: {(end - start).TotalMilliseconds} ms"); | |||
| Thread.Sleep(1000); | |||
| } | |||
| //Interlocked.Increment(ref Program.Count); | |||
| @@ -60,17 +60,19 @@ namespace Yitter.IdGenerator | |||
| protected long _LastTimeTick = 0; // -1L | |||
| protected long _TurnBackTimeTick = 0; // -1L; | |||
| protected byte _TurnBackIndex = 0; | |||
| protected bool _IsOverCost = false; | |||
| protected int _OverCostCountInOneTerm = 0; | |||
| #if DEBUG | |||
| protected int _GenCountInOneTerm = 0; | |||
| protected int _TermIndex = 0; | |||
| #endif | |||
| public Action<OverCostActionArg> GenAction { get; set; } | |||
| //private static long _StartTimeTick = 0; | |||
| //private static long _BaseTimeTick = 0; | |||
| public Action<OverCostActionArg> GenAction { get; set; } | |||
| public SnowWorkerM1(IdGeneratorOptions options) | |||
| { | |||
| @@ -130,9 +132,10 @@ namespace Yitter.IdGenerator | |||
| //_StartTimeTick = (long)(DateTime.UtcNow.Subtract(BaseTime).TotalMilliseconds) - Environment.TickCount; | |||
| } | |||
| #if DEBUG | |||
| private void DoGenIdAction(OverCostActionArg arg) | |||
| { | |||
| //return; | |||
| Task.Run(() => | |||
| { | |||
| GenAction(arg); | |||
| @@ -141,8 +144,6 @@ namespace Yitter.IdGenerator | |||
| private void BeginOverCostAction(in long useTimeTick) | |||
| { | |||
| return; | |||
| if (GenAction == null) | |||
| { | |||
| return; | |||
| @@ -159,11 +160,10 @@ namespace Yitter.IdGenerator | |||
| private void EndOverCostAction(in long useTimeTick) | |||
| { | |||
| if (_TermIndex > 10000) | |||
| { | |||
| _TermIndex = 0; | |||
| } | |||
| return; | |||
| //if (_TermIndex > 10000) | |||
| //{ | |||
| // _TermIndex = 0; | |||
| //} | |||
| if (GenAction == null) | |||
| { | |||
| @@ -181,8 +181,6 @@ namespace Yitter.IdGenerator | |||
| private void BeginTurnBackAction(in long useTimeTick) | |||
| { | |||
| return; | |||
| if (GenAction == null) | |||
| { | |||
| return; | |||
| @@ -199,8 +197,6 @@ namespace Yitter.IdGenerator | |||
| private void EndTurnBackAction(in long useTimeTick) | |||
| { | |||
| return; | |||
| if (GenAction == null) | |||
| { | |||
| return; | |||
| @@ -214,6 +210,7 @@ namespace Yitter.IdGenerator | |||
| 0, | |||
| _TurnBackIndex)); | |||
| } | |||
| #endif | |||
| protected virtual long NextOverCostId() | |||
| { | |||
| @@ -221,44 +218,50 @@ namespace Yitter.IdGenerator | |||
| if (currentTimeTick > _LastTimeTick) | |||
| { | |||
| #if DEBUG | |||
| EndOverCostAction(currentTimeTick); | |||
| _GenCountInOneTerm = 0; | |||
| #endif | |||
| _LastTimeTick = currentTimeTick; | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = false; | |||
| _OverCostCountInOneTerm = 0; | |||
| _GenCountInOneTerm = 0; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| if (_OverCostCountInOneTerm >= TopOverCostCount) | |||
| { | |||
| #if DEBUG | |||
| EndOverCostAction(currentTimeTick); | |||
| // TODO: 在漂移终止,等待时间对齐时,如果发生时间回拨较长,则此处可能等待较长时间。可优化为:在漂移终止时增加时间回拨应对逻辑。(该情况发生概率很低) | |||
| _GenCountInOneTerm = 0; | |||
| #endif | |||
| // TODO: 在漂移终止,等待时间对齐时,如果发生时间回拨较长,则此处可能等待较长时间。可优化为:在漂移终止时增加时间回拨应对逻辑。(该情况发生概率低,暂不处理) | |||
| _LastTimeTick = GetNextTimeTick(); | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = false; | |||
| _OverCostCountInOneTerm = 0; | |||
| _GenCountInOneTerm = 0; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| if (_CurrentSeqNumber > MaxSeqNumber) | |||
| { | |||
| #if DEBUG | |||
| _GenCountInOneTerm++; | |||
| #endif | |||
| _LastTimeTick++; | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = true; | |||
| _OverCostCountInOneTerm++; | |||
| _GenCountInOneTerm++; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| #if DEBUG | |||
| _GenCountInOneTerm++; | |||
| #endif | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| @@ -271,16 +274,17 @@ namespace Yitter.IdGenerator | |||
| if (_TurnBackTimeTick < 1) | |||
| { | |||
| _TurnBackTimeTick = _LastTimeTick - 1; | |||
| _TurnBackIndex++; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if (_TurnBackIndex > 4) | |||
| { | |||
| _TurnBackIndex = 1; | |||
| } | |||
| #if DEBUG | |||
| BeginTurnBackAction(_TurnBackTimeTick); | |||
| #endif | |||
| } | |||
| _TurnBackIndex++; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if (_TurnBackIndex > 4) | |||
| { | |||
| _TurnBackIndex = 1; | |||
| } | |||
| //Thread.Sleep(1); | |||
| @@ -290,7 +294,9 @@ namespace Yitter.IdGenerator | |||
| // 时间追平时,_TurnBackTimeTick清零 | |||
| if (_TurnBackTimeTick > 0) | |||
| { | |||
| #if DEBUG | |||
| EndTurnBackAction(_TurnBackTimeTick); | |||
| #endif | |||
| _TurnBackTimeTick = 0; | |||
| } | |||
| @@ -304,14 +310,15 @@ namespace Yitter.IdGenerator | |||
| if (_CurrentSeqNumber > MaxSeqNumber) | |||
| { | |||
| #if DEBUG | |||
| BeginOverCostAction(currentTimeTick); | |||
| _TermIndex++; | |||
| _GenCountInOneTerm = 1; | |||
| #endif | |||
| _OverCostCountInOneTerm = 1; | |||
| _LastTimeTick++; | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = true; | |||
| _OverCostCountInOneTerm = 1; | |||
| _GenCountInOneTerm = 1; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| @@ -351,7 +358,8 @@ namespace Yitter.IdGenerator | |||
| while (tempTimeTicker <= _LastTimeTick) | |||
| { | |||
| Thread.Sleep(1); | |||
| //Thread.Sleep(1); | |||
| SpinWait.SpinUntil(() => false, 1); | |||
| tempTimeTicker = GetCurrentTimeTick(); | |||
| } | |||
| @@ -18,10 +18,11 @@ | |||
| <Copyright>Yitter</Copyright> | |||
| <PackageProjectUrl>https://github.com/yitter/idgenerator</PackageProjectUrl> | |||
| <PackageLicenseExpression>MIT</PackageLicenseExpression> | |||
| <Version>1.0.14</Version> | |||
| <Version>1.0.15</Version> | |||
| <PackageReleaseNotes></PackageReleaseNotes> | |||
| <AssemblyVersion>1.0.0.*</AssemblyVersion> | |||
| <FileVersion>1.0.0.*</FileVersion> | |||
| <AssemblyVersion>1.0.0.15</AssemblyVersion> | |||
| <FileVersion>1.0.0.15</FileVersion> | |||
| <RepositoryUrl>http://www.github.com/yitter/idgenerator</RepositoryUrl> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | |||
| @@ -69,10 +69,11 @@ static inline int64_t NextNormalId(SnowFlakeWorker *worker) { | |||
| if (currentTimeTick < worker->_LastTimeTick) { | |||
| if (worker->_TurnBackTimeTick < 1) { | |||
| worker->_TurnBackTimeTick = worker->_LastTimeTick - 1; | |||
| worker->_TurnBackIndex++; | |||
| if (worker->_TurnBackIndex > 4) { | |||
| worker->_TurnBackIndex = 1; | |||
| } | |||
| } | |||
| worker->_TurnBackIndex++; | |||
| if (worker->_TurnBackIndex > 4) { | |||
| worker->_TurnBackIndex = 1; | |||
| } | |||
| // usleep(1000); // 暂停1ms | |||
| @@ -170,15 +170,16 @@ func (m1 *SnowWorkerM1) NextNormalId() int64 { | |||
| if currentTimeTick < m1._LastTimeTick { | |||
| if m1._TurnBackTimeTick < 1 { | |||
| m1._TurnBackTimeTick = m1._LastTimeTick - 1 | |||
| m1._TurnBackIndex++ | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if m1._TurnBackIndex > 4 { | |||
| m1._TurnBackIndex = 1 | |||
| } | |||
| m1.BeginTurnBackAction(m1._TurnBackTimeTick) | |||
| } | |||
| m1._TurnBackIndex++ | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if m1._TurnBackIndex > 4 { | |||
| m1._TurnBackIndex = 1 | |||
| } | |||
| // time.Sleep(time.Duration(1) * time.Millisecond) | |||
| return m1.CalcTurnBackId(m1._TurnBackTimeTick) | |||
| } | |||
| @@ -141,16 +141,16 @@ public class SnowWorkerM1 implements ISnowWorker { | |||
| if (currentTimeTick < _LastTimeTick) { | |||
| if (_TurnBackTimeTick < 1) { | |||
| _TurnBackTimeTick = _LastTimeTick - 1; | |||
| _TurnBackIndex++; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if (_TurnBackIndex > 4) { | |||
| _TurnBackIndex = 1; | |||
| } | |||
| BeginTurnBackAction(_TurnBackTimeTick); | |||
| } | |||
| _TurnBackIndex++; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if (_TurnBackIndex > 4) { | |||
| _TurnBackIndex = 1; | |||
| } | |||
| // try { | |||
| // Thread.sleep(1); | |||
| // } catch (InterruptedException e) { | |||
| @@ -136,16 +136,19 @@ class Genid { | |||
| if (currentTimeTick < this._LastTimeTick) { | |||
| if (this._TurnBackTimeTick < 1) { | |||
| this._TurnBackTimeTick = this._LastTimeTick - 1; | |||
| this._TurnBackIndex++; | |||
| // 每毫秒序列数的前 5 位是预留位,0 用于手工新值,1-4 是时间回拨次序 | |||
| // 支持 4 次回拨次序(避免回拨重叠导致 ID 重复),可无限次回拨(次序循环使用)。 | |||
| if (this._TurnBackIndex > 4) { | |||
| this._TurnBackIndex = 1; | |||
| } | |||
| this.BeginTurnBackAction(this._TurnBackTimeTick); | |||
| } | |||
| this._TurnBackIndex++; | |||
| // 每毫秒序列数的前 5 位是预留位,0 用于手工新值,1-4 是时间回拨次序 | |||
| // 支持 4 次回拨次序(避免回拨重叠导致 ID 重复),可无限次回拨(次序循环使用)。 | |||
| if (this._TurnBackIndex > 4) { | |||
| this._TurnBackIndex = 1; | |||
| } | |||
| return this.CalcTurnBackId(this._TurnBackTimeTick); | |||
| } | |||
| // 时间追平时,_TurnBackTimeTick 清零 | |||
| if (this._TurnBackTimeTick > 0) { | |||
| this.EndTurnBackAction(this._TurnBackTimeTick); | |||
| @@ -178,12 +178,14 @@ static inline uint64_t NextNormalId(snowflake *flake) | |||
| if (flake->_TurnBackTimeTick < 1) | |||
| { | |||
| flake->_TurnBackTimeTick = flake->_LastTimeTick - 1; | |||
| flake->_TurnBackIndex++; | |||
| if (flake->_TurnBackIndex > 4) | |||
| { | |||
| flake->_TurnBackIndex = 1; | |||
| } | |||
| } | |||
| flake->_TurnBackIndex++; | |||
| if (flake->_TurnBackIndex > 4) | |||
| { | |||
| flake->_TurnBackIndex = 1; | |||
| } | |||
| return CalcTurnBackId(flake); | |||
| } | |||
| if (flake->_TurnBackTimeTick > 0) | |||
| @@ -86,11 +86,11 @@ class SnowFlakeM1(SnowFlake): | |||
| if current_time_tick < self.__last_time_tick: | |||
| if self.__turn_back_time_tick < 1: | |||
| self.__turn_back_time_tick = self.__last_time_tick - 1 | |||
| self.__turn_back_index += 1 | |||
| # 每毫秒序列数的前5位是预留位, 0用于手工新值, 1-4是时间回拨次序 | |||
| # 支持4次回拨次序(避免回拨重叠导致ID重复), 可无限次回拨(次序循环使用)。 | |||
| if self.__turn_back_index > 4: | |||
| self.__turn_back_index = 1 | |||
| self.__turn_back_index += 1 | |||
| # 每毫秒序列数的前5位是预留位, 0用于手工新值, 1-4是时间回拨次序 | |||
| # 支持4次回拨次序(避免回拨重叠导致ID重复), 可无限次回拨(次序循环使用)。 | |||
| if self.__turn_back_index > 4: | |||
| self.__turn_back_index = 1 | |||
| return self.__calc_turn_back_id(self.__turn_back_time_tick) | |||
| @@ -226,16 +226,16 @@ impl SnowWorkerM1 { | |||
| if currentTimeTick < self._LastTimeTick { | |||
| if self._TurnBackTimeTick < 1 { | |||
| self._TurnBackTimeTick = self._LastTimeTick - 1; | |||
| self._TurnBackIndex += 1; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if self._TurnBackIndex > 4 { | |||
| self._TurnBackIndex = 1; | |||
| } | |||
| self.BeginTurnBackAction(self._TurnBackTimeTick); | |||
| } | |||
| self._TurnBackIndex += 1; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 | |||
| if self._TurnBackIndex > 4 { | |||
| self._TurnBackIndex = 1; | |||
| } | |||
| // thread::sleep(std::time::Duration::from_millis(1)); | |||
| return self.CalcTurnBackId(self._TurnBackTimeTick); | |||
| } | |||
| @@ -243,16 +243,18 @@ export class snowflakeIdv1 { | |||
| if (currentTimeTick < this._LastTimeTick) { | |||
| if (this._TurnBackTimeTick < 1) { | |||
| this._TurnBackTimeTick = this._LastTimeTick - BigInt(1) | |||
| this._TurnBackIndex++ | |||
| // 每毫秒序列数的前 5 位是预留位,0 用于手工新值,1-4 是时间回拨次序 | |||
| // 支持 4 次回拨次序(避免回拨重叠导致 ID 重复),可无限次回拨(次序循环使用)。 | |||
| if (this._TurnBackIndex > 4) | |||
| this._TurnBackIndex = 1 | |||
| this.BeginTurnBackAction(this._TurnBackTimeTick) | |||
| } | |||
| this._TurnBackIndex++ | |||
| // 每毫秒序列数的前 5 位是预留位,0 用于手工新值,1-4 是时间回拨次序 | |||
| // 支持 4 次回拨次序(避免回拨重叠导致 ID 重复),可无限次回拨(次序循环使用)。 | |||
| if (this._TurnBackIndex > 4) | |||
| this._TurnBackIndex = 1 | |||
| return this.CalcTurnBackId(this._TurnBackTimeTick) | |||
| } | |||
| // 时间追平时,_TurnBackTimeTick 清零 | |||
| if (this._TurnBackTimeTick > 0) { | |||
| this.EndTurnBackAction(this._TurnBackTimeTick) | |||
| @@ -143,16 +143,17 @@ class SnowWorkerM1 : ISnowWorker { | |||
| if (currentTimeTick < _LastTimeTick) { | |||
| if (_TurnBackTimeTick < 1) { | |||
| _TurnBackTimeTick = _LastTimeTick - 1; | |||
| _TurnBackIndex++; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 最多4次回拨(防止回拨重叠) | |||
| if (_TurnBackIndex > 4) { | |||
| _TurnBackIndex = 1; | |||
| } | |||
| BeginTurnBackAction(_TurnBackTimeTick); | |||
| } | |||
| _TurnBackIndex++; | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 最多4次回拨(防止回拨重叠) | |||
| if (_TurnBackIndex > 4) { | |||
| _TurnBackIndex = 1; | |||
| } | |||
| // try { | |||
| // Thread.sleep(1); | |||
| // } catch (InterruptedException e) { | |||
| @@ -130,14 +130,16 @@ fn (mut m1 SnowWorkerM1) next_normal_id() u64 { | |||
| if current_time_tick < m1.last_time_tick { | |||
| if m1.turn_back_timetick < 1 { | |||
| m1.turn_back_timetick = m1.last_time_tick - 1 | |||
| m1.turnback_index++ | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 最多4次回拨(防止回拨重叠) | |||
| if m1.turnback_index > 4 { | |||
| m1.turnback_index = 1 | |||
| } | |||
| // m1.begin_turn_back_action(m1.turn_back_timetick) | |||
| } | |||
| m1.turnback_index++ | |||
| // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | |||
| // 最多4次回拨(防止回拨重叠) | |||
| if m1.turnback_index > 4 { | |||
| m1.turnback_index = 1 | |||
| } | |||
| return m1.calc_turn_back_id() | |||
| } | |||
| // 时间追平时,turn_back_timetick清零 | |||