@@ -59,11 +59,13 @@ namespace Yitter.IdGenerator | |||||
protected ushort _CurrentSeqNumber; | protected ushort _CurrentSeqNumber; | ||||
protected long _LastTimeTick = -1L; | protected long _LastTimeTick = -1L; | ||||
protected long _TurnBackTimeTick = -1L; | protected long _TurnBackTimeTick = -1L; | ||||
protected byte _TurnBackIndex = 0; | |||||
protected bool _IsOverCost = false; | protected bool _IsOverCost = false; | ||||
protected int _OverCostCountInOneTerm = 0; | protected int _OverCostCountInOneTerm = 0; | ||||
protected int _GenCountInOneTerm = 0; | protected int _GenCountInOneTerm = 0; | ||||
protected int _TermIndex = 0; | protected int _TermIndex = 0; | ||||
public Action<OverCostActionArg> GenAction { get; set; } | public Action<OverCostActionArg> GenAction { get; set; } | ||||
public SnowWorkerM1(IdGeneratorOptions options) | public SnowWorkerM1(IdGeneratorOptions options) | ||||
@@ -97,7 +99,7 @@ namespace Yitter.IdGenerator | |||||
if (MaxSeqNumber == 0) | if (MaxSeqNumber == 0) | ||||
{ | { | ||||
MaxSeqNumber = (int)Math.Pow(2, SeqBitLength)-1; | |||||
MaxSeqNumber = (int)Math.Pow(2, SeqBitLength) - 1; | |||||
} | } | ||||
_TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | _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) | if (GenAction == null) | ||||
{ | { | ||||
@@ -129,7 +131,7 @@ namespace Yitter.IdGenerator | |||||
_TermIndex)); | _TermIndex)); | ||||
} | } | ||||
private void EndOverCostCallBack(in long useTimeTick) | |||||
private void EndOverCostAction(in long useTimeTick) | |||||
{ | { | ||||
if (_TermIndex > 10000) | if (_TermIndex > 10000) | ||||
{ | { | ||||
@@ -150,7 +152,7 @@ namespace Yitter.IdGenerator | |||||
_TermIndex)); | _TermIndex)); | ||||
} | } | ||||
private void TurnBackCallBack(in long useTimeTick) | |||||
private void BeginTurnBackAction(in long useTimeTick) | |||||
{ | { | ||||
if (GenAction == null) | if (GenAction == null) | ||||
{ | { | ||||
@@ -161,9 +163,25 @@ namespace Yitter.IdGenerator | |||||
WorkerId, | WorkerId, | ||||
useTimeTick, | useTimeTick, | ||||
8, | 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() | private long NextOverCostId() | ||||
@@ -172,7 +190,7 @@ namespace Yitter.IdGenerator | |||||
if (currentTimeTick > _LastTimeTick) | if (currentTimeTick > _LastTimeTick) | ||||
{ | { | ||||
EndOverCostCallBack(currentTimeTick); | |||||
EndOverCostAction(currentTimeTick); | |||||
_LastTimeTick = currentTimeTick; | _LastTimeTick = currentTimeTick; | ||||
_CurrentSeqNumber = MinSeqNumber; | _CurrentSeqNumber = MinSeqNumber; | ||||
@@ -185,7 +203,7 @@ namespace Yitter.IdGenerator | |||||
if (_OverCostCountInOneTerm >= TopOverCostCount) | if (_OverCostCountInOneTerm >= TopOverCostCount) | ||||
{ | { | ||||
EndOverCostCallBack(currentTimeTick); | |||||
EndOverCostAction(currentTimeTick); | |||||
_LastTimeTick = GetNextTimeTick(); | _LastTimeTick = GetNextTimeTick(); | ||||
_CurrentSeqNumber = MinSeqNumber; | _CurrentSeqNumber = MinSeqNumber; | ||||
@@ -215,6 +233,34 @@ namespace Yitter.IdGenerator | |||||
{ | { | ||||
long currentTimeTick = GetCurrentTimeTick(); | 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) | if (currentTimeTick > _LastTimeTick) | ||||
{ | { | ||||
_LastTimeTick = currentTimeTick; | _LastTimeTick = currentTimeTick; | ||||
@@ -225,32 +271,18 @@ namespace Yitter.IdGenerator | |||||
if (_CurrentSeqNumber > MaxSeqNumber) | if (_CurrentSeqNumber > MaxSeqNumber) | ||||
{ | { | ||||
BeginOverCostCallBack(currentTimeTick); | |||||
BeginOverCostAction(currentTimeTick); | |||||
_TermIndex++; | _TermIndex++; | ||||
_LastTimeTick++; | _LastTimeTick++; | ||||
_CurrentSeqNumber = MinSeqNumber; | _CurrentSeqNumber = MinSeqNumber; | ||||
_IsOverCost = true; | _IsOverCost = true; | ||||
_OverCostCountInOneTerm++; | |||||
_OverCostCountInOneTerm = 1; | |||||
_GenCountInOneTerm = 1; | _GenCountInOneTerm = 1; | ||||
return CalcId(_LastTimeTick); | return CalcId(_LastTimeTick); | ||||
} | } | ||||
if (currentTimeTick < _LastTimeTick) | |||||
{ | |||||
if (_TurnBackTimeTick < 1) | |||||
{ | |||||
_TurnBackTimeTick = _LastTimeTick - 1; | |||||
} | |||||
Thread.Sleep(10); | |||||
TurnBackCallBack(_TurnBackTimeTick); | |||||
return CalcTurnBackId(_TurnBackTimeTick); | |||||
} | |||||
return CalcId(_LastTimeTick); | return CalcId(_LastTimeTick); | ||||
} | } | ||||
@@ -267,7 +299,7 @@ namespace Yitter.IdGenerator | |||||
private long CalcTurnBackId(in long useTimeTick) | private long CalcTurnBackId(in long useTimeTick) | ||||
{ | { | ||||
var result = ((useTimeTick << _TimestampShift) + | var result = ((useTimeTick << _TimestampShift) + | ||||
((long)WorkerId << SeqBitLength) + 0); | |||||
((long)WorkerId << SeqBitLength) + _TurnBackIndex); | |||||
_TurnBackTimeTick--; | _TurnBackTimeTick--; | ||||
return result; | return result; | ||||
@@ -18,7 +18,7 @@ | |||||
<Copyright>Yitter</Copyright> | <Copyright>Yitter</Copyright> | ||||
<PackageProjectUrl>https://gitee.com/yitter/idgenerator</PackageProjectUrl> | <PackageProjectUrl>https://gitee.com/yitter/idgenerator</PackageProjectUrl> | ||||
<PackageLicenseExpression>MIT</PackageLicenseExpression> | <PackageLicenseExpression>MIT</PackageLicenseExpression> | ||||
<Version>1.0.7</Version> | |||||
<Version>1.0.8</Version> | |||||
<PackageReleaseNotes></PackageReleaseNotes> | <PackageReleaseNotes></PackageReleaseNotes> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
@@ -52,6 +52,8 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
protected short _CurrentSeqNumber; | protected short _CurrentSeqNumber; | ||||
protected long _LastTimeTick = -1L; | protected long _LastTimeTick = -1L; | ||||
protected long _TurnBackTimeTick = -1L; | protected long _TurnBackTimeTick = -1L; | ||||
protected byte _TurnBackIndex = 0; | |||||
protected boolean _IsOverCost = false; | protected boolean _IsOverCost = false; | ||||
protected int _OverCostCountInOneTerm = 0; | protected int _OverCostCountInOneTerm = 0; | ||||
protected int _GenCountInOneTerm = 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) { | // if (GenAction == null) { | ||||
// return; | // return; | ||||
// } | // } | ||||
@@ -87,7 +89,7 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
// _TermIndex)); | // _TermIndex)); | ||||
} | } | ||||
private void EndOverCostCallBack(long useTimeTick) { | |||||
private void EndOverCostAction(long useTimeTick) { | |||||
if (_TermIndex > 10000) { | if (_TermIndex > 10000) { | ||||
_TermIndex = 0; | _TermIndex = 0; | ||||
} | } | ||||
@@ -105,7 +107,7 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
// _TermIndex)); | // _TermIndex)); | ||||
} | } | ||||
private void TurnBackCallBack(long useTimeTick) { | |||||
private void BeginTurnBackAction(long useTimeTick) { | |||||
// if (GenAction == null) { | // if (GenAction == null) { | ||||
// return; | // return; | ||||
// } | // } | ||||
@@ -119,11 +121,15 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
// _TermIndex)); | // _TermIndex)); | ||||
} | } | ||||
private void EndTurnBackAction(long useTimeTick) { | |||||
} | |||||
private long NextOverCostId() { | private long NextOverCostId() { | ||||
long currentTimeTick = GetCurrentTimeTick(); | long currentTimeTick = GetCurrentTimeTick(); | ||||
if (currentTimeTick > _LastTimeTick) { | if (currentTimeTick > _LastTimeTick) { | ||||
EndOverCostCallBack(currentTimeTick); | |||||
EndOverCostAction(currentTimeTick); | |||||
_LastTimeTick = currentTimeTick; | _LastTimeTick = currentTimeTick; | ||||
_CurrentSeqNumber = MinSeqNumber; | _CurrentSeqNumber = MinSeqNumber; | ||||
@@ -135,7 +141,7 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
} | } | ||||
if (_OverCostCountInOneTerm >= TopOverCostCount) { | if (_OverCostCountInOneTerm >= TopOverCostCount) { | ||||
EndOverCostCallBack(currentTimeTick); | |||||
EndOverCostAction(currentTimeTick); | |||||
_LastTimeTick = GetNextTimeTick(); | _LastTimeTick = GetNextTimeTick(); | ||||
_CurrentSeqNumber = MinSeqNumber; | _CurrentSeqNumber = MinSeqNumber; | ||||
@@ -163,6 +169,33 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
private long NextNormalId() throws IdGeneratorException { | private long NextNormalId() throws IdGeneratorException { | ||||
long currentTimeTick = GetCurrentTimeTick(); | 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) { | if (currentTimeTick > _LastTimeTick) { | ||||
_LastTimeTick = currentTimeTick; | _LastTimeTick = currentTimeTick; | ||||
_CurrentSeqNumber = MinSeqNumber; | _CurrentSeqNumber = MinSeqNumber; | ||||
@@ -171,34 +204,18 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
} | } | ||||
if (_CurrentSeqNumber > MaxSeqNumber) { | if (_CurrentSeqNumber > MaxSeqNumber) { | ||||
BeginOverCostCallBack(currentTimeTick); | |||||
BeginOverCostAction(currentTimeTick); | |||||
_TermIndex++; | _TermIndex++; | ||||
_LastTimeTick++; | _LastTimeTick++; | ||||
_CurrentSeqNumber = MinSeqNumber; | _CurrentSeqNumber = MinSeqNumber; | ||||
_IsOverCost = true; | _IsOverCost = true; | ||||
_OverCostCountInOneTerm++; | |||||
_OverCostCountInOneTerm = 1; | |||||
_GenCountInOneTerm = 1; | _GenCountInOneTerm = 1; | ||||
return CalcId(_LastTimeTick); | 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); | return CalcId(_LastTimeTick); | ||||
} | } | ||||
@@ -213,7 +230,7 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
private long CalcTurnBackId(long useTimeTick) { | private long CalcTurnBackId(long useTimeTick) { | ||||
long result = ((useTimeTick << _TimestampShift) + | long result = ((useTimeTick << _TimestampShift) + | ||||
((long) WorkerId << SeqBitLength) + 0); | |||||
((long) WorkerId << SeqBitLength) + _TurnBackIndex); | |||||
_TurnBackTimeTick--; | _TurnBackTimeTick--; | ||||
return result; | return result; | ||||