feat: python m1版id生成器
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -259,4 +259,6 @@ target/
|
|||||||
# macOS
|
# macOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# python
|
||||||
|
__pycache__
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,20 @@ Python 3.6+
|
|||||||
|
|
||||||
## 引用 包
|
## 引用 包
|
||||||
|
|
||||||
|
|
||||||
## 调用示例
|
## 调用示例
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 导入包
|
||||||
|
from source import options,generator
|
||||||
|
# 声明id生成器参数,需要自己构建一个workerId
|
||||||
|
options = options.IdGeneratorOptions(workerId=23)
|
||||||
|
# 参数中,WorkerIdBitLength 默认值6,支持的 WorkerId 最大值为2^6-1,若 WorkerId 超过64,可设置更大的 WorkerIdBitLength
|
||||||
|
idgen = generator.DefaultIdGenerator()
|
||||||
|
# 保存参数
|
||||||
|
idgen.SetIdGernerator(options)
|
||||||
|
# 生成id
|
||||||
|
uid = idgen.NextId()
|
||||||
|
# 打印出来查看
|
||||||
|
print("%d, %x" % (uid,uid))
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import time
|
|
||||||
import traceback
|
|
||||||
from IdGeneratorOptions import IdGeneratorOptions
|
|
||||||
from SnowFlake import SnowFlake
|
|
||||||
from SnowFlakeM1 import SnowFlakeM1
|
|
||||||
|
|
||||||
class DefaultIdGenerator(object):
|
|
||||||
|
|
||||||
def SetIdGernerator(self, options) :
|
|
||||||
if options.BaseTime < 100000 :
|
|
||||||
raise ValueError ("BaseTime error.")
|
|
||||||
|
|
||||||
self.SnowFlake= SnowFlakeM1(options)
|
|
||||||
|
|
||||||
def NextId(self):
|
|
||||||
return self.SnowFlake.NextId()
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
options = IdGeneratorOptions(23)
|
|
||||||
options.BaseTime = 1231111111
|
|
||||||
idgen = DefaultIdGenerator()
|
|
||||||
idgen.SetIdGernerator(options)
|
|
||||||
|
|
||||||
print (idgen.NextId())
|
|
||||||
print (options.__dict__)
|
|
||||||
|
|
||||||
except ValueError as e:
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
|
|
||||||
17
Python/source/Generator.py
Normal file
17
Python/source/Generator.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
from .Options import IdGeneratorOptions
|
||||||
|
from .SnowFlakeM1 import SnowFlakeM1
|
||||||
|
|
||||||
|
class DefaultIdGenerator():
|
||||||
|
|
||||||
|
def SetIdGernerator(self, options:IdGeneratorOptions) :
|
||||||
|
if options.BaseTime < 100000 :
|
||||||
|
raise ValueError ("BaseTime error.")
|
||||||
|
|
||||||
|
self.SnowFlake= SnowFlakeM1(options)
|
||||||
|
|
||||||
|
def NextId(self) -> int:
|
||||||
|
"""
|
||||||
|
获取新的UUID
|
||||||
|
"""
|
||||||
|
return self.SnowFlake.NextId()
|
||||||
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import time
|
|
||||||
|
|
||||||
class IdGeneratorOptions(object):
|
class IdGeneratorOptions():
|
||||||
def __init__(self, workerId = 0, workerIdBitLength = 6, seqBitLength = 6):
|
def __init__(self, workerId = 0, workerIdBitLength = 6, seqBitLength = 6):
|
||||||
|
|
||||||
# 雪花计算方法,(1-漂移算法|2-传统算法),默认1。目前只实现了1。
|
# 雪花计算方法,(1-漂移算法|2-传统算法),默认1。目前只实现了1。
|
||||||
@@ -26,5 +25,3 @@ class IdGeneratorOptions(object):
|
|||||||
|
|
||||||
# 最大漂移次数(含),默认2000,推荐范围500-10000(与计算能力有关)
|
# 最大漂移次数(含),默认2000,推荐范围500-10000(与计算能力有关)
|
||||||
self.TopOverCostCount = 2000
|
self.TopOverCostCount = 2000
|
||||||
|
|
||||||
|
|
||||||
@@ -7,5 +7,5 @@ class SnowFlake(object):
|
|||||||
def __init__(self, options):
|
def __init__(self, options):
|
||||||
self.Options = options
|
self.Options = options
|
||||||
|
|
||||||
def NextId(self):
|
def NextId(self) -> int:
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -1,12 +1,136 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# coding=UTF-8
|
# coding=UTF-8
|
||||||
from SnowFlake import SnowFlake
|
from .SnowFlake import SnowFlake
|
||||||
|
from .Options import IdGeneratorOptions
|
||||||
|
import threading,time
|
||||||
|
|
||||||
# 组件编号生成器
|
# 组件编号生成器
|
||||||
class SnowFlakeM1(SnowFlake):
|
class SnowFlakeM1(SnowFlake):
|
||||||
|
|
||||||
def __init__(self, options):
|
def __init__(self, options:IdGeneratorOptions):
|
||||||
self.Options = options
|
# 1.BaseTime
|
||||||
|
if options.BaseTime != 0:
|
||||||
|
self.BaseTime = int(options.BaseTime)
|
||||||
|
else:
|
||||||
|
self.BaseTime = 1582136402000
|
||||||
|
|
||||||
def NextId(self):
|
# 2.WorkerIdBitLength
|
||||||
return self.Options.WorkerId
|
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
|
||||||
|
|||||||
18
Python/test.py
Normal file
18
Python/test.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from source import Options,Generator
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
options = Options.IdGeneratorOptions(workerId=23,seqBitLength=10)
|
||||||
|
options.BaseTime = 1231111111
|
||||||
|
idgen = Generator.DefaultIdGenerator()
|
||||||
|
idgen.SetIdGernerator(options)
|
||||||
|
|
||||||
|
uid = idgen.NextId()
|
||||||
|
|
||||||
|
print(uid)
|
||||||
|
print(options.__dict__)
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user