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.

snowflake_m1.py 5.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. """
  2. M1生成器
  3. """
  4. # !/usr/bin/python
  5. # coding=UTF-8
  6. import threading
  7. import time
  8. from .snowflake import SnowFlake
  9. from .options import IdGeneratorOptions
  10. # 组件编号生成器
  11. class SnowFlakeM1(SnowFlake):
  12. """
  13. M1规则ID生成器配置
  14. """
  15. def __init__(self, options: IdGeneratorOptions):
  16. # 1.base_time
  17. self.base_time = 1582136402000
  18. if options.base_time != 0:
  19. self.base_time = int(options.base_time)
  20. # 2.worker_id_bit_length
  21. self.worker_id_bit_length = 6
  22. if options.worker_id_bit_length != 0:
  23. self.worker_id_bit_length = int(options.worker_id_bit_length)
  24. # 3.worker_id
  25. self.worker_id = options.worker_id
  26. # 4.seq_bit_length
  27. self.seq_bit_length = 6
  28. if options.seq_bit_length != 0:
  29. self.seq_bit_length = int(options.seq_bit_length)
  30. # 5.max_seq_number
  31. self.max_seq_number = int(options.max_seq_number)
  32. if options.max_seq_number <= 0:
  33. self.max_seq_number = (1 << self.seq_bit_length) - 1
  34. # 6.min_seq_number
  35. self.min_seq_number = int(options.min_seq_number)
  36. # 7.top_over_cost_count
  37. self.top_over_cost_count = int(options.top_over_cost_count)
  38. # 8.Others
  39. self.__timestamp_shift = self.worker_id_bit_length + self.seq_bit_length
  40. self.__current_seq_number = self.min_seq_number
  41. self.__last_time_tick: int = 0
  42. self.__turn_back_time_tick: int = 0
  43. self.__turn_back_index: int = 0
  44. self.__is_over_cost = False
  45. self.___over_cost_count_in_one_term: int = 0
  46. self.__id_lock = threading.Lock()
  47. def __next_over_cost_id(self) -> int:
  48. current_time_tick = self.__get_current_time_tick()
  49. if current_time_tick > self.__last_time_tick:
  50. self.__last_time_tick = current_time_tick
  51. self.__current_seq_number = self.min_seq_number
  52. self.__is_over_cost = False
  53. self.___over_cost_count_in_one_term = 0
  54. return self.__calc_id(self.__last_time_tick)
  55. if self.___over_cost_count_in_one_term >= self.top_over_cost_count:
  56. self.__last_time_tick = self.__get_next_time_tick()
  57. self.__current_seq_number = self.min_seq_number
  58. self.__is_over_cost = False
  59. self.___over_cost_count_in_one_term = 0
  60. return self.__calc_id(self.__last_time_tick)
  61. if self.__current_seq_number > self.max_seq_number:
  62. self.__last_time_tick += 1
  63. self.__current_seq_number = self.min_seq_number
  64. self.__is_over_cost = True
  65. self.___over_cost_count_in_one_term += 1
  66. return self.__calc_id(self.__last_time_tick)
  67. return self.__calc_id(self.__last_time_tick)
  68. def __next_normal_id(self) -> int:
  69. current_time_tick = self.__get_current_time_tick()
  70. if current_time_tick < self.__last_time_tick:
  71. if self.__turn_back_time_tick < 1:
  72. self.__turn_back_time_tick = self.__last_time_tick - 1
  73. self.__turn_back_index += 1
  74. # 每毫秒序列数的前5位是预留位, 0用于手工新值, 1-4是时间回拨次序
  75. # 支持4次回拨次序(避免回拨重叠导致ID重复), 可无限次回拨(次序循环使用)。
  76. if self.__turn_back_index > 4:
  77. self.__turn_back_index = 1
  78. return self.__calc_turn_back_id(self.__turn_back_time_tick)
  79. # 时间追平时, _TurnBackTimeTick清零
  80. self.__turn_back_time_tick = min(self.__turn_back_time_tick, 0)
  81. if current_time_tick > self.__last_time_tick:
  82. self.__last_time_tick = current_time_tick
  83. self.__current_seq_number = self.min_seq_number
  84. return self.__calc_id(self.__last_time_tick)
  85. if self.__current_seq_number > self.max_seq_number:
  86. self.__last_time_tick += 1
  87. self.__current_seq_number = self.min_seq_number
  88. self.__is_over_cost = True
  89. self.___over_cost_count_in_one_term = 1
  90. return self.__calc_id(self.__last_time_tick)
  91. return self.__calc_id(self.__last_time_tick)
  92. def __calc_id(self, use_time_tick) -> int:
  93. self.__current_seq_number += 1
  94. return (
  95. (use_time_tick << self.__timestamp_shift) +
  96. (self.worker_id << self.seq_bit_length) +
  97. self.__current_seq_number
  98. ) % int(1e64)
  99. def __calc_turn_back_id(self, use_time_tick) -> int:
  100. self.__turn_back_time_tick -= 1
  101. return (
  102. (use_time_tick << self.__timestamp_shift) +
  103. (self.worker_id << self.seq_bit_length) +
  104. self.__turn_back_index
  105. ) % int(1e64)
  106. def __get_current_time_tick(self) -> int:
  107. return int((time.time_ns() / 1e6) - self.base_time)
  108. def __get_next_time_tick(self) -> int:
  109. temp_time_ticker = self.__get_current_time_tick()
  110. while temp_time_ticker <= self.__last_time_tick:
  111. # 0.001 = 1 mili sec
  112. time.sleep(0.001)
  113. temp_time_ticker = self.__get_current_time_tick()
  114. return temp_time_ticker
  115. def next_id(self) -> int:
  116. with self.__id_lock:
  117. if self.__is_over_cost:
  118. nextid = self.__next_over_cost_id()
  119. else:
  120. nextid = self.__next_normal_id()
  121. return nextid