重构StartTime
This commit is contained in:
54
C#/README.md
54
C#/README.md
@@ -20,57 +20,7 @@ var newId = IdHelper.NextId();
|
||||
```
|
||||
如果基于DI框架集成,可以参考 IdHelper 去管理 IdGenerator 对象,必须使用**单例**模式。
|
||||
|
||||
## options说明
|
||||
```
|
||||
public class IdGeneratorOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 雪花计算方法
|
||||
/// (1|2)
|
||||
/// </summary>
|
||||
public short Method { get; set; } = 1;
|
||||
## options 默认值及说明
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间(UTC格式)
|
||||
/// 不能超过当前系统时间
|
||||
/// </summary>
|
||||
public DateTime StartTime { get; set; } = DateTime.MinValue;
|
||||
参考源码:/Contract/IdGeneratorOptions.cs
|
||||
|
||||
/// <summary>
|
||||
/// 机器码
|
||||
/// 与 WorkerIdBitLength 有关系
|
||||
/// </summary>
|
||||
public ushort WorkerId { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 机器码位长
|
||||
/// 范围:2-21(要求:序列数位长+机器码位长不超过22)。
|
||||
/// 建议范围:6-12。
|
||||
/// </summary>
|
||||
public byte WorkerIdBitLength { get; set; } = 6;
|
||||
|
||||
/// <summary>
|
||||
/// 序列数位长
|
||||
/// 范围:2-21(要求:序列数位长+机器码位长不超过22)。
|
||||
/// 建议范围:6-14。
|
||||
/// </summary>
|
||||
public byte SeqBitLength { get; set; } = 6;
|
||||
|
||||
/// <summary>
|
||||
/// 最大序列数(含)
|
||||
/// (由SeqBitLength计算的最大值)
|
||||
/// </summary>
|
||||
public int MaxSeqNumber { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 最小序列数(含)
|
||||
/// 默认11,不小于5,不大于MaxSeqNumber-2
|
||||
/// </summary>
|
||||
public ushort MinSeqNumber { get; set; } = 11;
|
||||
|
||||
/// <summary>
|
||||
/// 最大漂移次数(含),
|
||||
/// 默认2000,推荐范围500-10000(与计算能力有关)
|
||||
/// </summary>
|
||||
public int TopOverCostCount { get; set; } = 2000;
|
||||
```
|
||||
@@ -50,7 +50,7 @@ namespace Yitter.OrgSystem.TestA
|
||||
//MinSeqNumber = 11,
|
||||
//MaxSeqNumber = 200,
|
||||
|
||||
StartTime = DateTime.Now.AddYears(-10),
|
||||
BaseTime = DateTime.Now.AddYears(-10),
|
||||
};
|
||||
|
||||
// ++++++++++++++++++++++++++++++++
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Yitter.IdGenerator
|
||||
/// 开始时间(UTC格式)
|
||||
/// 不能超过当前系统时间
|
||||
/// </summary>
|
||||
public virtual DateTime StartTime { get; set; } = DateTime.MinValue;
|
||||
public virtual DateTime BaseTime { get; set; } = new DateTime(2020, 2, 20, 2, 20, 2, 20, DateTimeKind.Utc);
|
||||
|
||||
/// <summary>
|
||||
/// 机器码
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Yitter.IdGenerator
|
||||
/// <summary>
|
||||
/// 基础时间
|
||||
/// </summary>
|
||||
protected readonly DateTime StartTimeUtc = new DateTime(2020, 2, 20, 2, 20, 2, 20, DateTimeKind.Utc);
|
||||
protected readonly DateTime BaseTime;
|
||||
|
||||
/// <summary>
|
||||
/// 机器码
|
||||
@@ -78,9 +78,9 @@ namespace Yitter.IdGenerator
|
||||
MinSeqNumber = options.MinSeqNumber;
|
||||
TopOverCostCount = options.TopOverCostCount;
|
||||
|
||||
if (options.StartTime != DateTime.MinValue)
|
||||
if (options.BaseTime != DateTime.MinValue)
|
||||
{
|
||||
StartTimeUtc = options.StartTime;
|
||||
BaseTime = options.BaseTime;
|
||||
}
|
||||
|
||||
if (WorkerId < 1)
|
||||
@@ -278,7 +278,7 @@ namespace Yitter.IdGenerator
|
||||
|
||||
protected virtual long GetCurrentTimeTick()
|
||||
{
|
||||
return (long)(DateTime.UtcNow - StartTimeUtc).TotalMilliseconds;
|
||||
return (long)(DateTime.UtcNow - BaseTime).TotalMilliseconds;
|
||||
}
|
||||
|
||||
protected virtual long GetNextTimeTick()
|
||||
|
||||
@@ -35,9 +35,9 @@ namespace Yitter.IdGenerator
|
||||
throw new ApplicationException("options error.");
|
||||
}
|
||||
|
||||
if (options.StartTime > DateTime.Now)
|
||||
if (options.BaseTime < DateTime.Now.AddYears(-50) || options.BaseTime > DateTime.Now)
|
||||
{
|
||||
throw new ApplicationException("StartTime error.");
|
||||
throw new ApplicationException("BaseTime error.");
|
||||
}
|
||||
|
||||
if (options.SeqBitLength + options.WorkerIdBitLength > 22)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<Copyright>Yitter</Copyright>
|
||||
<PackageProjectUrl>https://gitee.com/yitter/idgenerator</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<Version>1.0.3</Version>
|
||||
<Version>1.0.6</Version>
|
||||
<PackageReleaseNotes></PackageReleaseNotes>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
## <20><><EFBFBD>л<EFBFBD><D0BB><EFBFBD>
|
||||
|
||||
JDK 1.8
|
||||
JDK 1.8+
|
||||
|
||||
## <20><><EFBFBD><EFBFBD> maven <20><>
|
||||
```
|
||||
@@ -21,56 +21,8 @@ long newId = IdHelper.nextId();
|
||||
```
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DI<EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD><EFBFBD>ɣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բο<EFBFBD> IdHelper ȥ<><C8A5><EFBFBD><EFBFBD> IdGenerator <20><><EFBFBD><EFBFBD><F3A3ACB1><EFBFBD>ʹ<EFBFBD><CAB9>**<2A><><EFBFBD><EFBFBD>**ģʽ<C4A3><CABD>
|
||||
|
||||
## options˵<73><CBB5>
|
||||
```
|
||||
/**
|
||||
* ѩ<><D1A9><EFBFBD><EFBFBD><EFBFBD>㷽<EFBFBD><E3B7BD>
|
||||
* <20><>1-Ư<><C6AF><EFBFBD>㷨|2-<2D><>ͳ<EFBFBD>㷨<EFBFBD><E3B7A8><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>1
|
||||
*/
|
||||
public short Method = 1;
|
||||
|
||||
/**
|
||||
* <20><>ʼʱ<CABC><CAB1>
|
||||
* <20><><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD><EFBFBD><EFBFBD>ǰϵͳʱ<CDB3><CAB1>
|
||||
*/
|
||||
public long StartTime = 0;
|
||||
## options Ĭ<><C4AC>ֵ<EFBFBD><D6B5>˵<EFBFBD><CBB5>
|
||||
|
||||
/**
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ⲿϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>
|
||||
* <20><> WorkerIdBitLength <20>й<EFBFBD>ϵ
|
||||
*/
|
||||
public short WorkerId = 0;
|
||||
<EFBFBD>ο<EFBFBD>Դ<EFBFBD>룺/contract/IdGeneratorOptions.java
|
||||
|
||||
/**
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
* <20><>Χ<EFBFBD><CEA7>2-21<32><31>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>22<32><32><EFBFBD><EFBFBD>
|
||||
* <20><><EFBFBD>鷶Χ<E9B7B6><CEA7>6-12<31><32>
|
||||
*/
|
||||
public byte WorkerIdBitLength = 6;
|
||||
|
||||
/**
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
* <20><>Χ<EFBFBD><CEA7>2-21<32><31>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>22<32><32><EFBFBD><EFBFBD>
|
||||
* <20><><EFBFBD>鷶Χ<E9B7B6><CEA7>6-14<31><34>
|
||||
*/
|
||||
public byte SeqBitLength = 6;
|
||||
|
||||
/**
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD>SeqBitLength<74><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>
|
||||
*/
|
||||
public short MaxSeqNumber = 0;
|
||||
|
||||
/**
|
||||
* <20><>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* Ĭ<><C4AC>11<31><31><EFBFBD><EFBFBD>С<EFBFBD><D0A1>5<EFBFBD><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MaxSeqNumber-2
|
||||
*/
|
||||
public short MinSeqNumber = 11;
|
||||
|
||||
/**
|
||||
* <20><><EFBFBD><EFBFBD>Ư<EFBFBD>ƴ<EFBFBD><C6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* Ĭ<><C4AC>2000<30><30><EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD>Χ500-10000<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>йأ<D0B9>
|
||||
*/
|
||||
public short TopOverCostCount = 2000;
|
||||
|
||||
```
|
||||
@@ -20,7 +20,7 @@ public class IdGeneratorOptions {
|
||||
* 开始时间
|
||||
* 不能超过当前系统时间
|
||||
*/
|
||||
public long StartTime = 0;
|
||||
public long BaseTime = 1582136402000L;
|
||||
|
||||
/**
|
||||
* 机器码,必须由外部系统设置
|
||||
|
||||
@@ -14,7 +14,7 @@ public class SnowWorkerM1 implements ISnowWorker {
|
||||
/**
|
||||
* 基础时间
|
||||
*/
|
||||
protected final long StartTimeUtc;
|
||||
protected final long BaseTime;
|
||||
|
||||
/**
|
||||
* 机器码
|
||||
@@ -67,7 +67,7 @@ public class SnowWorkerM1 implements ISnowWorker {
|
||||
MaxSeqNumber = options.MaxSeqNumber > 0 ? options.MaxSeqNumber : (int) Math.pow(2, SeqBitLength);
|
||||
MinSeqNumber = options.MinSeqNumber;
|
||||
TopOverCostCount = options.TopOverCostCount;
|
||||
StartTimeUtc = options.StartTime != 0 ? options.StartTime : 1582136402000L;
|
||||
BaseTime = options.BaseTime != 0 ? options.BaseTime : 1582136402000L;
|
||||
_TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength);
|
||||
_CurrentSeqNumber = options.MinSeqNumber;
|
||||
}
|
||||
@@ -224,7 +224,7 @@ public class SnowWorkerM1 implements ISnowWorker {
|
||||
|
||||
protected long GetCurrentTimeTick() {
|
||||
long millis = System.currentTimeMillis();
|
||||
return millis - StartTimeUtc;
|
||||
return millis - BaseTime;
|
||||
}
|
||||
|
||||
protected long GetNextTimeTick() {
|
||||
|
||||
@@ -17,46 +17,38 @@ public class DefaultIdGenerator implements IIdGenerator {
|
||||
private final ISnowWorker _SnowWorker;
|
||||
|
||||
public DefaultIdGenerator(IdGeneratorOptions options) throws IdGeneratorException {
|
||||
if (options == null)
|
||||
{
|
||||
if (options == null) {
|
||||
throw new IdGeneratorException("options error.");
|
||||
}
|
||||
|
||||
if (options.StartTime > System.currentTimeMillis())
|
||||
{
|
||||
throw new IdGeneratorException("StartTime error.");
|
||||
if (options.BaseTime < 315504000000L || options.BaseTime > System.currentTimeMillis()) {
|
||||
throw new IdGeneratorException("BaseTime error.");
|
||||
}
|
||||
|
||||
if (options.SeqBitLength + options.WorkerIdBitLength > 22)
|
||||
{
|
||||
if (options.SeqBitLength + options.WorkerIdBitLength > 22) {
|
||||
throw new IdGeneratorException("error:WorkerIdBitLength + SeqBitLength <= 22");
|
||||
}
|
||||
|
||||
double maxWorkerIdNumber = Math.pow(2, options.WorkerIdBitLength) - 1;
|
||||
if (options.WorkerId < 1 || options.WorkerId > maxWorkerIdNumber)
|
||||
{
|
||||
if (options.WorkerId < 1 || options.WorkerId > maxWorkerIdNumber) {
|
||||
throw new IdGeneratorException("WorkerId error. (range:[1, " + maxWorkerIdNumber + "]");
|
||||
}
|
||||
|
||||
if (options.SeqBitLength < 2 || options.SeqBitLength > 21)
|
||||
{
|
||||
if (options.SeqBitLength < 2 || options.SeqBitLength > 21) {
|
||||
throw new IdGeneratorException("SeqBitLength error. (range:[2, 21])");
|
||||
}
|
||||
|
||||
double maxSeqNumber = Math.pow(2, options.SeqBitLength) - 1;
|
||||
if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber)
|
||||
{
|
||||
if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) {
|
||||
throw new IdGeneratorException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]");
|
||||
}
|
||||
|
||||
double maxValue = maxSeqNumber - 2;
|
||||
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxValue)
|
||||
{
|
||||
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxValue) {
|
||||
throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxValue + "]");
|
||||
}
|
||||
|
||||
switch (options.Method)
|
||||
{
|
||||
switch (options.Method) {
|
||||
case 1:
|
||||
_SnowWorker = new SnowWorkerM1(options);
|
||||
break;
|
||||
@@ -68,8 +60,7 @@ public class DefaultIdGenerator implements IIdGenerator {
|
||||
break;
|
||||
}
|
||||
|
||||
if (options.Method == 1)
|
||||
{
|
||||
if (options.Method == 1) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
@@ -79,7 +70,7 @@ public class DefaultIdGenerator implements IIdGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long newLong() {
|
||||
public long newLong() {
|
||||
return _SnowWorker.nextId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package com.yitter.test;
|
||||
|
||||
import com.yitter.contract.IIdGenerator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class GenTest {
|
||||
|
||||
private IIdGenerator IdGen;
|
||||
private int GenIdCount;
|
||||
private int WorkerId;
|
||||
private Set IdSet = new HashSet();
|
||||
|
||||
public GenTest(IIdGenerator idGen, int genIdCount, int workerId) {
|
||||
GenIdCount = genIdCount;
|
||||
@@ -19,6 +22,7 @@ public class GenTest {
|
||||
|
||||
for (int i = 0; i < GenIdCount; i++) {
|
||||
long id = IdGen.newLong();
|
||||
// IdSet.add(id);
|
||||
}
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
@@ -31,7 +31,7 @@ public class StartUp {
|
||||
// options.MaxSeqNumber = 200;
|
||||
|
||||
options.Method = method;
|
||||
options.StartTime = 1582206693000L; // (2020-2-20)
|
||||
options.BaseTime = 1582206693000L;
|
||||
options.WorkerId = 1;
|
||||
|
||||
IIdGenerator IdGen = new DefaultIdGenerator(options);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# IdGenerator
|
||||
|
||||
## 介绍
|
||||
用一种全新的雪花漂移算法,让ID更短、生成速度更快。
|
||||
核心在于缩短ID长度的同时,还能拥有极高瞬时并发处理量(50W/0.1s),及强大的配置能力。
|
||||
用一种全新的雪花漂移算法,让ID更短、生成速度更快。
|
||||
核心在于缩短ID长度的同时,还能拥有极高瞬时并发处理量(50W/0.1s)。
|
||||
顶尖优化,超强效能(位数更短,速度更快),全新 SnowFlake 算法,支持 C#/Java/Go/PHP 等语言。
|
||||
|
||||
## 需求来源
|
||||
|
||||
@@ -138,7 +139,7 @@
|
||||
|
||||
配置变更指是系统运行一段时间后,再变更运行参数(IdGeneratorOptions选项值),请注意:
|
||||
|
||||
1.最重要的一条原则是:StartTime **只能往前**(比老值更小、距离现在更远)赋值,原因是往后赋值极大可能产生相同的时间戳。[**不推荐**在系统运行之后调整 StartTime]
|
||||
1.最重要的一条原则是:BaseTime **只能往前**(比老值更小、距离现在更远)赋值,原因是往后赋值极大可能产生相同的时间戳。[**不推荐**在系统运行之后调整 BaseTime]
|
||||
|
||||
2.任何时候增加 WorkerIdBitLength 或 SeqBitLength,都是可以的,但是慎用 “减小”的操作,因为这可能导致在未来某天生成的 ID 与过去老配置时相同。[允许在系统运行之后**增加**任何一个 BitLength 值]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user