Updated UlidBasedGuidCreator
This commit is contained in:
parent
eb65ed35b1
commit
ffffe2af51
|
@ -18,12 +18,6 @@ Create a ULID as GUID object:
|
||||||
UUID ulid = UlidCreator.getGuid();
|
UUID ulid = UlidCreator.getGuid();
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a ULID as byte sequence:
|
|
||||||
|
|
||||||
```java
|
|
||||||
byte[] ulid = UlidCreator.getBytes();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Maven dependency
|
### Maven dependency
|
||||||
|
|
||||||
Add these lines to your `pom.xml`.
|
Add these lines to your `pom.xml`.
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class UlidCreator {
|
||||||
* @return a GUID
|
* @return a GUID
|
||||||
*/
|
*/
|
||||||
public static UUID getUlid() {
|
public static UUID getUlid() {
|
||||||
return GuidCreatorLazyHolder.INSTANCE.createGuid();
|
return GuidCreatorLazyHolder.INSTANCE.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,7 @@ public class UlidCreator {
|
||||||
* @return a GUID
|
* @return a GUID
|
||||||
*/
|
*/
|
||||||
public static UUID getFastUlid() {
|
public static UUID getFastUlid() {
|
||||||
return FastGuidCreatorLazyHolder.INSTANCE.createGuid();
|
return FastGuidCreatorLazyHolder.INSTANCE.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,15 +86,15 @@ public class UlidCreator {
|
||||||
*
|
*
|
||||||
* @return a {@link UlidBasedGuidCreator}
|
* @return a {@link UlidBasedGuidCreator}
|
||||||
*/
|
*/
|
||||||
public static UlidBasedGuidCreator getGuidCreator() {
|
public static UlidBasedGuidCreator getUlidBasedCreator() {
|
||||||
return new UlidBasedGuidCreator();
|
return new UlidBasedGuidCreator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class GuidCreatorLazyHolder {
|
private static class GuidCreatorLazyHolder {
|
||||||
static final UlidBasedGuidCreator INSTANCE = getGuidCreator();
|
static final UlidBasedGuidCreator INSTANCE = getUlidBasedCreator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FastGuidCreatorLazyHolder {
|
private static class FastGuidCreatorLazyHolder {
|
||||||
static final UlidBasedGuidCreator INSTANCE = getGuidCreator().withFastRandomGenerator();
|
static final UlidBasedGuidCreator INSTANCE = getUlidBasedCreator().withFastRandomGenerator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class UlidBasedGuidCreator {
|
||||||
* @throws UlidCreatorException an overrun exception if too many requests are
|
* @throws UlidCreatorException an overrun exception if too many requests are
|
||||||
* made within the same millisecond.
|
* made within the same millisecond.
|
||||||
*/
|
*/
|
||||||
public synchronized UUID createGuid() {
|
public synchronized UUID create() {
|
||||||
|
|
||||||
final long timestamp = this.getTimestamp();
|
final long timestamp = this.getTimestamp();
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ public class UlidBasedGuidCreator {
|
||||||
* @return a ULID string
|
* @return a ULID string
|
||||||
*/
|
*/
|
||||||
public synchronized String createString() {
|
public synchronized String createString() {
|
||||||
UUID guid = createGuid();
|
UUID guid = create();
|
||||||
return UlidUtil.fromUuidToUlid(guid);
|
return UlidUtil.fromUuidToUlid(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,29 +42,29 @@ public class Benchmarks {
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.Throughput)
|
@BenchmarkMode(Mode.Throughput)
|
||||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
public String getUlidThroughput() {
|
public String getUlidStringThroughput() {
|
||||||
return UlidCreator.getUlid();
|
return UlidCreator.getUlidString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
public String getUlidAverage() {
|
public String getUlidStringAverage() {
|
||||||
return UlidCreator.getUlid();
|
return UlidCreator.getUlidString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.Throughput)
|
@BenchmarkMode(Mode.Throughput)
|
||||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
public UUID getGuidThroughput() {
|
public UUID getUlidThroughput() {
|
||||||
return UlidCreator.getGuid();
|
return UlidCreator.getUlid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
public UUID getGuidAverage() {
|
public UUID getUlidAverage() {
|
||||||
return UlidCreator.getGuid();
|
return UlidCreator.getUlid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
|
|
|
@ -95,10 +95,10 @@ public class UniquenessTest {
|
||||||
// Request a UUID
|
// Request a UUID
|
||||||
UUID uuid = null;
|
UUID uuid = null;
|
||||||
try {
|
try {
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
} catch (UlidCreatorException e) {
|
} catch (UlidCreatorException e) {
|
||||||
// Ignore the overrun exception and try again
|
// Ignore the overrun exception and try again
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
@ -125,7 +125,7 @@ public class UniquenessTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void execute(boolean verbose, int threadCount, int requestCount) {
|
public static void execute(boolean verbose, int threadCount, int requestCount) {
|
||||||
UlidBasedGuidCreator creator = UlidCreator.getGuidCreator()
|
UlidBasedGuidCreator creator = UlidCreator.getUlidBasedCreator()
|
||||||
.withTimestampStrategy(new FixedTimestampStretegy(System.currentTimeMillis()));
|
.withTimestampStrategy(new FixedTimestampStretegy(System.currentTimeMillis()));
|
||||||
|
|
||||||
UniquenessTest test = new UniquenessTest(threadCount, requestCount, creator, verbose);
|
UniquenessTest test = new UniquenessTest(threadCount, requestCount, creator, verbose);
|
||||||
|
|
|
@ -1,19 +1,36 @@
|
||||||
package com.github.f4b6a3.ulid;
|
package com.github.f4b6a3.ulid;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.github.f4b6a3.ulid.UlidCreator;
|
import com.github.f4b6a3.ulid.UlidCreator;
|
||||||
|
import com.github.f4b6a3.ulid.creator.UlidBasedGuidCreator;
|
||||||
import com.github.f4b6a3.ulid.util.UlidUtil;
|
import com.github.f4b6a3.ulid.util.UlidUtil;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class UlidCreatorTest {
|
public class UlidCreatorTest {
|
||||||
|
|
||||||
|
private static int processors;
|
||||||
|
|
||||||
private static final int ULID_LENGTH = 26;
|
private static final int ULID_LENGTH = 26;
|
||||||
private static final int DEFAULT_LOOP_MAX = 100_000;
|
private static final int DEFAULT_LOOP_MAX = 100_000;
|
||||||
|
|
||||||
|
private static final String DUPLICATE_UUID_MSG = "A duplicate ULID was created";
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
|
||||||
|
processors = Runtime.getRuntime().availableProcessors();
|
||||||
|
if (processors < 4) {
|
||||||
|
processors = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetUlid() {
|
public void testGetUlid() {
|
||||||
String[] list = new String[DEFAULT_LOOP_MAX];
|
String[] list = new String[DEFAULT_LOOP_MAX];
|
||||||
|
@ -73,4 +90,49 @@ public class UlidCreatorTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUlidBasedGuidParallelGeneratorsShouldCreateUniqueUuids() throws InterruptedException {
|
||||||
|
|
||||||
|
Thread[] threads = new Thread[processors];
|
||||||
|
TestThread.clearHashSet();
|
||||||
|
|
||||||
|
// Instantiate and start many threads
|
||||||
|
for (int i = 0; i < processors; i++) {
|
||||||
|
threads[i] = new TestThread(UlidCreator.getUlidBasedCreator(), DEFAULT_LOOP_MAX);
|
||||||
|
threads[i].start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait all the threads to finish
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the quantity of unique UUIDs is correct
|
||||||
|
assertTrue(DUPLICATE_UUID_MSG, TestThread.hashSet.size() == (DEFAULT_LOOP_MAX * processors));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestThread extends Thread {
|
||||||
|
|
||||||
|
private static Set<UUID> hashSet = new HashSet<>();
|
||||||
|
private UlidBasedGuidCreator creator;
|
||||||
|
private int loopLimit;
|
||||||
|
|
||||||
|
public TestThread(UlidBasedGuidCreator creator, int loopLimit) {
|
||||||
|
this.creator = creator;
|
||||||
|
this.loopLimit = loopLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearHashSet() {
|
||||||
|
hashSet = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < loopLimit; i++) {
|
||||||
|
synchronized (hashSet) {
|
||||||
|
hashSet.add(creator.create());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ public class UlidBasedGuidCreatorTest {
|
||||||
UlidBasedGuidCreatorMock creator = new UlidBasedGuidCreatorMock(TIMESTAMP);
|
UlidBasedGuidCreatorMock creator = new UlidBasedGuidCreatorMock(TIMESTAMP);
|
||||||
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP));
|
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP));
|
||||||
|
|
||||||
UUID uuid = creator.createGuid();
|
UUID uuid = creator.create();
|
||||||
long firstMsb = creator.extractRandomMsb(uuid);
|
long firstMsb = creator.extractRandomMsb(uuid);
|
||||||
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public class UlidBasedGuidCreatorTest {
|
||||||
assertEquals(String.format("The last MSB should be iqual to the first %s.", expectedMsb), expectedMsb, lastMsb);
|
assertEquals(String.format("The last MSB should be iqual to the first %s.", expectedMsb), expectedMsb, lastMsb);
|
||||||
|
|
||||||
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP + 1));
|
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP + 1));
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
lastMsb = uuid.getMostSignificantBits();
|
lastMsb = uuid.getMostSignificantBits();
|
||||||
assertNotEquals("The last MSB should be random after timestamp changed.", firstMsb, lastMsb);
|
assertNotEquals("The last MSB should be random after timestamp changed.", firstMsb, lastMsb);
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,10 @@ public class UlidBasedGuidCreatorTest {
|
||||||
UlidBasedGuidCreatorMock creator = new UlidBasedGuidCreatorMock(TIMESTAMP);
|
UlidBasedGuidCreatorMock creator = new UlidBasedGuidCreatorMock(TIMESTAMP);
|
||||||
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP));
|
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP));
|
||||||
|
|
||||||
UUID uuid = creator.createGuid();
|
UUID uuid = creator.create();
|
||||||
long firstLsb = creator.extractRandomLsb(uuid);
|
long firstLsb = creator.extractRandomLsb(uuid);
|
||||||
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
long lastLsb = creator.extractRandomLsb(uuid);
|
long lastLsb = creator.extractRandomLsb(uuid);
|
||||||
|
@ -60,7 +60,7 @@ public class UlidBasedGuidCreatorTest {
|
||||||
|
|
||||||
long notExpected = firstLsb + DEFAULT_LOOP_MAX + 1;
|
long notExpected = firstLsb + DEFAULT_LOOP_MAX + 1;
|
||||||
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP + 1));
|
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP + 1));
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
lastLsb = uuid.getLeastSignificantBits();
|
lastLsb = uuid.getLeastSignificantBits();
|
||||||
assertNotEquals("The last LSB should be random after timestamp changed.", notExpected, lastLsb);
|
assertNotEquals("The last LSB should be random after timestamp changed.", notExpected, lastLsb);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ public class UlidBasedGuidCreatorTest {
|
||||||
|
|
||||||
UUID uuid = new UUID(0, 0);
|
UUID uuid = new UUID(0, 0);
|
||||||
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
long expectedLsb = lsb + DEFAULT_LOOP_MAX;
|
long expectedLsb = lsb + DEFAULT_LOOP_MAX;
|
||||||
|
@ -96,7 +96,7 @@ public class UlidBasedGuidCreatorTest {
|
||||||
|
|
||||||
UUID uuid = new UUID(0, 0);
|
UUID uuid = new UUID(0, 0);
|
||||||
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
long expectedMsb = msb;
|
long expectedMsb = msb;
|
||||||
|
@ -120,11 +120,11 @@ public class UlidBasedGuidCreatorTest {
|
||||||
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP));
|
creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP));
|
||||||
|
|
||||||
for (int i = 0; i < DEFAULT_LOOP_MAX - 1; i++) {
|
for (int i = 0; i < DEFAULT_LOOP_MAX - 1; i++) {
|
||||||
creator.createGuid();
|
creator.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
creator.createGuid();
|
creator.create();
|
||||||
fail("It should throw an overflow exception.");
|
fail("It should throw an overflow exception.");
|
||||||
} catch (UlidCreatorException e) {
|
} catch (UlidCreatorException e) {
|
||||||
// success
|
// success
|
||||||
|
@ -147,7 +147,7 @@ public class UlidBasedGuidCreatorTest {
|
||||||
|
|
||||||
UUID uuid = new UUID(0, 0);
|
UUID uuid = new UUID(0, 0);
|
||||||
for (int i = 0; i < DEFAULT_LOOP_MAX - 1; i++) {
|
for (int i = 0; i < DEFAULT_LOOP_MAX - 1; i++) {
|
||||||
uuid = creator.createGuid();
|
uuid = creator.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
long expectedLsb = (lsbMax - 1) & UlidBasedGuidCreatorMock.HALF_RANDOM_COMPONENT;
|
long expectedLsb = (lsbMax - 1) & UlidBasedGuidCreatorMock.HALF_RANDOM_COMPONENT;
|
||||||
|
@ -159,7 +159,7 @@ public class UlidBasedGuidCreatorTest {
|
||||||
assertEquals("Incorrect MSB after loop.", expectedMsb, randomMsb);
|
assertEquals("Incorrect MSB after loop.", expectedMsb, randomMsb);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
creator.createGuid();
|
creator.create();
|
||||||
fail("It should throw an overflow exception.");
|
fail("It should throw an overflow exception.");
|
||||||
} catch (UlidCreatorException e) {
|
} catch (UlidCreatorException e) {
|
||||||
// success
|
// success
|
||||||
|
|
Loading…
Reference in New Issue