-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix #162 finish the algorithm of self-id-generator
- Loading branch information
Showing
15 changed files
with
720 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
...g-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/id/generator/IdGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright 1999-2015 dangdang.com. | ||
* <p> | ||
* 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. | ||
* </p> | ||
*/ | ||
|
||
package com.dangdang.ddframe.rdb.sharding.id.generator; | ||
|
||
/** | ||
* Id 生成接口. | ||
* | ||
* @author gaohongtao | ||
*/ | ||
public interface IdGenerator { | ||
|
||
/** | ||
* 初始化配置环境. | ||
* | ||
* @param tableName 逻辑表名称 | ||
* @param columnName 需要生成的列名称 | ||
*/ | ||
void initContext(String tableName, String columnName); | ||
|
||
/** | ||
* 生成Id. | ||
* | ||
* @return 返回生成的Id,返回值应为@{@link Number}对象或者为@{@link String}对象 | ||
*/ | ||
Object generateId(); | ||
} |
37 changes: 37 additions & 0 deletions
37
...est/java/com/dangdang/ddframe/rdb/sharding/id/generator/fixture/IncrementIdGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright 1999-2015 dangdang.com. | ||
* <p> | ||
* 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. | ||
* </p> | ||
*/ | ||
|
||
package com.dangdang.ddframe.rdb.sharding.id.generator.fixture; | ||
|
||
import com.dangdang.ddframe.rdb.sharding.id.generator.IdGenerator; | ||
|
||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
public class IncrementIdGenerator implements IdGenerator{ | ||
|
||
private final AtomicInteger i = new AtomicInteger(); | ||
|
||
@Override | ||
public void initContext(final String tableName, final String columnName) { | ||
|
||
} | ||
|
||
@Override | ||
public Object generateId() { | ||
return i.incrementAndGet(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
~ Copyright 1999-2015 dangdang.com. | ||
~ <p> | ||
~ 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. | ||
~ </p> | ||
--> | ||
|
||
<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"> | ||
<parent> | ||
<artifactId>sharding-jdbc</artifactId> | ||
<groupId>com.dangdang</groupId> | ||
<version>1.4.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>sharding-jdbc-id-generator-parent</artifactId> | ||
<packaging>pom</packaging> | ||
<modules> | ||
<module>sharding-jdbc-self-id-generator</module> | ||
</modules> | ||
|
||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.dangdang</groupId> | ||
<artifactId>sharding-jdbc-core</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
</dependency> | ||
</dependencies> | ||
<dependencyManagement> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.dangdang</groupId> | ||
<artifactId>sharding-jdbc</artifactId> | ||
<version>${project.parent.version}</version> | ||
<type>pom</type> | ||
<scope>import</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.github.stefanbirkner</groupId> | ||
<artifactId>system-rules</artifactId> | ||
<version>1.16.0</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</dependencyManagement> | ||
</project> |
51 changes: 51 additions & 0 deletions
51
sharding-jdbc-id-generator-parent/sharding-jdbc-self-id-generator/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
~ Copyright 1999-2015 dangdang.com. | ||
~ <p> | ||
~ 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. | ||
~ </p> | ||
--> | ||
|
||
<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"> | ||
<parent> | ||
<artifactId>sharding-jdbc-id-generator-parent</artifactId> | ||
<groupId>com.dangdang</groupId> | ||
<version>1.4.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>sharding-jdbc-self-id-generator</artifactId> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.github.stefanbirkner</groupId> | ||
<artifactId>system-rules</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>ch.qos.logback</groupId> | ||
<artifactId>logback-classic</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>jcl-over-slf4j</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
137 changes: 137 additions & 0 deletions
137
.../main/java/com/dangdang/ddframe/rdb/sharding/id/generator/self/CommonSelfIdGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* | ||
* Copyright 1999-2015 dangdang.com. | ||
* <p> | ||
* 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. | ||
* </p> | ||
*/ | ||
|
||
package com.dangdang.ddframe.rdb.sharding.id.generator.self; | ||
|
||
import com.dangdang.ddframe.rdb.sharding.id.generator.IdGenerator; | ||
import com.dangdang.ddframe.rdb.sharding.id.generator.self.time.AbstractClock; | ||
import com.google.common.base.Preconditions; | ||
import com.google.common.base.Strings; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
/** | ||
* 自生成Id生成器. | ||
* | ||
* <p/> | ||
* 长度为64bit,从高位到低位依次为 | ||
* <pre> | ||
* 1bit 符号位 | ||
* 41bits 时间偏移量从2016年11月1日零点到现在的毫秒数 | ||
* 10bits 工作进程Id | ||
* 12bits 同一个毫秒内的自增量 | ||
* </pre> | ||
* | ||
* <p/> | ||
* 工作进程Id获取优先级: 系统变量{@code sjdbc.self.id.generator.worker.id} > 环境变量{@code SJDBC_SELF_ID_GENERATOR_WORKER_ID} | ||
* ,另外可以调用@{@code CommonSelfIdGenerator.setWorkerId}进行设置 | ||
* | ||
* @author gaohongtao. | ||
*/ | ||
@Getter | ||
public class CommonSelfIdGenerator implements IdGenerator { | ||
|
||
public static final long SJDBC_EPOCH = 1477933200000L; | ||
|
||
private static final long SEQUENCE_BITS = 12L; | ||
|
||
private static final long WORKER_ID_BITS = 10L; | ||
|
||
private static final long SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1; | ||
|
||
private static final long WORKER_ID_LEFT_SHIFT_BITS = SEQUENCE_BITS; | ||
|
||
private static final long TIMESTAMP_LEFT_SHIFT_BITS = WORKER_ID_LEFT_SHIFT_BITS + WORKER_ID_BITS; | ||
|
||
private static final long WORKER_ID_MAX_VALUE = 1L << WORKER_ID_BITS; | ||
|
||
@Setter | ||
private static AbstractClock clock = AbstractClock.systemClock(); | ||
|
||
@Getter | ||
private static long workerId; | ||
|
||
static { | ||
initWorkerId(); | ||
} | ||
|
||
private long sequence; | ||
|
||
private long lastTime; | ||
|
||
private String tableName; | ||
|
||
private String columnName; | ||
|
||
static void initWorkerId() { | ||
String workerId = System.getProperty("sjdbc.self.id.generator.worker.id"); | ||
if (!Strings.isNullOrEmpty(workerId)) { | ||
setWorkerId(Long.valueOf(workerId)); | ||
return; | ||
} | ||
workerId = System.getenv("SJDBC_SELF_ID_GENERATOR_WORKER_ID"); | ||
if (Strings.isNullOrEmpty(workerId)) { | ||
return; | ||
} | ||
setWorkerId(Long.valueOf(workerId)); | ||
} | ||
|
||
public static void setWorkerId(final Long workerId) { | ||
Preconditions.checkArgument(workerId >= 0L && workerId < WORKER_ID_MAX_VALUE); | ||
CommonSelfIdGenerator.workerId = workerId; | ||
} | ||
|
||
/** | ||
* 初始化环境. | ||
* | ||
* @param tableName 逻辑表名称 | ||
* @param columnName 需要生成的列名称 | ||
*/ | ||
@Override | ||
public void initContext(final String tableName, final String columnName) { | ||
this.tableName = tableName; | ||
this.columnName = columnName; | ||
} | ||
|
||
/** | ||
* 生成Id. | ||
* | ||
* @return 返回@{@link Long}类型的Id | ||
*/ | ||
@Override | ||
public synchronized Object generateId() { | ||
long time = clock.millis(); | ||
Preconditions.checkState(lastTime <= time, "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", lastTime, time); | ||
if (lastTime == time) { | ||
if (0L == (++sequence & SEQUENCE_MASK)) { | ||
time = waitUntilNextTime(time); | ||
} | ||
} else { | ||
sequence = 0; | ||
} | ||
lastTime = time; | ||
return ((time - SJDBC_EPOCH) << TIMESTAMP_LEFT_SHIFT_BITS) | (workerId << WORKER_ID_LEFT_SHIFT_BITS) | sequence; | ||
} | ||
|
||
private long waitUntilNextTime(final long lastTime) { | ||
long time = clock.millis(); | ||
while (time <= lastTime) { | ||
time = clock.millis(); | ||
} | ||
return time; | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
...src/main/java/com/dangdang/ddframe/rdb/sharding/id/generator/self/time/AbstractClock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright 1999-2015 dangdang.com. | ||
* <p> | ||
* 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. | ||
* </p> | ||
*/ | ||
|
||
package com.dangdang.ddframe.rdb.sharding.id.generator.self.time; | ||
|
||
/** | ||
* 时钟定义. | ||
* | ||
* @author gaohongtao | ||
*/ | ||
public abstract class AbstractClock { | ||
|
||
/** | ||
* 创建系统时钟. | ||
* | ||
* @return 系统时钟 | ||
*/ | ||
public static AbstractClock systemClock() { | ||
return new SystemClock(); | ||
} | ||
|
||
/** | ||
* 返回从纪元开始的毫秒数. | ||
* | ||
* @return 从纪元开始的毫秒数 | ||
*/ | ||
public abstract long millis(); | ||
|
||
private static final class SystemClock extends AbstractClock { | ||
|
||
@Override | ||
public long millis() { | ||
return System.currentTimeMillis(); | ||
} | ||
} | ||
} |
Oops, something went wrong.