优化时间回拨处理逻辑
This commit is contained in:
@@ -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,8 +274,12 @@ namespace Yitter.IdGenerator
|
||||
if (_TurnBackTimeTick < 1)
|
||||
{
|
||||
_TurnBackTimeTick = _LastTimeTick - 1;
|
||||
_TurnBackIndex++;
|
||||
#if DEBUG
|
||||
BeginTurnBackAction(_TurnBackTimeTick);
|
||||
#endif
|
||||
}
|
||||
|
||||
_TurnBackIndex++;
|
||||
// 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
|
||||
// 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。
|
||||
if (_TurnBackIndex > 4)
|
||||
@@ -280,9 +287,6 @@ namespace Yitter.IdGenerator
|
||||
_TurnBackIndex = 1;
|
||||
}
|
||||
|
||||
BeginTurnBackAction(_TurnBackTimeTick);
|
||||
}
|
||||
|
||||
//Thread.Sleep(1);
|
||||
return CalcTurnBackId(_TurnBackTimeTick);
|
||||
}
|
||||
@@ -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,11 +69,12 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
// usleep(1000); // 暂停1ms
|
||||
return CalcTurnBackId(worker);
|
||||
|
||||
@@ -170,14 +170,15 @@ func (m1 *SnowWorkerM1) NextNormalId() int64 {
|
||||
if currentTimeTick < m1._LastTimeTick {
|
||||
if m1._TurnBackTimeTick < 1 {
|
||||
m1._TurnBackTimeTick = m1._LastTimeTick - 1
|
||||
m1.BeginTurnBackAction(m1._TurnBackTimeTick)
|
||||
}
|
||||
|
||||
m1._TurnBackIndex++
|
||||
// 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
|
||||
// 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。
|
||||
if m1._TurnBackIndex > 4 {
|
||||
m1._TurnBackIndex = 1
|
||||
}
|
||||
m1.BeginTurnBackAction(m1._TurnBackTimeTick)
|
||||
}
|
||||
|
||||
// time.Sleep(time.Duration(1) * time.Millisecond)
|
||||
return m1.CalcTurnBackId(m1._TurnBackTimeTick)
|
||||
|
||||
@@ -141,15 +141,15 @@ public class SnowWorkerM1 implements ISnowWorker {
|
||||
if (currentTimeTick < _LastTimeTick) {
|
||||
if (_TurnBackTimeTick < 1) {
|
||||
_TurnBackTimeTick = _LastTimeTick - 1;
|
||||
_TurnBackIndex++;
|
||||
BeginTurnBackAction(_TurnBackTimeTick);
|
||||
}
|
||||
|
||||
_TurnBackIndex++;
|
||||
// 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
|
||||
// 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。
|
||||
if (_TurnBackIndex > 4) {
|
||||
_TurnBackIndex = 1;
|
||||
}
|
||||
BeginTurnBackAction(_TurnBackTimeTick);
|
||||
}
|
||||
|
||||
// try {
|
||||
// Thread.sleep(1);
|
||||
|
||||
@@ -136,16 +136,19 @@ class Genid {
|
||||
if (currentTimeTick < this._LastTimeTick) {
|
||||
if (this._TurnBackTimeTick < 1) {
|
||||
this._TurnBackTimeTick = this._LastTimeTick - 1;
|
||||
this.BeginTurnBackAction(this._TurnBackTimeTick);
|
||||
}
|
||||
|
||||
this._TurnBackIndex++;
|
||||
// 每毫秒序列数的前 5 位是预留位,0 用于手工新值,1-4 是时间回拨次序
|
||||
// 支持 4 次回拨次序(避免回拨重叠导致 ID 重复),可无限次回拨(次序循环使用)。
|
||||
if (this._TurnBackIndex > 4) {
|
||||
this._TurnBackIndex = 1;
|
||||
}
|
||||
this.BeginTurnBackAction(this._TurnBackTimeTick);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return CalcTurnBackId(flake);
|
||||
}
|
||||
if (flake->_TurnBackTimeTick > 0)
|
||||
|
||||
@@ -226,15 +226,15 @@ impl SnowWorkerM1 {
|
||||
if currentTimeTick < self._LastTimeTick {
|
||||
if self._TurnBackTimeTick < 1 {
|
||||
self._TurnBackTimeTick = self._LastTimeTick - 1;
|
||||
self._TurnBackIndex += 1;
|
||||
self.BeginTurnBackAction(self._TurnBackTimeTick);
|
||||
}
|
||||
|
||||
self._TurnBackIndex += 1;
|
||||
// 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
|
||||
// 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。
|
||||
if self._TurnBackIndex > 4 {
|
||||
self._TurnBackIndex = 1;
|
||||
}
|
||||
self.BeginTurnBackAction(self._TurnBackTimeTick);
|
||||
}
|
||||
|
||||
// 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.BeginTurnBackAction(this._TurnBackTimeTick)
|
||||
}
|
||||
|
||||
this._TurnBackIndex++
|
||||
// 每毫秒序列数的前 5 位是预留位,0 用于手工新值,1-4 是时间回拨次序
|
||||
// 支持 4 次回拨次序(避免回拨重叠导致 ID 重复),可无限次回拨(次序循环使用)。
|
||||
if (this._TurnBackIndex > 4)
|
||||
this._TurnBackIndex = 1
|
||||
|
||||
this.BeginTurnBackAction(this._TurnBackTimeTick)
|
||||
}
|
||||
return this.CalcTurnBackId(this._TurnBackTimeTick)
|
||||
}
|
||||
|
||||
// 时间追平时,_TurnBackTimeTick 清零
|
||||
if (this._TurnBackTimeTick > 0) {
|
||||
this.EndTurnBackAction(this._TurnBackTimeTick)
|
||||
|
||||
@@ -143,6 +143,9 @@ class SnowWorkerM1 : ISnowWorker {
|
||||
if (currentTimeTick < _LastTimeTick) {
|
||||
if (_TurnBackTimeTick < 1) {
|
||||
_TurnBackTimeTick = _LastTimeTick - 1;
|
||||
BeginTurnBackAction(_TurnBackTimeTick);
|
||||
}
|
||||
|
||||
_TurnBackIndex++;
|
||||
|
||||
// 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
|
||||
@@ -150,8 +153,6 @@ class SnowWorkerM1 : ISnowWorker {
|
||||
if (_TurnBackIndex > 4) {
|
||||
_TurnBackIndex = 1;
|
||||
}
|
||||
BeginTurnBackAction(_TurnBackTimeTick);
|
||||
}
|
||||
|
||||
// try {
|
||||
// Thread.sleep(1);
|
||||
|
||||
@@ -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.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
|
||||
}
|
||||
// m1.begin_turn_back_action(m1.turn_back_timetick)
|
||||
}
|
||||
|
||||
return m1.calc_turn_back_id()
|
||||
}
|
||||
// 时间追平时,turn_back_timetick清零
|
||||
|
||||
Reference in New Issue
Block a user