#!/usr/bin/python # coding=UTF-8 from .SnowFlake import SnowFlake from .Options import IdGeneratorOptions import threading,time # 组件编号生成器 class SnowFlakeM1(SnowFlake): def __init__(self, options:IdGeneratorOptions): # 1.BaseTime if options.BaseTime != 0: self.BaseTime = int(options.BaseTime) else: self.BaseTime = 1582136402000 # 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< int: self.__TurnBackTimeTick-=1 return ((useTimeTick< 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