1
0
mirror of synced 2026-04-27 10:48:41 +08:00

auto commit

This commit is contained in:
yitter
2021-04-02 22:22:55 +08:00
parent e494b91cae
commit 84d1d67dcb
22 changed files with 95 additions and 314 deletions

View File

@@ -7,18 +7,17 @@
package idgen
import (
"strconv"
"time"
"yitidgen/contract"
"yitidgen/core"
)
type DefaultIdGenerator struct {
Options *contract.IdGeneratorOptions
SnowWorker contract.ISnowWorker
IdGeneratorException contract.IdGeneratorException
Options *IdGeneratorOptions
SnowWorker ISnowWorker
IdGeneratorException IdGeneratorException
}
func NewDefaultIdGenerator(options *contract.IdGeneratorOptions) *DefaultIdGenerator {
func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator {
if options == nil {
panic("dig.Options error.")
}
@@ -32,9 +31,9 @@ func NewDefaultIdGenerator(options *contract.IdGeneratorOptions) *DefaultIdGener
panic("errorWorkerIdBitLength + SeqBitLength <= 22")
}
maxWorkerIdNumber := uint16(1<<options.WorkerIdBitLength) - 1
if options.WorkerId > maxWorkerIdNumber {
panic("WorkerId error. (range:[1, " + string(maxWorkerIdNumber) + "]")
maxWorkerIDNumber := uint16(1<<options.WorkerIdBitLength) - 1
if options.WorkerId > maxWorkerIDNumber {
panic("WorkerId error. (range:[1, " + strconv.FormatUint(uint64(maxWorkerIDNumber), 10) + "]")
}
if options.SeqBitLength < 2 || options.SeqBitLength > 21 {
@@ -43,22 +42,23 @@ func NewDefaultIdGenerator(options *contract.IdGeneratorOptions) *DefaultIdGener
maxSeqNumber := uint32(1<<options.SeqBitLength) - 1
if options.MaxSeqNumber > maxSeqNumber {
panic("MaxSeqNumber error. (range:[1, " + string(maxSeqNumber) + "]")
panic("MaxSeqNumber error. (range:[1, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]")
}
if options.MinSeqNumber > maxSeqNumber {
panic("MinSeqNumber error. (range:[1, " + string(maxSeqNumber) + "]")
panic("MinSeqNumber error. (range:[1, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]")
}
var snowWorker contract.ISnowWorker
var snowWorker ISnowWorker
switch options.Method {
case 1:
snowWorker = core.NewSnowWorkerM1(options)
snowWorker = NewSnowWorkerM1(options)
case 2:
snowWorker = core.NewSnowWorkerM2(options)
snowWorker = NewSnowWorkerM2(options)
default:
snowWorker = core.NewSnowWorkerM1(options)
snowWorker = NewSnowWorkerM1(options)
}
if options.Method == 1 {

View File

@@ -0,0 +1,11 @@
/*
* 版权属于yitter(yitter@126.com)
* 代码编辑guoyahao
* 代码修订yitter
* 开源地址https://gitee.com/yitter/idgenerator
*/
package idgen
type IIdGenerator interface {
NewLong() uint64
}

View File

@@ -0,0 +1,11 @@
/*
* 版权属于yitter(yitter@126.com)
* 代码编辑guoyahao
* 代码修订yitter
* 开源地址https://gitee.com/yitter/idgenerator
*/
package idgen
type ISnowWorker interface {
NextId() uint64
}

View File

@@ -0,0 +1,18 @@
/*
* 版权属于yitter(yitter@126.com)
* 代码编辑guoyahao
* 代码修订yitter
* 开源地址https://gitee.com/yitter/idgenerator
*/
package idgen
import "fmt"
type IdGeneratorException struct {
message string
error error
}
func (e IdGeneratorException) IdGeneratorException(message ...interface{}) {
fmt.Println(message)
}

View File

@@ -0,0 +1,31 @@
/*
* 版权属于yitter(yitter@126.com)
* 代码编辑guoyahao
* 代码修订yitter
* 开源地址https://gitee.com/yitter/idgenerator
*/
package idgen
type IdGeneratorOptions struct {
Method uint16 // 雪花计算方法,1-漂移算法|2-传统算法默认1
BaseTime int64 // 基础时间ms单位不能超过当前系统时间
WorkerId uint16 // 机器码,与 WorkerIdBitLength 有关系
WorkerIdBitLength byte // 机器码位长范围1-21要求序列数位长+机器码位长不超过22
SeqBitLength byte // 序列数位长范围2-21要求序列数位长+机器码位长不超过22
MaxSeqNumber uint32 // 最大序列数由SeqBitLength计算的最大值
MinSeqNumber uint32 // 最小序列数默认5不小于1不大于MaxSeqNumber
TopOverCostCount uint32 // 最大漂移次数默认2000推荐范围500-10000与计算能力有关
}
func NewIdGeneratorOptions(workerId uint16) *IdGeneratorOptions {
return &IdGeneratorOptions{
Method: 1,
WorkerId: workerId,
BaseTime: 1582136402000,
WorkerIdBitLength: 6,
SeqBitLength: 6,
MaxSeqNumber: 0,
MinSeqNumber: 5,
TopOverCostCount: 2000,
}
}

View File

@@ -0,0 +1,25 @@
/*
* 版权属于yitter(yitter@126.com)
* 代码编辑guoyahao
* 代码修订yitter
* 开源地址https://gitee.com/yitter/idgenerator
*/
package idgen
type OverCostActionArg struct {
ActionType int32
TimeTick int64
WorkerId uint16
OverCostCountInOneTerm int32
GenCountInOneTerm int32
TermIndex int32
}
func (ocaa OverCostActionArg) OverCostActionArg(workerId uint16, timeTick int64, actionType int32, overCostCountInOneTerm int32, genCountWhenOverCost int32, index int32) {
ocaa.ActionType = actionType
ocaa.TimeTick = timeTick
ocaa.WorkerId = workerId
ocaa.OverCostCountInOneTerm = overCostCountInOneTerm
ocaa.GenCountInOneTerm = genCountWhenOverCost
ocaa.TermIndex = index
}

View File

@@ -0,0 +1,221 @@
/*
* 版权属于yitter(yitter@126.com)
* 代码编辑guoyahao
* 代码修订yitter
* 开源地址https://gitee.com/yitter/idgenerator
*/
package idgen
import (
"sync"
"time"
)
// SnowWorkerM1 .
type SnowWorkerM1 struct {
BaseTime int64 //基础时间
WorkerId uint16 //机器码
WorkerIdBitLength byte //机器码位长
SeqBitLength byte //自增序列数位长
MaxSeqNumber uint32 //最大序列数(含)
MinSeqNumber uint32 //最小序列数(含)
TopOverCostCount uint32 //最大漂移次数
_TimestampShift byte
_CurrentSeqNumber uint32
_LastTimeTick int64
_TurnBackTimeTick int64
_TurnBackIndex byte
_IsOverCost bool
_OverCostCountInOneTerm uint32
_GenCountInOneTerm uint32
_TermIndex uint32
sync.Mutex
}
// NewSnowWorkerM1 .
func NewSnowWorkerM1(options *IdGeneratorOptions) ISnowWorker {
var workerIdBitLength byte
var seqBitLength byte
var maxSeqNumber uint32
var workerId = options.WorkerId
if options.WorkerIdBitLength == 0 {
workerIdBitLength = 6
} else {
workerIdBitLength = options.WorkerIdBitLength
}
if options.SeqBitLength == 0 {
seqBitLength = 6
} else {
seqBitLength = options.SeqBitLength
}
if options.MaxSeqNumber > 0 {
maxSeqNumber = options.MaxSeqNumber
} else {
maxSeqNumber = (1 << seqBitLength) - 1
}
var minSeqNumber = options.MinSeqNumber
var topOverCostCount = options.TopOverCostCount
var baseTime int64
if options.BaseTime != 0 {
baseTime = options.BaseTime
} else {
baseTime = 1582136402000
}
timestampShift := (byte)(options.WorkerIdBitLength + options.SeqBitLength)
currentSeqNumber := options.MinSeqNumber
return &SnowWorkerM1{
BaseTime: baseTime,
WorkerId: workerId,
WorkerIdBitLength: workerIdBitLength,
SeqBitLength: seqBitLength,
MaxSeqNumber: maxSeqNumber,
MinSeqNumber: minSeqNumber,
TopOverCostCount: topOverCostCount,
_TimestampShift: timestampShift,
_CurrentSeqNumber: currentSeqNumber}
}
// DoGenIDAction .
func (m1 *SnowWorkerM1) DoGenIdAction(arg *OverCostActionArg) {
}
func (m1 *SnowWorkerM1) BeginOverCostAction(useTimeTick int64) {
}
func (m1 *SnowWorkerM1) EndOverCostAction(useTimeTick int64) {
if m1._TermIndex > 10000 {
m1._TermIndex = 0
}
}
func (m1 *SnowWorkerM1) BeginTurnBackAction(useTimeTick int64) {
}
func (m1 *SnowWorkerM1) EndTurnBackAction(useTimeTick int64) {
}
func (m1 *SnowWorkerM1) NextOverCostId() uint64 {
currentTimeTick := m1.GetCurrentTimeTick()
if currentTimeTick > m1._LastTimeTick {
m1.EndOverCostAction(currentTimeTick)
m1._LastTimeTick = currentTimeTick
m1._CurrentSeqNumber = m1.MinSeqNumber
m1._IsOverCost = false
m1._OverCostCountInOneTerm = 0
m1._GenCountInOneTerm = 0
return m1.CalcId(m1._LastTimeTick)
}
if m1._OverCostCountInOneTerm >= m1.TopOverCostCount {
m1.EndOverCostAction(currentTimeTick)
m1._LastTimeTick = m1.GetNextTimeTick()
m1._CurrentSeqNumber = m1.MinSeqNumber
m1._IsOverCost = false
m1._OverCostCountInOneTerm = 0
m1._GenCountInOneTerm = 0
return m1.CalcId(m1._LastTimeTick)
}
if m1._CurrentSeqNumber > m1.MaxSeqNumber {
m1._LastTimeTick++
m1._CurrentSeqNumber = m1.MinSeqNumber
m1._IsOverCost = true
m1._OverCostCountInOneTerm++
m1._GenCountInOneTerm++
return m1.CalcId(m1._LastTimeTick)
}
m1._GenCountInOneTerm++
return m1.CalcId(m1._LastTimeTick)
}
// NextNormalID .
func (m1 *SnowWorkerM1) NextNormalId() uint64 {
currentTimeTick := m1.GetCurrentTimeTick()
if currentTimeTick < m1._LastTimeTick {
if m1._TurnBackTimeTick < 1 {
m1._TurnBackTimeTick = m1._LastTimeTick - 1
m1._TurnBackIndex++
// 每毫秒序列数的前5位是预留位0用于手工新值1-4是时间回拨次序
// 最多4次回拨防止回拨重叠
if m1._TurnBackIndex > 4 {
m1._TurnBackIndex = 1
}
m1.BeginTurnBackAction(m1._TurnBackTimeTick)
}
time.Sleep(time.Duration(1) * time.Millisecond)
return m1.CalcTurnBackId(m1._TurnBackTimeTick)
}
// 时间追平时_TurnBackTimeTick清零
if m1._TurnBackTimeTick > 0 {
m1.EndTurnBackAction(m1._TurnBackTimeTick)
m1._TurnBackTimeTick = 0
}
if currentTimeTick > m1._LastTimeTick {
m1._LastTimeTick = currentTimeTick
m1._CurrentSeqNumber = m1.MinSeqNumber
return m1.CalcId(m1._LastTimeTick)
}
if m1._CurrentSeqNumber > m1.MaxSeqNumber {
m1.BeginOverCostAction(currentTimeTick)
m1._TermIndex++
m1._LastTimeTick++
m1._CurrentSeqNumber = m1.MinSeqNumber
m1._IsOverCost = true
m1._OverCostCountInOneTerm = 1
m1._GenCountInOneTerm = 1
return m1.CalcId(m1._LastTimeTick)
}
return m1.CalcId(m1._LastTimeTick)
}
// CalcID .
func (m1 *SnowWorkerM1) CalcId(useTimeTick int64) uint64 {
result := uint64(useTimeTick<<m1._TimestampShift) + uint64(m1.WorkerId<<m1.SeqBitLength) + uint64(m1._CurrentSeqNumber)
m1._CurrentSeqNumber++
return result
}
// CalcTurnBackID .
func (m1 *SnowWorkerM1) CalcTurnBackId(useTimeTick int64) uint64 {
result := uint64(useTimeTick<<m1._TimestampShift) + uint64(m1.WorkerId<<m1.SeqBitLength) + uint64(m1._TurnBackIndex)
m1._TurnBackTimeTick--
return result
}
// GetCurrentTimeTick .
func (m1 *SnowWorkerM1) GetCurrentTimeTick() int64 {
var millis = time.Now().UnixNano() / 1e6
return millis - m1.BaseTime
}
// GetNextTimeTick .
func (m1 *SnowWorkerM1) GetNextTimeTick() int64 {
tempTimeTicker := m1.GetCurrentTimeTick()
for tempTimeTicker <= m1._LastTimeTick {
tempTimeTicker = m1.GetCurrentTimeTick()
}
return tempTimeTicker
}
// NextId .
func (m1 *SnowWorkerM1) NextId() uint64 {
m1.Lock()
defer m1.Unlock()
if m1._IsOverCost {
return m1.NextOverCostId()
} else {
return m1.NextNormalId()
}
}

View File

@@ -0,0 +1,43 @@
/*
* 版权属于yitter(yitter@126.com)
* 代码编辑guoyahao
* 代码修订yitter
* 开源地址https://gitee.com/yitter/idgenerator
*/
package idgen
import (
"fmt"
"strconv"
)
type SnowWorkerM2 struct {
*SnowWorkerM1
}
func NewSnowWorkerM2(options *IdGeneratorOptions) ISnowWorker {
return &SnowWorkerM2{
NewSnowWorkerM1(options).(*SnowWorkerM1),
}
}
func (m2 SnowWorkerM2) NextId() uint64 {
m2.Lock()
defer m2.Unlock()
currentTimeTick := m2.GetCurrentTimeTick()
if m2._LastTimeTick == currentTimeTick {
m2._CurrentSeqNumber++
if m2._CurrentSeqNumber > m2.MaxSeqNumber {
m2._CurrentSeqNumber = m2.MinSeqNumber
currentTimeTick = m2.GetNextTimeTick()
}
} else {
m2._CurrentSeqNumber = m2.MinSeqNumber
}
if currentTimeTick < m2._LastTimeTick {
fmt.Println("Time error for {0} milliseconds", strconv.FormatInt(m2._LastTimeTick-currentTimeTick, 10))
}
m2._LastTimeTick = currentTimeTick
result := uint64((currentTimeTick << m2._TimestampShift)) + uint64(m2.WorkerId<<m2.SeqBitLength) + uint64(m2._CurrentSeqNumber)
return result
}

View File

@@ -8,7 +8,6 @@ package idgen
import (
"sync"
"yitidgen/contract"
)
//var yitIdHelper *YitIdHelper
@@ -50,7 +49,7 @@ type YitIdHelper struct {
// return yih.idGenInstance.NewLong()
//}
func SetIdGenerator(options *contract.IdGeneratorOptions) {
func SetIdGenerator(options *IdGeneratorOptions) {
singletonMutex.Lock()
idGenerator = NewDefaultIdGenerator(options)
singletonMutex.Unlock()
@@ -59,7 +58,7 @@ func SetIdGenerator(options *contract.IdGeneratorOptions) {
func NextId() uint64 {
if idGenerator == nil {
singletonMutex.Lock()
options := contract.NewIdGeneratorOptions(1)
options := NewIdGeneratorOptions(1)
idGenerator = NewDefaultIdGenerator(options)
singletonMutex.Unlock()
}