|
|
@@ -1,12 +1,136 @@ |
|
|
|
#!/usr/bin/python |
|
|
|
# coding=UTF-8 |
|
|
|
from SnowFlake import SnowFlake |
|
|
|
from .SnowFlake import SnowFlake |
|
|
|
from .Options import IdGeneratorOptions |
|
|
|
import threading,time |
|
|
|
|
|
|
|
# 组件编号生成器 |
|
|
|
class SnowFlakeM1(SnowFlake): |
|
|
|
|
|
|
|
def __init__(self, options): |
|
|
|
self.Options = options |
|
|
|
def __init__(self, options:IdGeneratorOptions): |
|
|
|
# 1.BaseTime |
|
|
|
if options.BaseTime != 0: |
|
|
|
self.BaseTime = int(options.BaseTime) |
|
|
|
else: |
|
|
|
self.BaseTime = 1582136402000 |
|
|
|
|
|
|
|
def NextId(self): |
|
|
|
return self.Options.WorkerId |
|
|
|
# 2.WorkerIdBitLength |
|
|
|
if options.WorkerIdBitLength == 0: |
|
|
|
self.WorkerIdBitLength = 6 |
|
|
|
else: |
|
|
|
self.WorkerIdBitLength = int(options.WorkerIdBitLength) |
|
|
|
|
|
|
|
# 3.WorkerId |
|
|
|
self.WorkerId = options.WorkerId |
|
|
|
|
|
|
|
# 4.SeqBitLength |
|
|
|
if options.SeqBitLength == 0: |
|
|
|
self.SeqBitLength = 6 |
|
|
|
else: |
|
|
|
self.SeqBitLength = int(options.SeqBitLength) |
|
|
|
|
|
|
|
# 5.MaxSeqNumber |
|
|
|
if options.MaxSeqNumber <= 0: |
|
|
|
self.MaxSeqNumber = (1 << self.SeqBitLength) - 1 |
|
|
|
else: |
|
|
|
self.MaxSeqNumber = int(options.MaxSeqNumber) |
|
|
|
|
|
|
|
# 6.MinSeqNumber |
|
|
|
self.MinSeqNumber = int(options.MinSeqNumber) |
|
|
|
|
|
|
|
# 7.TopOverCostCount |
|
|
|
self.TopOverCostCount = int(options.TopOverCostCount) |
|
|
|
|
|
|
|
# 8.Others |
|
|
|
self.__TimestampShift = self.WorkerIdBitLength + self.SeqBitLength |
|
|
|
self.__CurrentSeqNumber = self.MinSeqNumber |
|
|
|
self.__LastTimeTick:int = 0 |
|
|
|
self.__TurnBackTimeTick:int = 0 |
|
|
|
self.__TurnBackIndex:int = 0 |
|
|
|
self.__IsOverCost = False |
|
|
|
self.__OverCostCountInOneTerm:int = 0 |
|
|
|
self.__IDLock = threading.Lock() |
|
|
|
|
|
|
|
def __NextOverCostId(self) -> int: |
|
|
|
CurrentTimeTick = self.__GetCurrentTimeTick() |
|
|
|
if CurrentTimeTick > self.__LastTimeTick: |
|
|
|
self.__LastTimeTick = CurrentTimeTick |
|
|
|
self.__CurrentSeqNumber = self.MinSeqNumber |
|
|
|
self.__IsOverCost = False |
|
|
|
self.__OverCostCountInOneTerm = 0 |
|
|
|
return self.__CalcId(self.__LastTimeTick) |
|
|
|
|
|
|
|
if self.__OverCostCountInOneTerm >= self.TopOverCostCount: |
|
|
|
self.__LastTimeTick = self.__GetNextTimeTick() |
|
|
|
self.__CurrentSeqNumber = self.MinSeqNumber |
|
|
|
self.__IsOverCost = False |
|
|
|
self.__OverCostCountInOneTerm = 0 |
|
|
|
return self.__CalcId(self.__LastTimeTick) |
|
|
|
|
|
|
|
if self.__CurrentSeqNumber > self.MaxSeqNumber: |
|
|
|
self.__LastTimeTick+=1 |
|
|
|
self.__CurrentSeqNumber = self.MinSeqNumber |
|
|
|
self.__IsOverCost = True |
|
|
|
self.__OverCostCountInOneTerm+=1 |
|
|
|
return self.__CalcId(self.__LastTimeTick) |
|
|
|
|
|
|
|
return self.__CalcId(self.__LastTimeTick) |
|
|
|
|
|
|
|
def __NextNormalId(self) -> int: |
|
|
|
CurrentTimeTick = self.__GetCurrentTimeTick() |
|
|
|
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 |
|
|
|
|
|
|
|
return self.__CalcTurnBackId(self.__TurnBackTimeTick) |
|
|
|
|
|
|
|
# 时间追平时,_TurnBackTimeTick清零 |
|
|
|
if self.__TurnBackTimeTick > 0: |
|
|
|
self.__TurnBackTimeTick = 0 |
|
|
|
|
|
|
|
if CurrentTimeTick > self.__LastTimeTick: |
|
|
|
self.__LastTimeTick = CurrentTimeTick |
|
|
|
self.__CurrentSeqNumber = self.MinSeqNumber |
|
|
|
return self.__CalcId(self.__LastTimeTick) |
|
|
|
|
|
|
|
if self.__CurrentSeqNumber > self.MaxSeqNumber: |
|
|
|
self.__LastTimeTick+=1 |
|
|
|
self.__CurrentSeqNumber = self.MinSeqNumber |
|
|
|
self.__IsOverCost = True |
|
|
|
self.__OverCostCountInOneTerm = 1 |
|
|
|
return self.__CalcId(self.__LastTimeTick) |
|
|
|
|
|
|
|
return self.__CalcId(self.__LastTimeTick) |
|
|
|
|
|
|
|
def __CalcId(self,useTimeTick) -> int: |
|
|
|
self.__CurrentSeqNumber+=1 |
|
|
|
return ((useTimeTick<<self.__TimestampShift) + (self.WorkerId<<self.SeqBitLength) + self.__CurrentSeqNumber) % int(1e64) |
|
|
|
|
|
|
|
def __CalcTurnBackId(self,useTimeTick) -> int: |
|
|
|
self.__TurnBackTimeTick-=1 |
|
|
|
return ((useTimeTick<<self.__TimestampShift) + (self.WorkerId<<self.SeqBitLength) + self.__TurnBackIndex) % int(1e64) |
|
|
|
|
|
|
|
def __GetCurrentTimeTick(self) -> int: |
|
|
|
return int((time.time_ns() / 1e6) - self.BaseTime) |
|
|
|
|
|
|
|
def __GetNextTimeTick(self) -> int: |
|
|
|
TempTimeTicker = self.__GetCurrentTimeTick() |
|
|
|
while TempTimeTicker <= self.__LastTimeTick: |
|
|
|
# 0.001 = 1 mili sec |
|
|
|
time.sleep(0.001) |
|
|
|
TempTimeTicker = self.__GetCurrentTimeTick() |
|
|
|
return TempTimeTicker |
|
|
|
|
|
|
|
def NextId(self) -> int: |
|
|
|
self.__IDLock.acquire() |
|
|
|
if self.__IsOverCost: |
|
|
|
id = self.__NextOverCostId() |
|
|
|
else: |
|
|
|
id = self.__NextNormalId() |
|
|
|
self.__IDLock.release() |
|
|
|
return id |