重命名 java 为 Java
This commit is contained in:
25
Java/source/.gitignore
vendored
Normal file
25
Java/source/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Compiled class file
|
||||
*.class
|
||||
*.iml
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
target/
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
201
Java/source/LICENSE
Normal file
201
Java/source/LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
93
Java/source/pom.xml
Normal file
93
Java/source/pom.xml
Normal file
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yitter</groupId>
|
||||
<artifactId>yitter.idgenerator</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<name>yitter.idgenerator</name>
|
||||
<description>Shorter ID and faster generation with a new snowflake drift algorithm. The core is to shorten the ID length, but also can have a very high instantaneous concurrent processing capacity (50W/0.1s), and powerful configuration capacity.</description>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>yitter</id>
|
||||
<name>yitter</name>
|
||||
<email>yitter@126.com</email>
|
||||
<url>https://gitee.com/yitter/idgenerator</url>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}</directory>
|
||||
<targetPath>META-INF</targetPath>
|
||||
<includes>
|
||||
<include>LICENSE</include>
|
||||
<include>NOTICE</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>src/test/resources</directory>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</testResource>
|
||||
</testResources>
|
||||
</build>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.contract;
|
||||
|
||||
public interface IIdGenerator {
|
||||
long newLong() throws IdGeneratorException;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.contract;
|
||||
|
||||
public interface ISnowWorker {
|
||||
long nextId() throws IdGeneratorException;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.contract;
|
||||
|
||||
public class IdGeneratorException extends RuntimeException {
|
||||
|
||||
public IdGeneratorException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public IdGeneratorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public IdGeneratorException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
public IdGeneratorException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public IdGeneratorException(String msgFormat, Object... args) {
|
||||
super(String.format(msgFormat, args));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.contract;
|
||||
|
||||
/**
|
||||
* 雪花算法使用的参数
|
||||
* 此处代码不采用 get/set 那种冗长的写法
|
||||
*/
|
||||
public class IdGeneratorOptions {
|
||||
/**
|
||||
* 雪花计算方法
|
||||
* (1-漂移算法|2-传统算法),默认1
|
||||
*/
|
||||
public short Method = 1;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
* 不能超过当前系统时间
|
||||
*/
|
||||
public long StartTime = 0;
|
||||
|
||||
/**
|
||||
* 机器码,必须由外部系统设置
|
||||
* 与 WorkerIdBitLength 有关系
|
||||
*/
|
||||
public short WorkerId = 0;
|
||||
|
||||
/**
|
||||
* 机器码位长
|
||||
* 范围:2-21(要求:序列数位长+机器码位长不超过22)。
|
||||
* 建议范围:6-12。
|
||||
*/
|
||||
public byte WorkerIdBitLength = 6;
|
||||
|
||||
/**
|
||||
* 序列数位长
|
||||
* 范围:2-21(要求:序列数位长+机器码位长不超过22)。
|
||||
* 建议范围:6-14。
|
||||
*/
|
||||
public byte SeqBitLength = 6;
|
||||
|
||||
/**
|
||||
* 最大序列数(含)
|
||||
* (由SeqBitLength计算的最大值)
|
||||
*/
|
||||
public short MaxSeqNumber = 0;
|
||||
|
||||
/**
|
||||
* 最小序列数(含)
|
||||
* 默认11,不小于5,不大于MaxSeqNumber-2
|
||||
*/
|
||||
public short MinSeqNumber = 11;
|
||||
|
||||
/**
|
||||
* 最大漂移次数(含)
|
||||
* 默认2000,推荐范围500-10000(与计算能力有关)
|
||||
*/
|
||||
public short TopOverCostCount = 2000;
|
||||
|
||||
public IdGeneratorOptions() {
|
||||
|
||||
}
|
||||
|
||||
public IdGeneratorOptions(short workerId) {
|
||||
WorkerId = workerId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.contract;
|
||||
|
||||
/**
|
||||
* Id生成时回调参数
|
||||
*/
|
||||
public class OverCostActionArg {
|
||||
|
||||
/**
|
||||
* 事件类型
|
||||
* 1-开始,2-结束,8-漂移
|
||||
*/
|
||||
public int ActionType = 0;
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
public long TimeTick = 0;
|
||||
|
||||
/**
|
||||
* 机器码
|
||||
*/
|
||||
public short WorkerId = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public int OverCostCountInOneTerm = 0;
|
||||
|
||||
/**
|
||||
* 漂移期间生产ID个数
|
||||
*/
|
||||
public int GenCountInOneTerm = 0;
|
||||
|
||||
/**
|
||||
* 漂移周期
|
||||
*/
|
||||
public int TermIndex = 0;
|
||||
|
||||
public OverCostActionArg(short workerId, long timeTick, int actionType, int overCostCountInOneTerm, int genCountWhenOverCost, int index) {
|
||||
ActionType = actionType;
|
||||
TimeTick = timeTick;
|
||||
WorkerId = workerId;
|
||||
OverCostCountInOneTerm = overCostCountInOneTerm;
|
||||
GenCountInOneTerm = genCountWhenOverCost;
|
||||
TermIndex = index;
|
||||
}
|
||||
}
|
||||
247
Java/source/src/main/java/com/yitter/core/SnowWorkerM1.java
Normal file
247
Java/source/src/main/java/com/yitter/core/SnowWorkerM1.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.core;
|
||||
|
||||
import com.yitter.contract.ISnowWorker;
|
||||
import com.yitter.contract.IdGeneratorException;
|
||||
import com.yitter.contract.IdGeneratorOptions;
|
||||
import com.yitter.contract.OverCostActionArg;
|
||||
|
||||
public class SnowWorkerM1 implements ISnowWorker {
|
||||
|
||||
/**
|
||||
* 基础时间
|
||||
*/
|
||||
protected final long StartTimeUtc;
|
||||
|
||||
/**
|
||||
* 机器码
|
||||
*/
|
||||
protected final short WorkerId;
|
||||
|
||||
/**
|
||||
* 机器码位长
|
||||
* (机器码+序列数<=22位)
|
||||
*/
|
||||
protected final byte WorkerIdBitLength;
|
||||
|
||||
/**
|
||||
* 自增序列数位长
|
||||
* (机器码+序列数<=22位)
|
||||
*/
|
||||
protected final byte SeqBitLength;
|
||||
|
||||
/**
|
||||
* 最大序列数(含此值)
|
||||
* 超过最大值,就会从MinSeqNumber开始
|
||||
*/
|
||||
protected final int MaxSeqNumber;
|
||||
|
||||
/**
|
||||
* 最小序列数(含此值)
|
||||
*/
|
||||
protected final short MinSeqNumber;
|
||||
|
||||
/**
|
||||
* 最大漂移次数
|
||||
*/
|
||||
protected final int TopOverCostCount;
|
||||
|
||||
protected final byte _TimestampShift;
|
||||
protected final static byte[] _SyncLock = new byte[0];
|
||||
|
||||
protected short _CurrentSeqNumber;
|
||||
protected long _LastTimeTick = -1L;
|
||||
protected long _TurnBackTimeTick = -1L;
|
||||
protected boolean _IsOverCost = false;
|
||||
protected int _OverCostCountInOneTerm = 0;
|
||||
protected int _GenCountInOneTerm = 0;
|
||||
protected int _TermIndex = 0;
|
||||
|
||||
public SnowWorkerM1(IdGeneratorOptions options) {
|
||||
WorkerId = options.WorkerId;
|
||||
WorkerIdBitLength = options.WorkerIdBitLength == 0 ? 6 : options.WorkerIdBitLength;
|
||||
SeqBitLength = options.SeqBitLength == 0 ? 6 : options.SeqBitLength;
|
||||
MaxSeqNumber = options.MaxSeqNumber > 0 ? options.MaxSeqNumber : (int) Math.pow(2, SeqBitLength);
|
||||
MinSeqNumber = options.MinSeqNumber;
|
||||
TopOverCostCount = options.TopOverCostCount;
|
||||
StartTimeUtc = options.StartTime != 0 ? options.StartTime : 1582136402000L;
|
||||
_TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength);
|
||||
_CurrentSeqNumber = options.MinSeqNumber;
|
||||
}
|
||||
|
||||
private void DoGenIdAction(OverCostActionArg arg) {
|
||||
|
||||
}
|
||||
|
||||
private void BeginOverCostCallBack(long useTimeTick) {
|
||||
// if (GenAction == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// DoGenIdAction(new OverCostActionArg(
|
||||
// WorkerId,
|
||||
// useTimeTick,
|
||||
// 1,
|
||||
// _OverCostCountInOneTerm,
|
||||
// _GenCountInOneTerm,
|
||||
// _TermIndex));
|
||||
}
|
||||
|
||||
private void EndOverCostCallBack(long useTimeTick) {
|
||||
if (_TermIndex > 10000) {
|
||||
_TermIndex = 0;
|
||||
}
|
||||
//
|
||||
// if (GenAction == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// DoGenIdAction(new OverCostActionArg(
|
||||
// WorkerId,
|
||||
// useTimeTick,
|
||||
// 2,
|
||||
// _OverCostCountInOneTerm,
|
||||
// _GenCountInOneTerm,
|
||||
// _TermIndex));
|
||||
}
|
||||
|
||||
private void TurnBackCallBack(long useTimeTick) {
|
||||
// if (GenAction == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// DoGenIdAction(new OverCostActionArg(
|
||||
// WorkerId,
|
||||
// useTimeTick,
|
||||
// 8,
|
||||
// _OverCostCountInOneTerm,
|
||||
// _GenCountInOneTerm,
|
||||
// _TermIndex));
|
||||
}
|
||||
|
||||
private long NextOverCostId() {
|
||||
long currentTimeTick = GetCurrentTimeTick();
|
||||
|
||||
if (currentTimeTick > _LastTimeTick) {
|
||||
EndOverCostCallBack(currentTimeTick);
|
||||
|
||||
_LastTimeTick = currentTimeTick;
|
||||
_CurrentSeqNumber = MinSeqNumber;
|
||||
_IsOverCost = false;
|
||||
_OverCostCountInOneTerm = 0;
|
||||
_GenCountInOneTerm = 0;
|
||||
|
||||
return CalcId(_LastTimeTick);
|
||||
}
|
||||
|
||||
if (_OverCostCountInOneTerm >= TopOverCostCount) {
|
||||
EndOverCostCallBack(currentTimeTick);
|
||||
|
||||
_LastTimeTick = GetNextTimeTick();
|
||||
_CurrentSeqNumber = MinSeqNumber;
|
||||
_IsOverCost = false;
|
||||
_OverCostCountInOneTerm = 0;
|
||||
_GenCountInOneTerm = 0;
|
||||
|
||||
return CalcId(_LastTimeTick);
|
||||
}
|
||||
|
||||
if (_CurrentSeqNumber > MaxSeqNumber) {
|
||||
_LastTimeTick++;
|
||||
_CurrentSeqNumber = MinSeqNumber;
|
||||
_IsOverCost = true;
|
||||
_OverCostCountInOneTerm++;
|
||||
_GenCountInOneTerm++;
|
||||
|
||||
return CalcId(_LastTimeTick);
|
||||
}
|
||||
|
||||
_GenCountInOneTerm++;
|
||||
return CalcId(_LastTimeTick);
|
||||
}
|
||||
|
||||
private long NextNormalId() throws IdGeneratorException {
|
||||
long currentTimeTick = GetCurrentTimeTick();
|
||||
|
||||
if (currentTimeTick > _LastTimeTick) {
|
||||
_LastTimeTick = currentTimeTick;
|
||||
_CurrentSeqNumber = MinSeqNumber;
|
||||
|
||||
return CalcId(_LastTimeTick);
|
||||
}
|
||||
|
||||
if (_CurrentSeqNumber > MaxSeqNumber) {
|
||||
BeginOverCostCallBack(currentTimeTick);
|
||||
|
||||
_TermIndex++;
|
||||
_LastTimeTick++;
|
||||
_CurrentSeqNumber = MinSeqNumber;
|
||||
_IsOverCost = true;
|
||||
_OverCostCountInOneTerm++;
|
||||
_GenCountInOneTerm = 1;
|
||||
|
||||
return CalcId(_LastTimeTick);
|
||||
}
|
||||
|
||||
if (currentTimeTick < _LastTimeTick) {
|
||||
if (_TurnBackTimeTick < 1) {
|
||||
_TurnBackTimeTick = _LastTimeTick - 1;
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
TurnBackCallBack(_TurnBackTimeTick);
|
||||
|
||||
return CalcTurnBackId(_TurnBackTimeTick);
|
||||
}
|
||||
|
||||
return CalcId(_LastTimeTick);
|
||||
}
|
||||
|
||||
private long CalcId(long useTimeTick) {
|
||||
long result = ((useTimeTick << _TimestampShift) +
|
||||
((long) WorkerId << SeqBitLength) +
|
||||
(int) _CurrentSeqNumber);
|
||||
|
||||
_CurrentSeqNumber++;
|
||||
return result;
|
||||
}
|
||||
|
||||
private long CalcTurnBackId(long useTimeTick) {
|
||||
long result = ((useTimeTick << _TimestampShift) +
|
||||
((long) WorkerId << SeqBitLength) + 0);
|
||||
|
||||
_TurnBackTimeTick--;
|
||||
return result;
|
||||
}
|
||||
|
||||
protected long GetCurrentTimeTick() {
|
||||
long millis = System.currentTimeMillis();
|
||||
return millis - StartTimeUtc;
|
||||
}
|
||||
|
||||
protected long GetNextTimeTick() {
|
||||
long tempTimeTicker = GetCurrentTimeTick();
|
||||
|
||||
while (tempTimeTicker <= _LastTimeTick) {
|
||||
tempTimeTicker = GetCurrentTimeTick();
|
||||
}
|
||||
|
||||
return tempTimeTicker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextId() {
|
||||
synchronized (_SyncLock) {
|
||||
return _IsOverCost ? NextOverCostId() : NextNormalId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
Java/source/src/main/java/com/yitter/core/SnowWorkerM2.java
Normal file
41
Java/source/src/main/java/com/yitter/core/SnowWorkerM2.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.core;
|
||||
|
||||
import com.yitter.contract.IdGeneratorException;
|
||||
import com.yitter.contract.IdGeneratorOptions;
|
||||
|
||||
public class SnowWorkerM2 extends SnowWorkerM1 {
|
||||
|
||||
public SnowWorkerM2(IdGeneratorOptions options) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextId() {
|
||||
synchronized (_SyncLock) {
|
||||
long currentTimeTick = GetCurrentTimeTick();
|
||||
|
||||
if (_LastTimeTick == currentTimeTick) {
|
||||
if (_CurrentSeqNumber++ > MaxSeqNumber) {
|
||||
_CurrentSeqNumber = MinSeqNumber;
|
||||
currentTimeTick = GetNextTimeTick();
|
||||
}
|
||||
} else {
|
||||
_CurrentSeqNumber = MinSeqNumber;
|
||||
}
|
||||
|
||||
if (currentTimeTick < _LastTimeTick) {
|
||||
throw new IdGeneratorException("Time error for {0} milliseconds", _LastTimeTick - currentTimeTick);
|
||||
}
|
||||
|
||||
_LastTimeTick = currentTimeTick;
|
||||
long result = ((currentTimeTick << _TimestampShift) + ((long) WorkerId << SeqBitLength) + (int) _CurrentSeqNumber);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.idgen;
|
||||
|
||||
import com.yitter.contract.ISnowWorker;
|
||||
import com.yitter.contract.IdGeneratorException;
|
||||
import com.yitter.contract.IdGeneratorOptions;
|
||||
import com.yitter.contract.IIdGenerator;
|
||||
import com.yitter.core.SnowWorkerM1;
|
||||
import com.yitter.core.SnowWorkerM2;
|
||||
|
||||
|
||||
public class DefaultIdGenerator implements IIdGenerator {
|
||||
|
||||
private final ISnowWorker _SnowWorker;
|
||||
|
||||
public DefaultIdGenerator(IdGeneratorOptions options) throws IdGeneratorException {
|
||||
if (options == null)
|
||||
{
|
||||
throw new IdGeneratorException("options error.");
|
||||
}
|
||||
|
||||
if (options.StartTime > System.currentTimeMillis())
|
||||
{
|
||||
throw new IdGeneratorException("StartTime error.");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
throw new IdGeneratorException("WorkerId error. (range:[1, " + maxWorkerIdNumber + "]");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
throw new IdGeneratorException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]");
|
||||
}
|
||||
|
||||
double maxValue = maxSeqNumber - 2;
|
||||
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxValue)
|
||||
{
|
||||
throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxValue + "]");
|
||||
}
|
||||
|
||||
switch (options.Method)
|
||||
{
|
||||
case 1:
|
||||
_SnowWorker = new SnowWorkerM1(options);
|
||||
break;
|
||||
case 2:
|
||||
_SnowWorker = new SnowWorkerM2(options);
|
||||
break;
|
||||
default:
|
||||
_SnowWorker = new SnowWorkerM1(options);
|
||||
break;
|
||||
}
|
||||
|
||||
if (options.Method == 1)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long newLong() {
|
||||
return _SnowWorker.nextId();
|
||||
}
|
||||
}
|
||||
45
Java/source/src/main/java/com/yitter/idgen/IdHelper.java
Normal file
45
Java/source/src/main/java/com/yitter/idgen/IdHelper.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package com.yitter.idgen;
|
||||
|
||||
import com.yitter.contract.IdGeneratorException;
|
||||
import com.yitter.contract.IdGeneratorOptions;
|
||||
import com.yitter.contract.IIdGenerator;
|
||||
|
||||
/**
|
||||
* 这是一个调用的例子,默认情况下,单机集成者可以直接使用 NewId()。
|
||||
*/
|
||||
public class IdHelper {
|
||||
|
||||
private static IIdGenerator idGenInstance = null;
|
||||
|
||||
public static IIdGenerator getIdGenInstance()
|
||||
{
|
||||
return idGenInstance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置参数,建议程序初始化时执行一次
|
||||
* @param options
|
||||
*/
|
||||
public static void setIdGenerator(IdGeneratorOptions options) throws IdGeneratorException {
|
||||
idGenInstance = new DefaultIdGenerator(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成新的Id
|
||||
* 调用本方法前,请确保调用了 SetIdGenerator 方法做初始化。
|
||||
* @return
|
||||
*/
|
||||
public static long nextId() throws IdGeneratorException {
|
||||
if (idGenInstance == null)
|
||||
{
|
||||
idGenInstance = new DefaultIdGenerator(new IdGeneratorOptions((short)1));
|
||||
}
|
||||
|
||||
return idGenInstance.newLong();
|
||||
}
|
||||
}
|
||||
31
Java/source/src/main/java/com/yitter/test/GenTest.java
Normal file
31
Java/source/src/main/java/com/yitter/test/GenTest.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.yitter.test;
|
||||
|
||||
import com.yitter.contract.IIdGenerator;
|
||||
|
||||
public class GenTest {
|
||||
|
||||
private IIdGenerator IdGen;
|
||||
private int GenIdCount;
|
||||
private int WorkerId;
|
||||
|
||||
public GenTest(IIdGenerator idGen, int genIdCount, int workerId) {
|
||||
GenIdCount = genIdCount;
|
||||
IdGen = idGen;
|
||||
WorkerId = workerId;
|
||||
}
|
||||
|
||||
public void GenStart() {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
for (int i = 0; i < GenIdCount; i++) {
|
||||
long id = IdGen.newLong();
|
||||
}
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
long time = end - start;
|
||||
|
||||
System.out.println("++++++++++++++++++++++++++++++++++++++++WorkerId: "
|
||||
+ WorkerId + ", total: " + time + " ms");
|
||||
|
||||
}
|
||||
}
|
||||
57
Java/source/src/main/java/com/yitter/test/StartUp.java
Normal file
57
Java/source/src/main/java/com/yitter/test/StartUp.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package com.yitter.test;
|
||||
|
||||
import com.yitter.contract.IdGeneratorOptions;
|
||||
import com.yitter.contract.IIdGenerator;
|
||||
import com.yitter.idgen.DefaultIdGenerator;
|
||||
import com.yitter.idgen.IdHelper;
|
||||
|
||||
public class StartUp {
|
||||
|
||||
/**
|
||||
* 测试结果:
|
||||
* (1):1W并发,方法 1只要 1ms.而方法 2 要 180ms。
|
||||
* (2):5W并发,方法 1只要 9ms.而方法 2 要 900ms。
|
||||
* [不同CPU可能结果有差异,但相对大小不变]
|
||||
* 默认配置下,最佳性能是5W/s-8W/s
|
||||
*/
|
||||
final static int genIdCount = 50000;
|
||||
|
||||
//1-漂移算法,2-传统算法
|
||||
final static short method = 1;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
IdGeneratorOptions options = new IdGeneratorOptions();
|
||||
|
||||
//options.TopOverCostCount = 10000;
|
||||
|
||||
// options.WorkerIdBitLength = 6;
|
||||
// options.SeqBitLength = 9;
|
||||
// options.MinSeqNumber = 11;
|
||||
// options.MaxSeqNumber = 200;
|
||||
|
||||
options.Method = method;
|
||||
options.WorkerId = 1;
|
||||
options.StartTime = 1582206693000L; // (2020-2-20)
|
||||
|
||||
IIdGenerator IdGen = new DefaultIdGenerator(options);
|
||||
GenTest genTest = new GenTest(IdGen, genIdCount, options.WorkerId);
|
||||
|
||||
// 首先测试一下 IdHelper 方法,获取单个Id
|
||||
IdHelper.setIdGenerator(options);
|
||||
long newId = IdHelper.nextId();
|
||||
System.out.println("=====================================");
|
||||
System.out.println("这是用方法 " + method + " 生成的 Id:" + newId);
|
||||
|
||||
// 然后循环测试一下,看看并发请求时的耗时情况
|
||||
try {
|
||||
while (true) {
|
||||
genTest.GenStart();
|
||||
Thread.sleep(1000); // 每隔1秒执行一次GenStart
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user