snowflake.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import time
  2. class Snowflake:
  3. def __init__(self, datacenter_id, worker_id):
  4. self.sequence = 0
  5. self.last_timestamp = -1
  6. self.datacenter_id = datacenter_id
  7. self.worker_id = worker_id
  8. self.DATACENTER_ID_BITS = 5
  9. self.WORKER_ID_BITS = 5
  10. self.SEQUENCE_BITS = 12
  11. self.MAX_DATACENTER_ID = -1 ^ (-1 << self.DATACENTER_ID_BITS)
  12. self.MAX_WORKER_ID = -1 ^ (-1 << self.WORKER_ID_BITS)
  13. self.MAX_SEQUENCE = -1 ^ (-1 << self.SEQUENCE_BITS)
  14. self.DATA_CENTER_SHIFT = self.WORKER_ID_BITS + self.SEQUENCE_BITS
  15. self.WORKER_SHIFT = self.SEQUENCE_BITS
  16. self.TIMESTAMP_LEFT_SHIFT = self.DATACENTER_ID_BITS + self.WORKER_ID_BITS + self.SEQUENCE_BITS
  17. def generate_id(self):
  18. timestamp = int(time.time() * 1000)
  19. if timestamp < self.last_timestamp:
  20. raise Exception("Clock moved backwards. Refusing to generate id")
  21. if timestamp == self.last_timestamp:
  22. self.sequence = (self.sequence + 1) & self.MAX_SEQUENCE
  23. if self.sequence == 0:
  24. timestamp = self.wait_next_millis(self.last_timestamp)
  25. else:
  26. self.sequence = 0
  27. self.last_timestamp = timestamp
  28. return (
  29. (timestamp << self.TIMESTAMP_LEFT_SHIFT) |
  30. (self.datacenter_id << self.DATA_CENTER_SHIFT) |
  31. (self.worker_id << self.WORKER_SHIFT) |
  32. self.sequence
  33. )
  34. def wait_next_millis(self, last_timestamp):
  35. timestamp = int(time.time() * 1000)
  36. while timestamp <= last_timestamp:
  37. timestamp = int(time.time() * 1000)
  38. return timestamp
  39. if __name__ == "__main__":
  40. # 假设数据中心ID为1,工作机器ID为1
  41. snowflake = Snowflake(231, 111)
  42. for _ in range(10):
  43. print(snowflake.generate_id())