未验证 提交 4db4bda3 编写于 作者: Y yitter 提交者: GitHub

Merge pull request #35 from LoveBeforT/feat/python

python版本m1生成器
...@@ -259,4 +259,6 @@ target/ ...@@ -259,4 +259,6 @@ target/
# macOS # macOS
.DS_Store .DS_Store
# python
__pycache__
...@@ -7,6 +7,20 @@ Python 3.6+ ...@@ -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))
```
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)
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()
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): ...@@ -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): ...@@ -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
#!/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
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)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册