You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

SnowFlakeM1.py 4.3 kB

3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/python
  2. # coding=UTF-8
  3. from .SnowFlake import SnowFlake
  4. from .Options import IdGeneratorOptions
  5. import threading,time
  6. # 组件编号生成器
  7. class SnowFlakeM1(SnowFlake):
  8. def __init__(self, options:IdGeneratorOptions):
  9. # 1.BaseTime
  10. if options.BaseTime != 0:
  11. self.BaseTime = int(options.BaseTime)
  12. else:
  13. self.BaseTime = 1582136402000
  14. # 2.WorkerIdBitLength
  15. if options.WorkerIdBitLength == 0:
  16. self.WorkerIdBitLength = 6
  17. else:
  18. self.WorkerIdBitLength = int(options.WorkerIdBitLength)
  19. # 3.WorkerId
  20. self.WorkerId = options.WorkerId
  21. # 4.SeqBitLength
  22. if options.SeqBitLength == 0:
  23. self.SeqBitLength = 6
  24. else:
  25. self.SeqBitLength = int(options.SeqBitLength)
  26. # 5.MaxSeqNumber
  27. if options.MaxSeqNumber <= 0:
  28. self.MaxSeqNumber = (1 << self.SeqBitLength) - 1
  29. else:
  30. self.MaxSeqNumber = int(options.MaxSeqNumber)
  31. # 6.MinSeqNumber
  32. self.MinSeqNumber = int(options.MinSeqNumber)
  33. # 7.TopOverCostCount
  34. self.TopOverCostCount = int(options.TopOverCostCount)
  35. # 8.Others
  36. self.__TimestampShift = self.WorkerIdBitLength + self.SeqBitLength
  37. self.__CurrentSeqNumber = self.MinSeqNumber
  38. self.__LastTimeTick:int = 0
  39. self.__TurnBackTimeTick:int = 0
  40. self.__TurnBackIndex:int = 0
  41. self.__IsOverCost = False
  42. self.__OverCostCountInOneTerm:int = 0
  43. self.__IDLock = threading.Lock()
  44. def __NextOverCostId(self) -> int:
  45. CurrentTimeTick = self.__GetCurrentTimeTick()
  46. if CurrentTimeTick > self.__LastTimeTick:
  47. self.__LastTimeTick = CurrentTimeTick
  48. self.__CurrentSeqNumber = self.MinSeqNumber
  49. self.__IsOverCost = False
  50. self.__OverCostCountInOneTerm = 0
  51. return self.__CalcId(self.__LastTimeTick)
  52. if self.__OverCostCountInOneTerm >= self.TopOverCostCount:
  53. self.__LastTimeTick = self.__GetNextTimeTick()
  54. self.__CurrentSeqNumber = self.MinSeqNumber
  55. self.__IsOverCost = False
  56. self.__OverCostCountInOneTerm = 0
  57. return self.__CalcId(self.__LastTimeTick)
  58. if self.__CurrentSeqNumber > self.MaxSeqNumber:
  59. self.__LastTimeTick+=1
  60. self.__CurrentSeqNumber = self.MinSeqNumber
  61. self.__IsOverCost = True
  62. self.__OverCostCountInOneTerm+=1
  63. return self.__CalcId(self.__LastTimeTick)
  64. return self.__CalcId(self.__LastTimeTick)
  65. def __NextNormalId(self) -> int:
  66. CurrentTimeTick = self.__GetCurrentTimeTick()
  67. if CurrentTimeTick < self.__LastTimeTick:
  68. if self.__TurnBackTimeTick < 1:
  69. self.__TurnBackTimeTick = self.__LastTimeTick - 1
  70. self.__TurnBackIndex+=1
  71. # 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
  72. # 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。
  73. if self.__TurnBackIndex > 4:
  74. self.__TurnBackIndex = 1
  75. return self.__CalcTurnBackId(self.__TurnBackTimeTick)
  76. # 时间追平时,_TurnBackTimeTick清零
  77. if self.__TurnBackTimeTick > 0:
  78. self.__TurnBackTimeTick = 0
  79. if CurrentTimeTick > self.__LastTimeTick:
  80. self.__LastTimeTick = CurrentTimeTick
  81. self.__CurrentSeqNumber = self.MinSeqNumber
  82. return self.__CalcId(self.__LastTimeTick)
  83. if self.__CurrentSeqNumber > self.MaxSeqNumber:
  84. self.__LastTimeTick+=1
  85. self.__CurrentSeqNumber = self.MinSeqNumber
  86. self.__IsOverCost = True
  87. self.__OverCostCountInOneTerm = 1
  88. return self.__CalcId(self.__LastTimeTick)
  89. return self.__CalcId(self.__LastTimeTick)
  90. def __CalcId(self,useTimeTick) -> int:
  91. self.__CurrentSeqNumber+=1
  92. return ((useTimeTick<<self.__TimestampShift) + (self.WorkerId<<self.SeqBitLength) + self.__CurrentSeqNumber) % int(1e64)
  93. def __CalcTurnBackId(self,useTimeTick) -> int:
  94. self.__TurnBackTimeTick-=1
  95. return ((useTimeTick<<self.__TimestampShift) + (self.WorkerId<<self.SeqBitLength) + self.__TurnBackIndex) % int(1e64)
  96. def __GetCurrentTimeTick(self) -> int:
  97. return int((time.time_ns() / 1e6) - self.BaseTime)
  98. def __GetNextTimeTick(self) -> int:
  99. TempTimeTicker = self.__GetCurrentTimeTick()
  100. while TempTimeTicker <= self.__LastTimeTick:
  101. # 0.001 = 1 mili sec
  102. time.sleep(0.001)
  103. TempTimeTicker = self.__GetCurrentTimeTick()
  104. return TempTimeTicker
  105. def NextId(self) -> int:
  106. self.__IDLock.acquire()
  107. if self.__IsOverCost:
  108. id = self.__NextOverCostId()
  109. else:
  110. id = self.__NextNormalId()
  111. self.__IDLock.release()
  112. return id