@@ -12,7 +12,7 @@ namespace Yitter.OrgSystem.TestA | |||
class Program | |||
{ | |||
// 测试参数(默认配置下,最佳性能是10W/s) | |||
static int genIdCount = 500000;//5000; // 计算ID数量(如果要验证50W效率,请将TopOverCostCount设置为2000或适当增加SeqBitLength) | |||
static int genIdCount = 50000;//5000; // 计算ID数量(如果要验证50W效率,请将TopOverCostCount设置为2000或适当增加SeqBitLength) | |||
static short method = 1; // 1-漂移算法,2-传统算法 | |||
@@ -39,7 +39,7 @@ namespace Yitter.OrgSystem.TestA | |||
WorkerIdBitLength = 6, | |||
SeqBitLength = 6, | |||
DataCenterIdBitLength = 10, | |||
DataCenterIdBitLength = 0, | |||
TopOverCostCount = 2000, | |||
//TimestampType = 1, | |||
@@ -142,8 +142,8 @@ namespace Yitter.OrgSystem.TestA | |||
//WorkerIdBitLength = 6, | |||
SeqBitLength = 6, | |||
//DataCenterIdBitLength = 0, | |||
//TopOverCostCount = 2000, | |||
//DataCenterIdBitLength = 0, | |||
//TimestampType = 1, | |||
// MinSeqNumber = 1, | |||
@@ -63,7 +63,6 @@ namespace Yitter.IdGenerator | |||
/// </summary> | |||
public virtual int TopOverCostCount { get; set; } = 2000; | |||
/// <summary> | |||
/// 数据中心ID(默认0) | |||
/// </summary> | |||
@@ -118,10 +118,10 @@ namespace Yitter.IdGenerator | |||
// 7.Others | |||
TopOverCostCount = options.TopOverCostCount; | |||
if (TopOverCostCount == 0) | |||
{ | |||
TopOverCostCount = 2000; | |||
} | |||
//if (TopOverCostCount == 0) | |||
//{ | |||
// TopOverCostCount = 2000; | |||
//} | |||
_TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | |||
_CurrentSeqNumber = options.MinSeqNumber; | |||
@@ -92,6 +92,12 @@ namespace Yitter.IdGenerator | |||
throw new ApplicationException("MinSeqNumber error. (range:[5, " + maxSeqNumber + "]"); | |||
} | |||
// 7.TopOverCostCount | |||
if (options.TopOverCostCount < 0 || options.TopOverCostCount > 10000) | |||
{ | |||
throw new ApplicationException("TopOverCostCount error. (range:[0, 10000]"); | |||
} | |||
switch (options.Method) | |||
{ | |||
case 2: | |||
@@ -9,107 +9,147 @@ | |||
#include <unistd.h> | |||
#include "IdGenerator.h" | |||
static inline uint64_t WorkerM1Id() { | |||
static inline uint64_t WorkerM1Id() | |||
{ | |||
return WorkerM1NextId(_idGenerator->Worker); | |||
} | |||
static inline uint64_t WorkerM2Id() { | |||
static inline uint64_t WorkerM2Id() | |||
{ | |||
return WorkerM2NextId(_idGenerator->Worker); | |||
} | |||
extern IdGenerator *GetIdGenInstance() { | |||
extern IdGenerator *GetIdGenInstance() | |||
{ | |||
if (_idGenerator != NULL) | |||
return _idGenerator; | |||
else { | |||
_idGenerator = (IdGenerator *) malloc(sizeof(IdGenerator)); | |||
else | |||
{ | |||
_idGenerator = (IdGenerator *)malloc(sizeof(IdGenerator)); | |||
_idGenerator->Worker = NewSnowFlakeWorker(); | |||
return _idGenerator; | |||
} | |||
} | |||
extern void SetOptions(IdGeneratorOptions options) { | |||
if (GetIdGenInstance() == NULL) { | |||
extern void SetOptions(IdGeneratorOptions options) | |||
{ | |||
if (GetIdGenInstance() == NULL) | |||
{ | |||
exit(1); | |||
} | |||
// 1.BaseTime | |||
if (options.BaseTime == 0) { | |||
if (options.BaseTime == 0) | |||
{ | |||
_idGenerator->Worker->BaseTime = 1582136402000; | |||
} else if (options.BaseTime < 631123200000 || options.BaseTime > GetCurrentTime()) { | |||
} | |||
else if (options.BaseTime < 631123200000 || options.BaseTime > GetCurrentTime()) | |||
{ | |||
perror("BaseTime error."); | |||
exit(1); | |||
} else { | |||
} | |||
else | |||
{ | |||
_idGenerator->Worker->BaseTime = options.BaseTime; | |||
} | |||
// 2.WorkerIdBitLength | |||
if (options.WorkerIdBitLength <= 0) { | |||
if (options.WorkerIdBitLength <= 0) | |||
{ | |||
perror("WorkerIdBitLength error.(range:[1, 21])"); | |||
exit(1); | |||
} | |||
if (options.SeqBitLength + options.WorkerIdBitLength > 22) { | |||
if (options.SeqBitLength + options.WorkerIdBitLength > 22) | |||
{ | |||
perror("error:WorkerIdBitLength + SeqBitLength <= 22"); | |||
exit(1); | |||
} else { | |||
} | |||
else | |||
{ | |||
// _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength; | |||
_idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength <= 0 ? 6 : options.WorkerIdBitLength; | |||
} | |||
// 3.WorkerId | |||
uint32_t maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; | |||
if (maxWorkerIdNumber == 0) { | |||
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]}"); | |||
exit(1); | |||
} else { | |||
} | |||
else | |||
{ | |||
_idGenerator->Worker->WorkerId = options.WorkerId; | |||
} | |||
// 4.SeqBitLength | |||
if (options.SeqBitLength < 2 || options.SeqBitLength > 21) { | |||
if (options.SeqBitLength < 2 || options.SeqBitLength > 21) | |||
{ | |||
perror("SeqBitLength error. (range:[2, 21])"); | |||
exit(1); | |||
} else { | |||
} | |||
else | |||
{ | |||
// _idGenerator->Worker->SeqBitLength = options.SeqBitLength; | |||
_idGenerator->Worker->SeqBitLength = options.SeqBitLength <= 0 ? 6 : options.SeqBitLength; | |||
} | |||
// 5.MaxSeqNumber | |||
uint32_t maxSeqNumber = (1 << options.SeqBitLength) - 1; | |||
if (maxSeqNumber == 0) { | |||
if (maxSeqNumber == 0) | |||
{ | |||
maxSeqNumber = 63; | |||
} | |||
if (options.MaxSeqNumber > maxSeqNumber) { | |||
if (options.MaxSeqNumber > maxSeqNumber) | |||
{ | |||
perror("MaxSeqNumber error. (range:[1, {2^options.SeqBitLength-1}]"); | |||
exit(1); | |||
} else { | |||
} | |||
else | |||
{ | |||
_idGenerator->Worker->MaxSeqNumber = options.MaxSeqNumber <= 0 ? maxSeqNumber : options.MaxSeqNumber; | |||
} | |||
// 6.MinSeqNumber | |||
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) { | |||
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) | |||
{ | |||
perror("MinSeqNumber error. (range:[5, {options.MinSeqNumber}]"); | |||
exit(1); | |||
} else { | |||
} | |||
else | |||
{ | |||
_idGenerator->Worker->MinSeqNumber = options.MinSeqNumber <= 0 ? 5 : options.MinSeqNumber; | |||
} | |||
// 7.Others | |||
_idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount; | |||
// 7.TopOverCostCount | |||
if (options.TopOverCostCount < 0 || options.TopOverCostCount > 10000) | |||
{ | |||
perror("TopOverCostCount error. (range:[0, 10000]"); | |||
exit(1); | |||
} | |||
else | |||
{ | |||
//_idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount; | |||
_idGenerator->Worker->TopOverCostCount = options.TopOverCostCount; | |||
} | |||
// 8.Others | |||
_idGenerator->Worker->_TimestampShift = | |||
_idGenerator->Worker->WorkerIdBitLength + _idGenerator->Worker->SeqBitLength; | |||
_idGenerator->Worker->WorkerIdBitLength + _idGenerator->Worker->SeqBitLength; | |||
_idGenerator->Worker->_CurrentSeqNumber = _idGenerator->Worker->MinSeqNumber; | |||
_idGenerator->Worker->Method = options.Method; | |||
if (options.Method == 2) { | |||
if (options.Method == 2) | |||
{ | |||
_idGenerator->NextId = WorkerM2Id; | |||
} else { | |||
} | |||
else | |||
{ | |||
_idGenerator->NextId = WorkerM1Id; | |||
usleep(500*1000); // 暂停500ms | |||
usleep(500 * 1000); // 暂停500ms | |||
} | |||
} | |||
@@ -4,6 +4,7 @@ | |||
* 代码修订:yitter | |||
* 开源地址:https://github.com/yitter/idgenerator | |||
*/ | |||
package idgen | |||
import ( | |||
@@ -64,6 +65,11 @@ func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator { | |||
panic("MinSeqNumber error. (range:[5, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]") | |||
} | |||
// 7.TopOverCostCount | |||
if options.TopOverCostCount < 0 || options.TopOverCostCount > 10000 { | |||
panic("TopOverCostCount error. (range:[0, 10000]") | |||
} | |||
var snowWorker ISnowWorker | |||
switch options.Method { | |||
case 1: | |||
@@ -4,6 +4,7 @@ | |||
* 代码修订:yitter | |||
* 开源地址:https://github.com/yitter/idgenerator | |||
*/ | |||
package idgen | |||
import ( | |||
@@ -13,13 +14,13 @@ import ( | |||
// SnowWorkerM1 . | |||
type SnowWorkerM1 struct { | |||
BaseTime int64 //基础时间 | |||
WorkerId uint16 //机器码 | |||
WorkerIdBitLength byte //机器码位长 | |||
SeqBitLength byte //自增序列数位长 | |||
MaxSeqNumber uint32 //最大序列数(含) | |||
MinSeqNumber uint32 //最小序列数(含) | |||
TopOverCostCount uint32 //最大漂移次数 | |||
BaseTime int64 // 基础时间 | |||
WorkerId uint16 // 机器码 | |||
WorkerIdBitLength byte // 机器码位长 | |||
SeqBitLength byte // 自增序列数位长 | |||
MaxSeqNumber uint32 // 最大序列数(含) | |||
MinSeqNumber uint32 // 最小序列数(含) | |||
TopOverCostCount uint32 // 最大漂移次数 | |||
_TimestampShift byte | |||
_CurrentSeqNumber uint32 | |||
@@ -75,12 +76,13 @@ func NewSnowWorkerM1(options *IdGeneratorOptions) ISnowWorker { | |||
// 6.MinSeqNumber | |||
var minSeqNumber = options.MinSeqNumber | |||
// 7.Others | |||
// 7.TopOverCostCount | |||
var topOverCostCount = options.TopOverCostCount | |||
if topOverCostCount == 0 { | |||
topOverCostCount = 2000 | |||
} | |||
// if topOverCostCount == 0 { | |||
// topOverCostCount = 2000 | |||
// } | |||
// 8.Others | |||
timestampShift := (byte)(workerIdBitLength + seqBitLength) | |||
currentSeqNumber := minSeqNumber | |||
@@ -66,7 +66,8 @@ public class SnowWorkerM1 implements ISnowWorker { | |||
SeqBitLength = options.SeqBitLength == 0 ? 6 : options.SeqBitLength; | |||
MaxSeqNumber = options.MaxSeqNumber <= 0 ? (1 << SeqBitLength) - 1 : options.MaxSeqNumber; | |||
MinSeqNumber = options.MinSeqNumber; | |||
TopOverCostCount = options.TopOverCostCount == 0 ? 2000 : options.TopOverCostCount; | |||
// TopOverCostCount = options.TopOverCostCount == 0 ? 2000 : options.TopOverCostCount; | |||
TopOverCostCount = options.TopOverCostCount; | |||
_TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength); | |||
_CurrentSeqNumber = MinSeqNumber; | |||
} | |||
@@ -150,11 +151,11 @@ public class SnowWorkerM1 implements ISnowWorker { | |||
BeginTurnBackAction(_TurnBackTimeTick); | |||
} | |||
// try { | |||
// Thread.sleep(1); | |||
// } catch (InterruptedException e) { | |||
// e.printStackTrace(); | |||
// } | |||
// try { | |||
// Thread.sleep(1); | |||
// } catch (InterruptedException e) { | |||
// e.printStackTrace(); | |||
// } | |||
return CalcTurnBackId(_TurnBackTimeTick); | |||
} | |||
@@ -214,7 +215,7 @@ public class SnowWorkerM1 implements ISnowWorker { | |||
long tempTimeTicker = GetCurrentTimeTick(); | |||
while (tempTimeTicker <= _LastTimeTick) { | |||
try { | |||
try { | |||
Thread.sleep(1); | |||
} catch (InterruptedException e) { | |||
e.printStackTrace(); | |||
@@ -232,4 +233,3 @@ public class SnowWorkerM1 implements ISnowWorker { | |||
} | |||
} | |||
} | |||
@@ -11,7 +11,6 @@ import com.github.yitter.contract.IdGeneratorOptions; | |||
import com.github.yitter.core.SnowWorkerM1; | |||
import com.github.yitter.core.SnowWorkerM2; | |||
public class DefaultIdGenerator implements IIdGenerator { | |||
private static ISnowWorker _SnowWorker = null; | |||
@@ -40,7 +39,8 @@ public class DefaultIdGenerator implements IIdGenerator { | |||
maxWorkerIdNumber = 63; | |||
} | |||
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 | |||
@@ -62,6 +62,11 @@ public class DefaultIdGenerator implements IIdGenerator { | |||
throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxSeqNumber + "]"); | |||
} | |||
// 7.TopOverCostCount | |||
if (options.TopOverCostCount < 0 || options.TopOverCostCount > 10000) { | |||
throw new IdGeneratorException("TopOverCostCount error. (range:[0, 10000]"); | |||
} | |||
switch (options.Method) { | |||
case 2: | |||
_SnowWorker = new SnowWorkerM2(options); | |||
@@ -26,7 +26,7 @@ public class GenTest { | |||
long end = System.currentTimeMillis(); | |||
long time = end - start; | |||
System.out.println(id); | |||
// System.out.println(id); | |||
System.out.println("++++++++++++++++++++++++++++++++++++++++WorkerId: " | |||
+ WorkerId + ", total: " + time + " ms"); | |||
@@ -25,7 +25,7 @@ public class StartUp { | |||
// options.BaseTime = 1582206693000L; | |||
options.Method = method; | |||
options.WorkerId = 1; | |||
options.TopOverCostCount=2000; | |||
// options.TopOverCostCount=2000; | |||
// 首先测试一下 IdHelper 方法,获取单个Id | |||
YitIdHelper.setIdGenerator(options); | |||
@@ -39,7 +39,7 @@ public class StartUp { | |||
while (true) { | |||
genTest.GenStart(); | |||
Thread.sleep(1000); // 每隔1秒执行一次GenStart | |||
System.out.println("Hello World! Java"); | |||
// System.out.println("Hello World! Java"); | |||
} | |||
} catch (InterruptedException e) { | |||
e.printStackTrace(); | |||
@@ -2,10 +2,10 @@ | |||
* 版权属于:yitter(yitter@126.com) | |||
* 开源地址:https://github.com/yitter/idgenerator | |||
*/ | |||
use std::{thread}; | |||
use crate::idgen::*; | |||
use chrono::Utc; | |||
use std::thread; | |||
use std::thread::sleep; | |||
use crate::idgen::*; | |||
// use lazy_static::lazy_static; | |||
pub struct SnowWorkerM1 { | |||
@@ -42,26 +42,30 @@ impl SnowWorkerM1 { | |||
} | |||
pub fn SetOptions(&mut self, options: IdGeneratorOptions) { | |||
// 1.BaseTime | |||
if options.BaseTime == 0 { | |||
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() | |||
{ | |||
panic!("BaseTime error."); | |||
} else { | |||
self.BaseTime = options.BaseTime; | |||
} | |||
// 2.WorkerIdBitLength | |||
if options.WorkerIdBitLength <= 0 | |||
{ | |||
if options.WorkerIdBitLength <= 0 { | |||
panic!("WorkerIdBitLength error.(range:[1, 21])"); | |||
} | |||
if options.SeqBitLength + options.WorkerIdBitLength > 22 { | |||
panic!("error:WorkerIdBitLength + SeqBitLength <= 22"); | |||
} else { | |||
// self.WorkerIdBitLength = options.WorkerIdBitLength; | |||
self.WorkerIdBitLength = if options.WorkerIdBitLength <= 0 { 6 } else { options.WorkerIdBitLength }; | |||
self.WorkerIdBitLength = if options.WorkerIdBitLength <= 0 { | |||
6 | |||
} else { | |||
options.WorkerIdBitLength | |||
}; | |||
} | |||
// 3.WorkerId | |||
@@ -80,7 +84,11 @@ impl SnowWorkerM1 { | |||
panic!("SeqBitLength error. (range:[2, 21])"); | |||
} else { | |||
// self.SeqBitLength = options.SeqBitLength; | |||
self.SeqBitLength = if options.SeqBitLength <= 0 { 6 } else { options.SeqBitLength }; | |||
self.SeqBitLength = if options.SeqBitLength <= 0 { | |||
6 | |||
} else { | |||
options.SeqBitLength | |||
}; | |||
} | |||
// 5.MaxSeqNumber | |||
@@ -91,7 +99,11 @@ impl SnowWorkerM1 { | |||
if options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber { | |||
panic!("MaxSeqNumber error. (range:[1, {}]", maxSeqNumber); | |||
} else { | |||
self.MaxSeqNumber = if options.MaxSeqNumber == 0 { maxSeqNumber } else { options.MaxSeqNumber }; | |||
self.MaxSeqNumber = if options.MaxSeqNumber == 0 { | |||
maxSeqNumber | |||
} else { | |||
options.MaxSeqNumber | |||
}; | |||
} | |||
// 6.MinSeqNumber | |||
@@ -102,8 +114,15 @@ impl SnowWorkerM1 { | |||
// self.MinSeqNumber = if options.MinSeqNumber <= 0 { 5 } else { options.MinSeqNumber }; | |||
} | |||
// 7.Others | |||
self.TopOverCostCount = if options.TopOverCostCount == 0 { 2000 } else { options.TopOverCostCount }; | |||
// 7.TopOverCostCount | |||
//self.TopOverCostCount = if options.TopOverCostCount == 0 { 2000 } else { options.TopOverCostCount }; | |||
if options.TopOverCostCount < 0 || options.TopOverCostCount > 10000 { | |||
panic!("TopOverCostCount error. (range:[0, 10000]"); | |||
} else { | |||
self.TopOverCostCount = options.TopOverCostCount; | |||
} | |||
// 8.Others | |||
self._TimestampShift = self.WorkerIdBitLength + self.SeqBitLength; | |||
self._CurrentSeqNumber = self.MinSeqNumber; | |||
@@ -139,7 +158,11 @@ impl SnowWorkerM1 { | |||
pub fn NextId(&mut self) -> i64 { | |||
// println!("SeqBitLength: {}", self.SeqBitLength); | |||
if self._IsOverCost { self.NextOverCostId() } else { self.NextNormalId() } | |||
if self._IsOverCost { | |||
self.NextOverCostId() | |||
} else { | |||
self.NextNormalId() | |||
} | |||
} | |||
fn DoGenIdAction(&self, arg: OverCostActionArg) {} | |||
@@ -247,17 +270,17 @@ impl SnowWorkerM1 { | |||
} | |||
fn CalcId(&mut self, useTimeTick: i64) -> i64 { | |||
let result = (useTimeTick << self._TimestampShift) + | |||
(self.WorkerId << self.SeqBitLength) as i64 + | |||
(self._CurrentSeqNumber) as i64; | |||
let result = (useTimeTick << self._TimestampShift) | |||
+ (self.WorkerId << self.SeqBitLength) as i64 | |||
+ (self._CurrentSeqNumber) as i64; | |||
self._CurrentSeqNumber += 1; | |||
return result; | |||
} | |||
fn CalcTurnBackId(&mut self, useTimeTick: i64) -> i64 { | |||
let result = (useTimeTick << self._TimestampShift) + | |||
(self.WorkerId << self.SeqBitLength) as i64 + | |||
(self._TurnBackIndex) as i64; | |||
let result = (useTimeTick << self._TimestampShift) | |||
+ (self.WorkerId << self.SeqBitLength) as i64 | |||
+ (self._TurnBackIndex) as i64; | |||
self._TurnBackTimeTick -= 1; | |||
return result; | |||
} | |||
@@ -277,4 +300,4 @@ impl SnowWorkerM1 { | |||
return tempTimeTicker; | |||
} | |||
} | |||
} |