| @@ -56,7 +56,7 @@ namespace Yitter.IdGenerator | |||||
| /// <summary> | /// <summary> | ||||
| /// 最小序列数(含) | /// 最小序列数(含) | ||||
| /// 默认5,不小于1,不大于MaxSeqNumber | |||||
| /// 默认5,不小于5,不大于MaxSeqNumber | |||||
| /// </summary> | /// </summary> | ||||
| public virtual ushort MinSeqNumber { get; set; } = 5; | public virtual ushort MinSeqNumber { get; set; } = 5; | ||||
| @@ -57,8 +57,8 @@ namespace Yitter.IdGenerator | |||||
| protected static object _SyncLock = new object(); | protected static object _SyncLock = new object(); | ||||
| protected ushort _CurrentSeqNumber; | protected ushort _CurrentSeqNumber; | ||||
| protected long _LastTimeTick = -1L; | |||||
| protected long _TurnBackTimeTick = -1L; | |||||
| protected long _LastTimeTick = 0; // -1L | |||||
| protected long _TurnBackTimeTick = 0; // -1L; | |||||
| protected byte _TurnBackIndex = 0; | protected byte _TurnBackIndex = 0; | ||||
| protected bool _IsOverCost = false; | protected bool _IsOverCost = false; | ||||
| @@ -73,34 +73,56 @@ namespace Yitter.IdGenerator | |||||
| public SnowWorkerM1(IdGeneratorOptions options) | public SnowWorkerM1(IdGeneratorOptions options) | ||||
| { | |||||
| WorkerId = options.WorkerId; | |||||
| WorkerIdBitLength = options.WorkerIdBitLength; | |||||
| SeqBitLength = options.SeqBitLength; | |||||
| MaxSeqNumber = options.MaxSeqNumber; | |||||
| MinSeqNumber = options.MinSeqNumber; | |||||
| TopOverCostCount = options.TopOverCostCount; | |||||
| { | |||||
| // 1.BaseTime | |||||
| if (options.BaseTime != DateTime.MinValue) | if (options.BaseTime != DateTime.MinValue) | ||||
| { | { | ||||
| BaseTime = options.BaseTime; | BaseTime = options.BaseTime; | ||||
| } | |||||
| if (SeqBitLength == 0) | |||||
| } | |||||
| // 2.WorkerIdBitLength | |||||
| if (options.WorkerIdBitLength == 0) | |||||
| { | |||||
| WorkerIdBitLength = 6; | |||||
| } | |||||
| else | |||||
| { | |||||
| WorkerIdBitLength = options.WorkerIdBitLength; | |||||
| } | |||||
| // 3.WorkerId | |||||
| WorkerId = options.WorkerId; | |||||
| // 4.SeqBitLength | |||||
| if (options.SeqBitLength == 0) | |||||
| { | { | ||||
| SeqBitLength = 6; | SeqBitLength = 6; | ||||
| } | |||||
| if (WorkerIdBitLength == 0) | |||||
| } | |||||
| else | |||||
| { | { | ||||
| WorkerIdBitLength = 6; | |||||
| } | |||||
| SeqBitLength = options.SeqBitLength; | |||||
| } | |||||
| // 5.MaxSeqNumber | |||||
| if (MaxSeqNumber == 0) | if (MaxSeqNumber == 0) | ||||
| { | { | ||||
| MaxSeqNumber = (1 << SeqBitLength) - 1; | MaxSeqNumber = (1 << SeqBitLength) - 1; | ||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| MaxSeqNumber = options.MaxSeqNumber; | |||||
| } | |||||
| // 6.MinSeqNumber | |||||
| MinSeqNumber = options.MinSeqNumber; | |||||
| // 7.Others | |||||
| TopOverCostCount = options.TopOverCostCount; | |||||
| if (TopOverCostCount == 0) | |||||
| { | |||||
| TopOverCostCount = 2000; | |||||
| } | |||||
| _TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | _TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | ||||
| _CurrentSeqNumber = options.MinSeqNumber; | _CurrentSeqNumber = options.MinSeqNumber; | ||||
| @@ -35,11 +35,13 @@ namespace Yitter.IdGenerator | |||||
| throw new ApplicationException("options error."); | throw new ApplicationException("options error."); | ||||
| } | } | ||||
| // 1.BaseTime | |||||
| if (options.BaseTime < DateTime.Now.AddYears(-50) || options.BaseTime > DateTime.Now) | if (options.BaseTime < DateTime.Now.AddYears(-50) || options.BaseTime > DateTime.Now) | ||||
| { | { | ||||
| throw new ApplicationException("BaseTime error."); | throw new ApplicationException("BaseTime error."); | ||||
| } | } | ||||
| // 2.WorkerIdBitLength | |||||
| if (options.WorkerIdBitLength <= 0) | if (options.WorkerIdBitLength <= 0) | ||||
| { | { | ||||
| throw new ApplicationException("WorkerIdBitLength error.(range:[1, 21])"); | throw new ApplicationException("WorkerIdBitLength error.(range:[1, 21])"); | ||||
| @@ -49,27 +51,38 @@ namespace Yitter.IdGenerator | |||||
| throw new ApplicationException("error:WorkerIdBitLength + SeqBitLength <= 22"); | throw new ApplicationException("error:WorkerIdBitLength + SeqBitLength <= 22"); | ||||
| } | } | ||||
| // 3.WorkerId | |||||
| var maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | var maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | ||||
| if (maxWorkerIdNumber == 0) | |||||
| { | |||||
| maxWorkerIdNumber = 63; | |||||
| } | |||||
| if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) | if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) | ||||
| { | { | ||||
| throw new ApplicationException("WorkerId error. (range:[0, " + (maxWorkerIdNumber > 0 ? maxWorkerIdNumber : 63) + "]"); | |||||
| throw new ApplicationException("WorkerId error. (range:[0, " + maxWorkerIdNumber + "]"); | |||||
| } | } | ||||
| // 4.SeqBitLength | |||||
| if (options.SeqBitLength < 2 || options.SeqBitLength > 21) | if (options.SeqBitLength < 2 || options.SeqBitLength > 21) | ||||
| { | { | ||||
| throw new ApplicationException("SeqBitLength error. (range:[2, 21])"); | throw new ApplicationException("SeqBitLength error. (range:[2, 21])"); | ||||
| } | } | ||||
| // 5.MaxSeqNumber | |||||
| var maxSeqNumber = (1 << options.SeqBitLength) - 1; | var maxSeqNumber = (1 << options.SeqBitLength) - 1; | ||||
| if (maxSeqNumber == 0) | |||||
| { | |||||
| maxSeqNumber = 63; | |||||
| } | |||||
| if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) | if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) | ||||
| { | { | ||||
| throw new ApplicationException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]"); | throw new ApplicationException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]"); | ||||
| } | } | ||||
| var maxValue = maxSeqNumber; | |||||
| if (options.MinSeqNumber < 1 || options.MinSeqNumber > maxValue) | |||||
| // 6.MinSeqNumber | |||||
| if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) | |||||
| { | { | ||||
| throw new ApplicationException("MinSeqNumber error. (range:[1, " + maxValue + "]"); | |||||
| throw new ApplicationException("MinSeqNumber error. (range:[5, " + maxSeqNumber + "]"); | |||||
| } | } | ||||
| switch (options.Method) | switch (options.Method) | ||||
| @@ -18,7 +18,7 @@ | |||||
| <Copyright>Yitter</Copyright> | <Copyright>Yitter</Copyright> | ||||
| <PackageProjectUrl>https://github.com/yitter/idgenerator</PackageProjectUrl> | <PackageProjectUrl>https://github.com/yitter/idgenerator</PackageProjectUrl> | ||||
| <PackageLicenseExpression>MIT</PackageLicenseExpression> | <PackageLicenseExpression>MIT</PackageLicenseExpression> | ||||
| <Version>1.0.10</Version> | |||||
| <Version>1.0.11</Version> | |||||
| <PackageReleaseNotes></PackageReleaseNotes> | <PackageReleaseNotes></PackageReleaseNotes> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| @@ -34,7 +34,7 @@ extern void SetOptions(IdGeneratorOptions options) { | |||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| // BaseTime | |||||
| // 1.BaseTime | |||||
| if (options.BaseTime == 0) { | if (options.BaseTime == 0) { | ||||
| _idGenerator->Worker->BaseTime = 1582136402000; | _idGenerator->Worker->BaseTime = 1582136402000; | ||||
| } else if (options.BaseTime < 631123200000 || options.BaseTime > GetCurrentTime()) { | } else if (options.BaseTime < 631123200000 || options.BaseTime > GetCurrentTime()) { | ||||
| @@ -44,7 +44,7 @@ extern void SetOptions(IdGeneratorOptions options) { | |||||
| _idGenerator->Worker->BaseTime = options.BaseTime; | _idGenerator->Worker->BaseTime = options.BaseTime; | ||||
| } | } | ||||
| // WorkerIdBitLength | |||||
| // 2.WorkerIdBitLength | |||||
| if (options.WorkerIdBitLength <= 0) { | if (options.WorkerIdBitLength <= 0) { | ||||
| perror("WorkerIdBitLength error.(range:[1, 21])"); | perror("WorkerIdBitLength error.(range:[1, 21])"); | ||||
| exit(1); | exit(1); | ||||
| @@ -53,12 +53,15 @@ extern void SetOptions(IdGeneratorOptions options) { | |||||
| perror("error:WorkerIdBitLength + SeqBitLength <= 22"); | perror("error:WorkerIdBitLength + SeqBitLength <= 22"); | ||||
| exit(1); | exit(1); | ||||
| } else { | } else { | ||||
| // _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength; | |||||
| // _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength; | |||||
| _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength <= 0 ? 6 : options.WorkerIdBitLength; | _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength <= 0 ? 6 : options.WorkerIdBitLength; | ||||
| } | } | ||||
| // WorkerId | |||||
| // 3.WorkerId | |||||
| uint32_t maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | uint32_t maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | ||||
| if (maxWorkerIdNumber == 0) { | |||||
| maxWorkerIdNumber = 63; | |||||
| } | |||||
| if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) { | if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) { | ||||
| perror("WorkerId error. (range:[0, {2^options.WorkerIdBitLength-1]}"); | perror("WorkerId error. (range:[0, {2^options.WorkerIdBitLength-1]}"); | ||||
| exit(1); | exit(1); | ||||
| @@ -66,17 +69,20 @@ extern void SetOptions(IdGeneratorOptions options) { | |||||
| _idGenerator->Worker->WorkerId = options.WorkerId; | _idGenerator->Worker->WorkerId = options.WorkerId; | ||||
| } | } | ||||
| // SeqBitLength | |||||
| // 4.SeqBitLength | |||||
| if (options.SeqBitLength < 2 || options.SeqBitLength > 21) { | if (options.SeqBitLength < 2 || options.SeqBitLength > 21) { | ||||
| perror("SeqBitLength error. (range:[2, 21])"); | perror("SeqBitLength error. (range:[2, 21])"); | ||||
| exit(1); | exit(1); | ||||
| } else { | } else { | ||||
| // _idGenerator->Worker->SeqBitLength = options.SeqBitLength; | |||||
| // _idGenerator->Worker->SeqBitLength = options.SeqBitLength; | |||||
| _idGenerator->Worker->SeqBitLength = options.SeqBitLength <= 0 ? 6 : options.SeqBitLength; | _idGenerator->Worker->SeqBitLength = options.SeqBitLength <= 0 ? 6 : options.SeqBitLength; | ||||
| } | } | ||||
| // MaxSeqNumber | |||||
| // 5.MaxSeqNumber | |||||
| uint32_t maxSeqNumber = (1 << options.SeqBitLength) - 1; | uint32_t maxSeqNumber = (1 << options.SeqBitLength) - 1; | ||||
| if (maxSeqNumber == 0) { | |||||
| maxSeqNumber = 63; | |||||
| } | |||||
| if (options.MaxSeqNumber > maxSeqNumber) { | if (options.MaxSeqNumber > maxSeqNumber) { | ||||
| perror("MaxSeqNumber error. (range:[1, {2^options.SeqBitLength-1}]"); | perror("MaxSeqNumber error. (range:[1, {2^options.SeqBitLength-1}]"); | ||||
| exit(1); | exit(1); | ||||
| @@ -84,17 +90,19 @@ extern void SetOptions(IdGeneratorOptions options) { | |||||
| _idGenerator->Worker->MaxSeqNumber = options.MaxSeqNumber <= 0 ? maxSeqNumber : options.MaxSeqNumber; | _idGenerator->Worker->MaxSeqNumber = options.MaxSeqNumber <= 0 ? maxSeqNumber : options.MaxSeqNumber; | ||||
| } | } | ||||
| // MinSeqNumber | |||||
| if (options.MinSeqNumber > maxSeqNumber || options.MinSeqNumber < 5) { | |||||
| // 6.MinSeqNumber | |||||
| if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) { | |||||
| perror("MinSeqNumber error. (range:[5, {options.MinSeqNumber}]"); | perror("MinSeqNumber error. (range:[5, {options.MinSeqNumber}]"); | ||||
| exit(1); | exit(1); | ||||
| } else { | } else { | ||||
| _idGenerator->Worker->MinSeqNumber = options.MinSeqNumber <= 0 ? 5 : options.MinSeqNumber; | _idGenerator->Worker->MinSeqNumber = options.MinSeqNumber <= 0 ? 5 : options.MinSeqNumber; | ||||
| } | } | ||||
| // 7.Others | |||||
| _idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount; | _idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount; | ||||
| _idGenerator->Worker->_TimestampShift = options.WorkerIdBitLength + options.SeqBitLength; | |||||
| _idGenerator->Worker->_CurrentSeqNumber = options.MinSeqNumber; | |||||
| _idGenerator->Worker->_TimestampShift = | |||||
| _idGenerator->Worker->WorkerIdBitLength + _idGenerator->Worker->SeqBitLength; | |||||
| _idGenerator->Worker->_CurrentSeqNumber = _idGenerator->Worker->MinSeqNumber; | |||||
| _idGenerator->Worker->Method = options.Method; | _idGenerator->Worker->Method = options.Method; | ||||
| if (options.Method == 2) { | if (options.Method == 2) { | ||||
| @@ -22,36 +22,49 @@ func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator { | |||||
| panic("dig.Options error.") | panic("dig.Options error.") | ||||
| } | } | ||||
| // 1.BaseTime | |||||
| minTime := int64(631123200000) // time.Now().AddDate(-30, 0, 0).UnixNano() / 1e6 | minTime := int64(631123200000) // time.Now().AddDate(-30, 0, 0).UnixNano() / 1e6 | ||||
| if options.BaseTime < minTime || options.BaseTime > time.Now().UnixNano()/1e6 { | if options.BaseTime < minTime || options.BaseTime > time.Now().UnixNano()/1e6 { | ||||
| panic("BaseTime error.") | panic("BaseTime error.") | ||||
| } | } | ||||
| if options.SeqBitLength+options.WorkerIdBitLength > 22 { | |||||
| // 2.WorkerIdBitLength | |||||
| if options.WorkerIdBitLength <= 0 { | |||||
| panic("WorkerIdBitLength error.(range:[1, 21])") | |||||
| } | |||||
| if options.WorkerIdBitLength+options.SeqBitLength > 22 { | |||||
| panic("error:WorkerIdBitLength + SeqBitLength <= 22") | panic("error:WorkerIdBitLength + SeqBitLength <= 22") | ||||
| } | } | ||||
| maxWorkerIDNumber := uint16(1<<options.WorkerIdBitLength) - 1 | |||||
| if options.WorkerId > maxWorkerIDNumber { | |||||
| panic("WorkerId error. (range:[1, " + strconv.FormatUint(uint64(maxWorkerIDNumber), 10) + "]") | |||||
| // 3.WorkerId | |||||
| maxWorkerIdNumber := uint16(1<<options.WorkerIdBitLength) - 1 | |||||
| if maxWorkerIdNumber == 0 { | |||||
| maxWorkerIdNumber = 63 | |||||
| } | |||||
| if options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber { | |||||
| panic("WorkerId error. (range:[0, " + strconv.FormatUint(uint64(maxWorkerIdNumber), 10) + "]") | |||||
| } | } | ||||
| // 4.SeqBitLength | |||||
| if options.SeqBitLength < 2 || options.SeqBitLength > 21 { | if options.SeqBitLength < 2 || options.SeqBitLength > 21 { | ||||
| panic("SeqBitLength error. (range:[2, 21])") | panic("SeqBitLength error. (range:[2, 21])") | ||||
| } | } | ||||
| // 5.MaxSeqNumber | |||||
| maxSeqNumber := uint32(1<<options.SeqBitLength) - 1 | maxSeqNumber := uint32(1<<options.SeqBitLength) - 1 | ||||
| if options.MaxSeqNumber > maxSeqNumber { | |||||
| if maxSeqNumber == 0 { | |||||
| maxSeqNumber = 63 | |||||
| } | |||||
| if options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber { | |||||
| panic("MaxSeqNumber error. (range:[1, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]") | panic("MaxSeqNumber error. (range:[1, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]") | ||||
| } | } | ||||
| if options.MinSeqNumber > maxSeqNumber { | |||||
| panic("MinSeqNumber error. (range:[1, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]") | |||||
| // 6.MinSeqNumber | |||||
| if options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber { | |||||
| panic("MinSeqNumber error. (range:[5, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]") | |||||
| } | } | ||||
| var snowWorker ISnowWorker | var snowWorker ISnowWorker | ||||
| switch options.Method { | switch options.Method { | ||||
| case 1: | case 1: | ||||
| snowWorker = NewSnowWorkerM1(options) | snowWorker = NewSnowWorkerM1(options) | ||||
| @@ -64,6 +77,7 @@ func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator { | |||||
| if options.Method == 1 { | if options.Method == 1 { | ||||
| time.Sleep(time.Duration(500) * time.Microsecond) | time.Sleep(time.Duration(500) * time.Microsecond) | ||||
| } | } | ||||
| return &DefaultIdGenerator{ | return &DefaultIdGenerator{ | ||||
| Options: options, | Options: options, | ||||
| SnowWorker: snowWorker, | SnowWorker: snowWorker, | ||||
| @@ -13,15 +13,16 @@ import ( | |||||
| // SnowWorkerM1 . | // SnowWorkerM1 . | ||||
| type SnowWorkerM1 struct { | type SnowWorkerM1 struct { | ||||
| BaseTime int64 //基础时间 | |||||
| WorkerId uint16 //机器码 | |||||
| WorkerIdBitLength byte //机器码位长 | |||||
| SeqBitLength byte //自增序列数位长 | |||||
| MaxSeqNumber uint32 //最大序列数(含) | |||||
| MinSeqNumber uint32 //最小序列数(含) | |||||
| TopOverCostCount uint32 //最大漂移次数 | |||||
| _TimestampShift byte | |||||
| _CurrentSeqNumber uint32 | |||||
| BaseTime int64 //基础时间 | |||||
| WorkerId uint16 //机器码 | |||||
| WorkerIdBitLength byte //机器码位长 | |||||
| SeqBitLength byte //自增序列数位长 | |||||
| MaxSeqNumber uint32 //最大序列数(含) | |||||
| MinSeqNumber uint32 //最小序列数(含) | |||||
| TopOverCostCount uint32 //最大漂移次数 | |||||
| _TimestampShift byte | |||||
| _CurrentSeqNumber uint32 | |||||
| _LastTimeTick int64 | _LastTimeTick int64 | ||||
| _TurnBackTimeTick int64 | _TurnBackTimeTick int64 | ||||
| _TurnBackIndex byte | _TurnBackIndex byte | ||||
| @@ -29,6 +30,7 @@ type SnowWorkerM1 struct { | |||||
| _OverCostCountInOneTerm uint32 | _OverCostCountInOneTerm uint32 | ||||
| _GenCountInOneTerm uint32 | _GenCountInOneTerm uint32 | ||||
| _TermIndex uint32 | _TermIndex uint32 | ||||
| sync.Mutex | sync.Mutex | ||||
| } | } | ||||
| @@ -38,46 +40,69 @@ func NewSnowWorkerM1(options *IdGeneratorOptions) ISnowWorker { | |||||
| var seqBitLength byte | var seqBitLength byte | ||||
| var maxSeqNumber uint32 | var maxSeqNumber uint32 | ||||
| var workerId = options.WorkerId | |||||
| // 1.BaseTime | |||||
| var baseTime int64 | |||||
| if options.BaseTime != 0 { | |||||
| baseTime = options.BaseTime | |||||
| } else { | |||||
| baseTime = 1582136402000 | |||||
| } | |||||
| // 2.WorkerIdBitLength | |||||
| if options.WorkerIdBitLength == 0 { | if options.WorkerIdBitLength == 0 { | ||||
| workerIdBitLength = 6 | workerIdBitLength = 6 | ||||
| } else { | } else { | ||||
| workerIdBitLength = options.WorkerIdBitLength | workerIdBitLength = options.WorkerIdBitLength | ||||
| } | } | ||||
| // 3.WorkerId | |||||
| var workerId = options.WorkerId | |||||
| // 4.SeqBitLength | |||||
| if options.SeqBitLength == 0 { | if options.SeqBitLength == 0 { | ||||
| seqBitLength = 6 | seqBitLength = 6 | ||||
| } else { | } else { | ||||
| seqBitLength = options.SeqBitLength | seqBitLength = options.SeqBitLength | ||||
| } | } | ||||
| if options.MaxSeqNumber > 0 { | |||||
| maxSeqNumber = options.MaxSeqNumber | |||||
| } else { | |||||
| // 5.MaxSeqNumber | |||||
| if options.MaxSeqNumber <= 0 { | |||||
| maxSeqNumber = (1 << seqBitLength) - 1 | maxSeqNumber = (1 << seqBitLength) - 1 | ||||
| } else { | |||||
| maxSeqNumber = options.MaxSeqNumber | |||||
| } | } | ||||
| // 6.MinSeqNumber | |||||
| var minSeqNumber = options.MinSeqNumber | var minSeqNumber = options.MinSeqNumber | ||||
| var topOverCostCount = options.TopOverCostCount | |||||
| var baseTime int64 | |||||
| if options.BaseTime != 0 { | |||||
| baseTime = options.BaseTime | |||||
| } else { | |||||
| baseTime = 1582136402000 | |||||
| // 7.Others | |||||
| var topOverCostCount = options.TopOverCostCount | |||||
| if topOverCostCount == 0 { | |||||
| topOverCostCount = 2000 | |||||
| } | } | ||||
| timestampShift := (byte)(options.WorkerIdBitLength + options.SeqBitLength) | |||||
| currentSeqNumber := options.MinSeqNumber | |||||
| timestampShift := (byte)(workerIdBitLength + seqBitLength) | |||||
| currentSeqNumber := minSeqNumber | |||||
| return &SnowWorkerM1{ | return &SnowWorkerM1{ | ||||
| BaseTime: baseTime, | BaseTime: baseTime, | ||||
| WorkerId: workerId, | |||||
| WorkerIdBitLength: workerIdBitLength, | WorkerIdBitLength: workerIdBitLength, | ||||
| WorkerId: workerId, | |||||
| SeqBitLength: seqBitLength, | SeqBitLength: seqBitLength, | ||||
| MaxSeqNumber: maxSeqNumber, | MaxSeqNumber: maxSeqNumber, | ||||
| MinSeqNumber: minSeqNumber, | MinSeqNumber: minSeqNumber, | ||||
| TopOverCostCount: topOverCostCount, | TopOverCostCount: topOverCostCount, | ||||
| _TimestampShift: timestampShift, | _TimestampShift: timestampShift, | ||||
| _CurrentSeqNumber: currentSeqNumber} | |||||
| _CurrentSeqNumber: currentSeqNumber, | |||||
| _LastTimeTick: 0, | |||||
| _TurnBackTimeTick: 0, | |||||
| _TurnBackIndex: 0, | |||||
| _IsOverCost: false, | |||||
| _OverCostCountInOneTerm: 0, | |||||
| _GenCountInOneTerm: 0, | |||||
| _TermIndex: 0, | |||||
| } | |||||
| } | } | ||||
| // DoGenIDAction . | // DoGenIDAction . | ||||
| @@ -1,34 +1,34 @@ | |||||
| ## 运行环境 | |||||
| ## 杩愯�鐜�� | |||||
| JDK 1.8+ | JDK 1.8+ | ||||
| ## 引用 maven 包 | |||||
| ## 寮曠敤 maven 鍖� | |||||
| ``` | ``` | ||||
| <dependency> | <dependency> | ||||
| <groupId>com.github.yitter</groupId> | <groupId>com.github.yitter</groupId> | ||||
| <artifactId>yitter-idgenerator</artifactId> | <artifactId>yitter-idgenerator</artifactId> | ||||
| <version>1.0.3</version> | |||||
| <version>1.0.5</version> | |||||
| </dependency> | </dependency> | ||||
| ``` | ``` | ||||
| ## 调用示例 | |||||
| ## 璋冪敤绀轰緥 | |||||
| ``` | ``` | ||||
| // 全局初始化设置WorkerId,默认最大2^16-1,可通过调整 WorkerIdBitLength 增加最大值 | |||||
| // 鍏ㄥ眬鍒濆�鍖栬�缃甒orkerId锛岄粯璁ゆ渶澶�2^16-1锛屽彲閫氳繃璋冩暣 WorkerIdBitLength 澧炲姞鏈€澶у€� | |||||
| IdGeneratorOptions options = new IdGeneratorOptions(); | IdGeneratorOptions options = new IdGeneratorOptions(); | ||||
| options.WorkerId = 1; | options.WorkerId = 1; | ||||
| YitIdHelper.setIdGenerator(options); | YitIdHelper.setIdGenerator(options); | ||||
| // 以上初始化过程全局只需一次,且必须最先设置 | |||||
| // 浠ヤ笂鍒濆�鍖栬繃绋嬪叏灞€鍙�渶涓€娆★紝涓斿繀椤绘渶鍏堣�缃� | |||||
| // 初始化以后,即可在需要生成ID的地方,调用以下方法。 | |||||
| // 鍒濆�鍖栦互鍚庯紝鍗冲彲鍦ㄩ渶瑕佺敓鎴怚D鐨勫湴鏂癸紝璋冪敤浠ヤ笅鏂规硶銆� | |||||
| long newId = YitIdHelper.nextId(); | long newId = YitIdHelper.nextId(); | ||||
| ``` | ``` | ||||
| 如果基于DI框架集成,可以参考 YitIdHelper 去管理 IdGenerator 对象,须使用**单例**模式。 | |||||
| 濡傛灉鍩轰簬DI妗嗘灦闆嗘垚锛屽彲浠ュ弬鑰� YitIdHelper 鍘荤�鐞� IdGenerator 瀵硅薄锛岄』浣跨敤**鍗曚緥**妯″紡銆� | |||||
| ## options 默认值及说明 | |||||
| ## options 榛樿�鍊煎強璇存槑 | |||||
| 参考源码:/contract/IdGeneratorOptions.java | |||||
| 鍙傝€冩簮鐮侊細/contract/IdGeneratorOptions.java | |||||
| @@ -6,7 +6,7 @@ | |||||
| <groupId>com.github.yitter</groupId> | <groupId>com.github.yitter</groupId> | ||||
| <artifactId>yitter-idgenerator</artifactId> | <artifactId>yitter-idgenerator</artifactId> | ||||
| <version>1.0.4-SNAPSHOT</version> | |||||
| <version>1.0.5</version> | |||||
| <packaging>jar</packaging> | <packaging>jar</packaging> | ||||
| <name>yitter-idgenerator</name> | <name>yitter-idgenerator</name> | ||||
| @@ -50,8 +50,8 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
| protected final static byte[] _SyncLock = new byte[0]; | protected final static byte[] _SyncLock = new byte[0]; | ||||
| protected short _CurrentSeqNumber; | protected short _CurrentSeqNumber; | ||||
| protected long _LastTimeTick = -1L; | |||||
| protected long _TurnBackTimeTick = -1L; | |||||
| protected long _LastTimeTick = 0; | |||||
| protected long _TurnBackTimeTick = 0; | |||||
| protected byte _TurnBackIndex = 0; | protected byte _TurnBackIndex = 0; | ||||
| protected boolean _IsOverCost = false; | protected boolean _IsOverCost = false; | ||||
| @@ -60,15 +60,15 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
| protected int _TermIndex = 0; | protected int _TermIndex = 0; | ||||
| public SnowWorkerM1(IdGeneratorOptions options) { | public SnowWorkerM1(IdGeneratorOptions options) { | ||||
| WorkerId = options.WorkerId; | |||||
| BaseTime = options.BaseTime != 0 ? options.BaseTime : 1582136402000L; | |||||
| WorkerIdBitLength = options.WorkerIdBitLength == 0 ? 6 : options.WorkerIdBitLength; | WorkerIdBitLength = options.WorkerIdBitLength == 0 ? 6 : options.WorkerIdBitLength; | ||||
| WorkerId = options.WorkerId; | |||||
| SeqBitLength = options.SeqBitLength == 0 ? 6 : options.SeqBitLength; | SeqBitLength = options.SeqBitLength == 0 ? 6 : options.SeqBitLength; | ||||
| MaxSeqNumber = options.MaxSeqNumber > 0 ? options.MaxSeqNumber : (1 << SeqBitLength) - 1; | |||||
| MaxSeqNumber = options.MaxSeqNumber <= 0 ? (1 << SeqBitLength) - 1 : options.MaxSeqNumber; | |||||
| MinSeqNumber = options.MinSeqNumber; | MinSeqNumber = options.MinSeqNumber; | ||||
| TopOverCostCount = options.TopOverCostCount; | |||||
| BaseTime = options.BaseTime != 0 ? options.BaseTime : 1582136402000L; | |||||
| TopOverCostCount = options.TopOverCostCount == 0 ? 2000 : options.TopOverCostCount; | |||||
| _TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength); | _TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength); | ||||
| _CurrentSeqNumber = options.MinSeqNumber; | |||||
| _CurrentSeqNumber = MinSeqNumber; | |||||
| } | } | ||||
| private void DoGenIdAction(OverCostActionArg arg) { | private void DoGenIdAction(OverCostActionArg arg) { | ||||
| @@ -182,11 +182,12 @@ public class SnowWorkerM1 implements ISnowWorker { | |||||
| BeginTurnBackAction(_TurnBackTimeTick); | BeginTurnBackAction(_TurnBackTimeTick); | ||||
| } | } | ||||
| try { | |||||
| // Thread.sleep(1); | |||||
| } catch (InterruptedException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| // try { | |||||
| // Thread.sleep(1); | |||||
| // } catch (InterruptedException e) { | |||||
| // e.printStackTrace(); | |||||
| // } | |||||
| return CalcTurnBackId(_TurnBackTimeTick); | return CalcTurnBackId(_TurnBackTimeTick); | ||||
| } | } | ||||
| @@ -21,34 +21,45 @@ public class DefaultIdGenerator implements IIdGenerator { | |||||
| throw new IdGeneratorException("options error."); | throw new IdGeneratorException("options error."); | ||||
| } | } | ||||
| // 1.BaseTime | |||||
| if (options.BaseTime < 315504000000L || options.BaseTime > System.currentTimeMillis()) { | if (options.BaseTime < 315504000000L || options.BaseTime > System.currentTimeMillis()) { | ||||
| throw new IdGeneratorException("BaseTime error."); | throw new IdGeneratorException("BaseTime error."); | ||||
| } | } | ||||
| // 2.WorkerIdBitLength | |||||
| if (options.WorkerIdBitLength <= 0) { | if (options.WorkerIdBitLength <= 0) { | ||||
| throw new IdGeneratorException("WorkerIdBitLength error.(range:[1, 21])"); | throw new IdGeneratorException("WorkerIdBitLength error.(range:[1, 21])"); | ||||
| } | } | ||||
| if (options.SeqBitLength + options.WorkerIdBitLength > 22) { | |||||
| if (options.WorkerIdBitLength + options.SeqBitLength > 22) { | |||||
| throw new IdGeneratorException("error:WorkerIdBitLength + SeqBitLength <= 22"); | throw new IdGeneratorException("error:WorkerIdBitLength + SeqBitLength <= 22"); | ||||
| } | } | ||||
| // 3.WorkerId | |||||
| int maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | int maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | ||||
| if (maxWorkerIdNumber == 0) { | |||||
| maxWorkerIdNumber = 63; | |||||
| } | |||||
| if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) { | if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) { | ||||
| throw new IdGeneratorException("WorkerId error. (range:[0, " + (maxWorkerIdNumber > 0 ? maxWorkerIdNumber : 63) + "]"); | throw new IdGeneratorException("WorkerId error. (range:[0, " + (maxWorkerIdNumber > 0 ? maxWorkerIdNumber : 63) + "]"); | ||||
| } | } | ||||
| // 4.SeqBitLength | |||||
| if (options.SeqBitLength < 2 || options.SeqBitLength > 21) { | if (options.SeqBitLength < 2 || options.SeqBitLength > 21) { | ||||
| throw new IdGeneratorException("SeqBitLength error. (range:[2, 21])"); | throw new IdGeneratorException("SeqBitLength error. (range:[2, 21])"); | ||||
| } | } | ||||
| // 5.MaxSeqNumber | |||||
| int maxSeqNumber = (1 << options.SeqBitLength) - 1; | int maxSeqNumber = (1 << options.SeqBitLength) - 1; | ||||
| if (maxSeqNumber == 0) { | |||||
| maxSeqNumber = 63; | |||||
| } | |||||
| if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) { | if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) { | ||||
| throw new IdGeneratorException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]"); | throw new IdGeneratorException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]"); | ||||
| } | } | ||||
| int maxValue = maxSeqNumber; | |||||
| if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxValue) { | |||||
| throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxValue + "]"); | |||||
| // 6.MinSeqNumber | |||||
| if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) { | |||||
| throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxSeqNumber + "]"); | |||||
| } | } | ||||
| switch (options.Method) { | switch (options.Method) { | ||||
| @@ -53,3 +53,5 @@ public class StartUp { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| // mvn clean deploy -P release | |||||
| @@ -43,7 +43,7 @@ impl SnowWorkerM1 { | |||||
| pub fn SetOptions(&mut self, options: IdGeneratorOptions) { | pub fn SetOptions(&mut self, options: IdGeneratorOptions) { | ||||
| // BaseTime | |||||
| // 1.BaseTime | |||||
| if options.BaseTime == 0 { | if options.BaseTime == 0 { | ||||
| self.BaseTime = 1582136402000; | self.BaseTime = 1582136402000; | ||||
| } else if options.BaseTime < 631123200000 || options.BaseTime > Utc::now().timestamp_millis() { | } else if options.BaseTime < 631123200000 || options.BaseTime > Utc::now().timestamp_millis() { | ||||
| @@ -52,7 +52,7 @@ impl SnowWorkerM1 { | |||||
| self.BaseTime = options.BaseTime; | self.BaseTime = options.BaseTime; | ||||
| } | } | ||||
| // WorkerIdBitLength | |||||
| // 2.WorkerIdBitLength | |||||
| if options.WorkerIdBitLength <= 0 | if options.WorkerIdBitLength <= 0 | ||||
| { | { | ||||
| panic!("WorkerIdBitLength error.(range:[1, 21])"); | panic!("WorkerIdBitLength error.(range:[1, 21])"); | ||||
| @@ -64,15 +64,18 @@ impl SnowWorkerM1 { | |||||
| self.WorkerIdBitLength = if options.WorkerIdBitLength <= 0 { 6 } else { options.WorkerIdBitLength }; | self.WorkerIdBitLength = if options.WorkerIdBitLength <= 0 { 6 } else { options.WorkerIdBitLength }; | ||||
| } | } | ||||
| // WorkerId | |||||
| let maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | |||||
| // 3.WorkerId | |||||
| let mut maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | |||||
| if maxWorkerIdNumber == 0 { | |||||
| maxWorkerIdNumber = 63; | |||||
| } | |||||
| if options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber { | if options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber { | ||||
| panic!("WorkerId error. (range:[0, {} ]", if maxWorkerIdNumber <= 0 { 63 } else { maxWorkerIdNumber }); | |||||
| panic!("WorkerId error. (range:[0, {} ]", maxWorkerIdNumber); | |||||
| } else { | } else { | ||||
| self.WorkerId = options.WorkerId; | self.WorkerId = options.WorkerId; | ||||
| } | } | ||||
| // SeqBitLength | |||||
| // 4.SeqBitLength | |||||
| if options.SeqBitLength < 2 || options.SeqBitLength > 21 { | if options.SeqBitLength < 2 || options.SeqBitLength > 21 { | ||||
| panic!("SeqBitLength error. (range:[2, 21])"); | panic!("SeqBitLength error. (range:[2, 21])"); | ||||
| } else { | } else { | ||||
| @@ -80,24 +83,29 @@ impl SnowWorkerM1 { | |||||
| self.SeqBitLength = if options.SeqBitLength <= 0 { 6 } else { options.SeqBitLength }; | self.SeqBitLength = if options.SeqBitLength <= 0 { 6 } else { options.SeqBitLength }; | ||||
| } | } | ||||
| // MaxSeqNumber | |||||
| let maxSeqNumber = (1 << options.SeqBitLength) - 1; | |||||
| if options.MaxSeqNumber > maxSeqNumber { | |||||
| // 5.MaxSeqNumber | |||||
| let mut maxSeqNumber = (1 << options.SeqBitLength) - 1; | |||||
| if maxSeqNumber == 0 { | |||||
| maxSeqNumber = 63; | |||||
| } | |||||
| if options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber { | |||||
| panic!("MaxSeqNumber error. (range:[1, {}]", maxSeqNumber); | panic!("MaxSeqNumber error. (range:[1, {}]", maxSeqNumber); | ||||
| } else { | } else { | ||||
| self.MaxSeqNumber = if options.MaxSeqNumber <= 0 { maxSeqNumber } else { options.MaxSeqNumber }; | |||||
| self.MaxSeqNumber = if options.MaxSeqNumber == 0 { maxSeqNumber } else { options.MaxSeqNumber }; | |||||
| } | } | ||||
| // MinSeqNumber | |||||
| if options.MinSeqNumber > maxSeqNumber || options.MinSeqNumber < 5 { | |||||
| // 6.MinSeqNumber | |||||
| if options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber { | |||||
| panic!("MinSeqNumber error. (range:[5, {}]", maxSeqNumber); | panic!("MinSeqNumber error. (range:[5, {}]", maxSeqNumber); | ||||
| } else { | } else { | ||||
| self.MinSeqNumber = if options.MinSeqNumber <= 0 { 5 } else { options.MinSeqNumber }; | |||||
| self.MinSeqNumber = options.MinSeqNumber; | |||||
| // self.MinSeqNumber = if options.MinSeqNumber <= 0 { 5 } else { options.MinSeqNumber }; | |||||
| } | } | ||||
| // 7.Others | |||||
| self.TopOverCostCount = if options.TopOverCostCount == 0 { 2000 } else { options.TopOverCostCount }; | self.TopOverCostCount = if options.TopOverCostCount == 0 { 2000 } else { options.TopOverCostCount }; | ||||
| self._TimestampShift = options.WorkerIdBitLength + options.SeqBitLength; | |||||
| self._CurrentSeqNumber = options.MinSeqNumber; | |||||
| self._TimestampShift = self.WorkerIdBitLength + self.SeqBitLength; | |||||
| self._CurrentSeqNumber = self.MinSeqNumber; | |||||
| if options.Method == 1 { | if options.Method == 1 { | ||||
| sleep(std::time::Duration::from_millis(500)); | sleep(std::time::Duration::from_millis(500)); | ||||
| @@ -107,14 +115,15 @@ impl SnowWorkerM1 { | |||||
| pub fn New(options: IdGeneratorOptions) -> SnowWorkerM1 { | pub fn New(options: IdGeneratorOptions) -> SnowWorkerM1 { | ||||
| let mut worker = SnowWorkerM1 { | let mut worker = SnowWorkerM1 { | ||||
| BaseTime: 1582136402000, | BaseTime: 1582136402000, | ||||
| WorkerId: 0, | |||||
| WorkerIdBitLength: 0, | WorkerIdBitLength: 0, | ||||
| WorkerId: 0, | |||||
| SeqBitLength: 0, | SeqBitLength: 0, | ||||
| MaxSeqNumber: 0, | MaxSeqNumber: 0, | ||||
| MinSeqNumber: 0, | MinSeqNumber: 0, | ||||
| TopOverCostCount: 0, | TopOverCostCount: 0, | ||||
| _TimestampShift: 0, | _TimestampShift: 0, | ||||
| _CurrentSeqNumber: 0, | _CurrentSeqNumber: 0, | ||||
| _LastTimeTick: 0, | _LastTimeTick: 0, | ||||
| _TurnBackTimeTick: 0, | _TurnBackTimeTick: 0, | ||||
| _TurnBackIndex: 0, | _TurnBackIndex: 0, | ||||