auto commit
This commit is contained in:
@@ -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("error:WorkerIdBitLength + 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 {
|
||||
|
||||
11
Go/source/idgen/IIdGenerator.go
Normal file
11
Go/source/idgen/IIdGenerator.go
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 代码编辑:guoyahao
|
||||
* 代码修订:yitter
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package idgen
|
||||
|
||||
type IIdGenerator interface {
|
||||
NewLong() uint64
|
||||
}
|
||||
11
Go/source/idgen/ISnowWorker.go
Normal file
11
Go/source/idgen/ISnowWorker.go
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 代码编辑:guoyahao
|
||||
* 代码修订:yitter
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package idgen
|
||||
|
||||
type ISnowWorker interface {
|
||||
NextId() uint64
|
||||
}
|
||||
18
Go/source/idgen/IdGeneratorException.go
Normal file
18
Go/source/idgen/IdGeneratorException.go
Normal 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)
|
||||
}
|
||||
31
Go/source/idgen/IdGeneratorOptions.go
Normal file
31
Go/source/idgen/IdGeneratorOptions.go
Normal 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,
|
||||
}
|
||||
}
|
||||
25
Go/source/idgen/OverCostActionArg.go
Normal file
25
Go/source/idgen/OverCostActionArg.go
Normal 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
|
||||
}
|
||||
221
Go/source/idgen/SnowWorkerM1.go
Normal file
221
Go/source/idgen/SnowWorkerM1.go
Normal 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()
|
||||
}
|
||||
}
|
||||
43
Go/source/idgen/SnowWorkerM2.go
Normal file
43
Go/source/idgen/SnowWorkerM2.go
Normal 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
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user