diff --git a/C#/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs b/C#/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs index 18580df..6b04322 100644 --- a/C#/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs +++ b/C#/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs @@ -59,11 +59,13 @@ namespace Yitter.IdGenerator protected ushort _CurrentSeqNumber; protected long _LastTimeTick = -1L; protected long _TurnBackTimeTick = -1L; + protected byte _TurnBackIndex = 0; protected bool _IsOverCost = false; protected int _OverCostCountInOneTerm = 0; protected int _GenCountInOneTerm = 0; protected int _TermIndex = 0; + public Action GenAction { get; set; } public SnowWorkerM1(IdGeneratorOptions options) @@ -97,7 +99,7 @@ namespace Yitter.IdGenerator if (MaxSeqNumber == 0) { - MaxSeqNumber = (int)Math.Pow(2, SeqBitLength)-1; + MaxSeqNumber = (int)Math.Pow(2, SeqBitLength) - 1; } _TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); @@ -113,7 +115,7 @@ namespace Yitter.IdGenerator }); } - private void BeginOverCostCallBack(in long useTimeTick) + private void BeginOverCostAction(in long useTimeTick) { if (GenAction == null) { @@ -129,7 +131,7 @@ namespace Yitter.IdGenerator _TermIndex)); } - private void EndOverCostCallBack(in long useTimeTick) + private void EndOverCostAction(in long useTimeTick) { if (_TermIndex > 10000) { @@ -150,7 +152,7 @@ namespace Yitter.IdGenerator _TermIndex)); } - private void TurnBackCallBack(in long useTimeTick) + private void BeginTurnBackAction(in long useTimeTick) { if (GenAction == null) { @@ -161,9 +163,25 @@ namespace Yitter.IdGenerator WorkerId, useTimeTick, 8, - _OverCostCountInOneTerm, - _GenCountInOneTerm, - _TermIndex)); + 0, + 0, + _TurnBackIndex)); + } + + private void EndTurnBackAction(in long useTimeTick) + { + if (GenAction == null) + { + return; + } + + DoGenIdAction(new OverCostActionArg( + WorkerId, + useTimeTick, + 9, + 0, + 0, + _TurnBackIndex)); } private long NextOverCostId() @@ -172,7 +190,7 @@ namespace Yitter.IdGenerator if (currentTimeTick > _LastTimeTick) { - EndOverCostCallBack(currentTimeTick); + EndOverCostAction(currentTimeTick); _LastTimeTick = currentTimeTick; _CurrentSeqNumber = MinSeqNumber; @@ -185,7 +203,7 @@ namespace Yitter.IdGenerator if (_OverCostCountInOneTerm >= TopOverCostCount) { - EndOverCostCallBack(currentTimeTick); + EndOverCostAction(currentTimeTick); _LastTimeTick = GetNextTimeTick(); _CurrentSeqNumber = MinSeqNumber; @@ -215,6 +233,34 @@ namespace Yitter.IdGenerator { long currentTimeTick = GetCurrentTimeTick(); + if (currentTimeTick < _LastTimeTick) + { + if (_TurnBackTimeTick < 1) + { + _TurnBackTimeTick = _LastTimeTick - 1; + _TurnBackIndex++; + + // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 + // 最多4次回拨(防止回拨重叠) + if (_TurnBackIndex > 4) + { + _TurnBackIndex = 1; + } + + BeginTurnBackAction(_TurnBackTimeTick); + } + + Thread.Sleep(10); + return CalcTurnBackId(_TurnBackTimeTick); + } + + // 时间追平时,_TurnBackTimeTick清零 + if (_TurnBackTimeTick > 0) + { + EndTurnBackAction(_TurnBackTimeTick); + _TurnBackTimeTick = 0; + } + if (currentTimeTick > _LastTimeTick) { _LastTimeTick = currentTimeTick; @@ -225,32 +271,18 @@ namespace Yitter.IdGenerator if (_CurrentSeqNumber > MaxSeqNumber) { - BeginOverCostCallBack(currentTimeTick); + BeginOverCostAction(currentTimeTick); _TermIndex++; _LastTimeTick++; _CurrentSeqNumber = MinSeqNumber; _IsOverCost = true; - _OverCostCountInOneTerm++; + _OverCostCountInOneTerm = 1; _GenCountInOneTerm = 1; return CalcId(_LastTimeTick); } - if (currentTimeTick < _LastTimeTick) - { - if (_TurnBackTimeTick < 1) - { - _TurnBackTimeTick = _LastTimeTick - 1; - } - - Thread.Sleep(10); - TurnBackCallBack(_TurnBackTimeTick); - - return CalcTurnBackId(_TurnBackTimeTick); - } - - return CalcId(_LastTimeTick); } @@ -267,7 +299,7 @@ namespace Yitter.IdGenerator private long CalcTurnBackId(in long useTimeTick) { var result = ((useTimeTick << _TimestampShift) + - ((long)WorkerId << SeqBitLength) + 0); + ((long)WorkerId << SeqBitLength) + _TurnBackIndex); _TurnBackTimeTick--; return result; diff --git a/C#/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj b/C#/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj index 6589a2d..8b1a5f8 100644 --- a/C#/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj +++ b/C#/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj @@ -18,7 +18,7 @@ Yitter https://gitee.com/yitter/idgenerator MIT - 1.0.7 + 1.0.8 diff --git a/Java/source/src/main/java/com/yitter/core/SnowWorkerM1.java b/Java/source/src/main/java/com/yitter/core/SnowWorkerM1.java index 311ee5b..d793c43 100644 --- a/Java/source/src/main/java/com/yitter/core/SnowWorkerM1.java +++ b/Java/source/src/main/java/com/yitter/core/SnowWorkerM1.java @@ -52,6 +52,8 @@ public class SnowWorkerM1 implements ISnowWorker { protected short _CurrentSeqNumber; protected long _LastTimeTick = -1L; protected long _TurnBackTimeTick = -1L; + protected byte _TurnBackIndex = 0; + protected boolean _IsOverCost = false; protected int _OverCostCountInOneTerm = 0; protected int _GenCountInOneTerm = 0; @@ -73,7 +75,7 @@ public class SnowWorkerM1 implements ISnowWorker { } - private void BeginOverCostCallBack(long useTimeTick) { + private void BeginOverCostAction(long useTimeTick) { // if (GenAction == null) { // return; // } @@ -87,7 +89,7 @@ public class SnowWorkerM1 implements ISnowWorker { // _TermIndex)); } - private void EndOverCostCallBack(long useTimeTick) { + private void EndOverCostAction(long useTimeTick) { if (_TermIndex > 10000) { _TermIndex = 0; } @@ -105,7 +107,7 @@ public class SnowWorkerM1 implements ISnowWorker { // _TermIndex)); } - private void TurnBackCallBack(long useTimeTick) { + private void BeginTurnBackAction(long useTimeTick) { // if (GenAction == null) { // return; // } @@ -119,11 +121,15 @@ public class SnowWorkerM1 implements ISnowWorker { // _TermIndex)); } + private void EndTurnBackAction(long useTimeTick) { + + } + private long NextOverCostId() { long currentTimeTick = GetCurrentTimeTick(); if (currentTimeTick > _LastTimeTick) { - EndOverCostCallBack(currentTimeTick); + EndOverCostAction(currentTimeTick); _LastTimeTick = currentTimeTick; _CurrentSeqNumber = MinSeqNumber; @@ -135,7 +141,7 @@ public class SnowWorkerM1 implements ISnowWorker { } if (_OverCostCountInOneTerm >= TopOverCostCount) { - EndOverCostCallBack(currentTimeTick); + EndOverCostAction(currentTimeTick); _LastTimeTick = GetNextTimeTick(); _CurrentSeqNumber = MinSeqNumber; @@ -163,6 +169,33 @@ public class SnowWorkerM1 implements ISnowWorker { private long NextNormalId() throws IdGeneratorException { long currentTimeTick = GetCurrentTimeTick(); + if (currentTimeTick < _LastTimeTick) { + if (_TurnBackTimeTick < 1) { + _TurnBackTimeTick = _LastTimeTick - 1; + _TurnBackIndex++; + + // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 + // 最多4次回拨(防止回拨重叠) + if (_TurnBackIndex > 4) { + _TurnBackIndex = 1; + } + BeginTurnBackAction(_TurnBackTimeTick); + } + + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return CalcTurnBackId(_TurnBackTimeTick); + } + + // 时间追平时,_TurnBackTimeTick清零 + if (_TurnBackTimeTick > 0) { + EndTurnBackAction(_TurnBackTimeTick); + _TurnBackTimeTick = 0; + } + if (currentTimeTick > _LastTimeTick) { _LastTimeTick = currentTimeTick; _CurrentSeqNumber = MinSeqNumber; @@ -171,34 +204,18 @@ public class SnowWorkerM1 implements ISnowWorker { } if (_CurrentSeqNumber > MaxSeqNumber) { - BeginOverCostCallBack(currentTimeTick); + BeginOverCostAction(currentTimeTick); _TermIndex++; _LastTimeTick++; _CurrentSeqNumber = MinSeqNumber; _IsOverCost = true; - _OverCostCountInOneTerm++; + _OverCostCountInOneTerm = 1; _GenCountInOneTerm = 1; return CalcId(_LastTimeTick); } - if (currentTimeTick < _LastTimeTick) { - if (_TurnBackTimeTick < 1) { - _TurnBackTimeTick = _LastTimeTick - 1; - } - - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - TurnBackCallBack(_TurnBackTimeTick); - - return CalcTurnBackId(_TurnBackTimeTick); - } - return CalcId(_LastTimeTick); } @@ -213,7 +230,7 @@ public class SnowWorkerM1 implements ISnowWorker { private long CalcTurnBackId(long useTimeTick) { long result = ((useTimeTick << _TimestampShift) + - ((long) WorkerId << SeqBitLength) + 0); + ((long) WorkerId << SeqBitLength) + _TurnBackIndex); _TurnBackTimeTick--; return result;