2
.gitignore
vendored
2
.gitignore
vendored
@@ -259,4 +259,6 @@ target/
|
||||
# macOS
|
||||
.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):
|
||||
|
||||
# 雪花计算方法,(1-漂移算法|2-传统算法),默认1。目前只实现了1。
|
||||
@@ -26,5 +25,3 @@ class IdGeneratorOptions(object):
|
||||
|
||||
# 最大漂移次数(含),默认2000,推荐范围500-10000(与计算能力有关)
|
||||
self.TopOverCostCount = 2000
|
||||
|
||||
|
||||
@@ -7,5 +7,5 @@ class SnowFlake(object):
|
||||
def __init__(self, options):
|
||||
self.Options = options
|
||||
|
||||
def NextId(self):
|
||||
def NextId(self) -> int:
|
||||
return 0
|
||||
|
||||
@@ -1,12 +1,136 @@
|
||||
#!/usr/bin/python
|
||||
# coding=UTF-8
|
||||
from SnowFlake import SnowFlake
|
||||
from .SnowFlake import SnowFlake
|
||||
from .Options import IdGeneratorOptions
|
||||
import threading,time
|
||||
|
||||
# 组件编号生成器
|
||||
class SnowFlakeM1(SnowFlake):
|
||||
|
||||
def __init__(self, options):
|
||||
self.Options = options
|
||||
def __init__(self, options:IdGeneratorOptions):
|
||||
# 1.BaseTime
|
||||
if options.BaseTime != 0:
|
||||
self.BaseTime = int(options.BaseTime)
|
||||
else:
|
||||
self.BaseTime = 1582136402000
|
||||
|
||||
def NextId(self):
|
||||
return self.Options.WorkerId
|
||||
# 2.WorkerIdBitLength
|
||||
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