From ffffe2af5107cec4a514dc3c152b61b18738e88e Mon Sep 17 00:00:00 2001 From: Fabio Lima Date: Mon, 16 Mar 2020 00:27:32 -0300 Subject: [PATCH] Updated UlidBasedGuidCreator --- README.md | 6 -- .../com/github/f4b6a3/ulid/UlidCreator.java | 10 +-- .../ulid/creator/UlidBasedGuidCreator.java | 4 +- .../java/com/github/f4b6a3/Benchmarks.java | 16 ++--- .../com/github/f4b6a3/UniquenessTest.java | 6 +- .../github/f4b6a3/ulid/UlidCreatorTest.java | 62 +++++++++++++++++++ .../creator/UlidBasedGuidCreatorTest.java | 24 +++---- 7 files changed, 92 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index ee42bc9..d9f51d3 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,6 @@ Create a ULID as GUID object: UUID ulid = UlidCreator.getGuid(); ``` -Create a ULID as byte sequence: - -```java -byte[] ulid = UlidCreator.getBytes(); -``` - ### Maven dependency Add these lines to your `pom.xml`. diff --git a/src/main/java/com/github/f4b6a3/ulid/UlidCreator.java b/src/main/java/com/github/f4b6a3/ulid/UlidCreator.java index 2219c21..7e08321 100644 --- a/src/main/java/com/github/f4b6a3/ulid/UlidCreator.java +++ b/src/main/java/com/github/f4b6a3/ulid/UlidCreator.java @@ -45,7 +45,7 @@ public class UlidCreator { * @return a GUID */ public static UUID getUlid() { - return GuidCreatorLazyHolder.INSTANCE.createGuid(); + return GuidCreatorLazyHolder.INSTANCE.create(); } /** @@ -54,7 +54,7 @@ public class UlidCreator { * @return a GUID */ public static UUID getFastUlid() { - return FastGuidCreatorLazyHolder.INSTANCE.createGuid(); + return FastGuidCreatorLazyHolder.INSTANCE.create(); } /** @@ -86,15 +86,15 @@ public class UlidCreator { * * @return a {@link UlidBasedGuidCreator} */ - public static UlidBasedGuidCreator getGuidCreator() { + public static UlidBasedGuidCreator getUlidBasedCreator() { return new UlidBasedGuidCreator(); } private static class GuidCreatorLazyHolder { - static final UlidBasedGuidCreator INSTANCE = getGuidCreator(); + static final UlidBasedGuidCreator INSTANCE = getUlidBasedCreator(); } private static class FastGuidCreatorLazyHolder { - static final UlidBasedGuidCreator INSTANCE = getGuidCreator().withFastRandomGenerator(); + static final UlidBasedGuidCreator INSTANCE = getUlidBasedCreator().withFastRandomGenerator(); } } diff --git a/src/main/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreator.java b/src/main/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreator.java index a8e4b64..26641b6 100644 --- a/src/main/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreator.java +++ b/src/main/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreator.java @@ -124,7 +124,7 @@ public class UlidBasedGuidCreator { * @throws UlidCreatorException an overrun exception if too many requests are * made within the same millisecond. */ - public synchronized UUID createGuid() { + public synchronized UUID create() { final long timestamp = this.getTimestamp(); @@ -143,7 +143,7 @@ public class UlidBasedGuidCreator { * @return a ULID string */ public synchronized String createString() { - UUID guid = createGuid(); + UUID guid = create(); return UlidUtil.fromUuidToUlid(guid); } diff --git a/src/test/java/com/github/f4b6a3/Benchmarks.java b/src/test/java/com/github/f4b6a3/Benchmarks.java index 2bc9647..2eddf2e 100644 --- a/src/test/java/com/github/f4b6a3/Benchmarks.java +++ b/src/test/java/com/github/f4b6a3/Benchmarks.java @@ -42,29 +42,29 @@ public class Benchmarks { @Benchmark @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.MILLISECONDS) - public String getUlidThroughput() { - return UlidCreator.getUlid(); + public String getUlidStringThroughput() { + return UlidCreator.getUlidString(); } @Benchmark @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) - public String getUlidAverage() { - return UlidCreator.getUlid(); + public String getUlidStringAverage() { + return UlidCreator.getUlidString(); } @Benchmark @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.MILLISECONDS) - public UUID getGuidThroughput() { - return UlidCreator.getGuid(); + public UUID getUlidThroughput() { + return UlidCreator.getUlid(); } @Benchmark @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) - public UUID getGuidAverage() { - return UlidCreator.getGuid(); + public UUID getUlidAverage() { + return UlidCreator.getUlid(); } @Benchmark diff --git a/src/test/java/com/github/f4b6a3/UniquenessTest.java b/src/test/java/com/github/f4b6a3/UniquenessTest.java index 5613ba3..ea00a26 100644 --- a/src/test/java/com/github/f4b6a3/UniquenessTest.java +++ b/src/test/java/com/github/f4b6a3/UniquenessTest.java @@ -95,10 +95,10 @@ public class UniquenessTest { // Request a UUID UUID uuid = null; try { - uuid = creator.createGuid(); + uuid = creator.create(); } catch (UlidCreatorException e) { // Ignore the overrun exception and try again - uuid = creator.createGuid(); + uuid = creator.create(); } if (verbose) { @@ -125,7 +125,7 @@ public class UniquenessTest { } public static void execute(boolean verbose, int threadCount, int requestCount) { - UlidBasedGuidCreator creator = UlidCreator.getGuidCreator() + UlidBasedGuidCreator creator = UlidCreator.getUlidBasedCreator() .withTimestampStrategy(new FixedTimestampStretegy(System.currentTimeMillis())); UniquenessTest test = new UniquenessTest(threadCount, requestCount, creator, verbose); diff --git a/src/test/java/com/github/f4b6a3/ulid/UlidCreatorTest.java b/src/test/java/com/github/f4b6a3/ulid/UlidCreatorTest.java index 2f45030..c16389d 100644 --- a/src/test/java/com/github/f4b6a3/ulid/UlidCreatorTest.java +++ b/src/test/java/com/github/f4b6a3/ulid/UlidCreatorTest.java @@ -1,19 +1,36 @@ package com.github.f4b6a3.ulid; +import org.junit.BeforeClass; import org.junit.Test; import com.github.f4b6a3.ulid.UlidCreator; +import com.github.f4b6a3.ulid.creator.UlidBasedGuidCreator; import com.github.f4b6a3.ulid.util.UlidUtil; import static org.junit.Assert.*; import java.util.Arrays; import java.util.HashSet; +import java.util.Set; +import java.util.UUID; public class UlidCreatorTest { + private static int processors; + private static final int ULID_LENGTH = 26; 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 public void testGetUlid() { 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 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()); + } + } + } + } } diff --git a/src/test/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreatorTest.java b/src/test/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreatorTest.java index 3e50d25..9068805 100644 --- a/src/test/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreatorTest.java +++ b/src/test/java/com/github/f4b6a3/ulid/creator/UlidBasedGuidCreatorTest.java @@ -25,10 +25,10 @@ public class UlidBasedGuidCreatorTest { UlidBasedGuidCreatorMock creator = new UlidBasedGuidCreatorMock(TIMESTAMP); creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP)); - UUID uuid = creator.createGuid(); + UUID uuid = creator.create(); long firstMsb = creator.extractRandomMsb(uuid); 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); creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP + 1)); - uuid = creator.createGuid(); + uuid = creator.create(); lastMsb = uuid.getMostSignificantBits(); assertNotEquals("The last MSB should be random after timestamp changed.", firstMsb, lastMsb); } @@ -48,10 +48,10 @@ public class UlidBasedGuidCreatorTest { UlidBasedGuidCreatorMock creator = new UlidBasedGuidCreatorMock(TIMESTAMP); creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP)); - UUID uuid = creator.createGuid(); + UUID uuid = creator.create(); long firstLsb = creator.extractRandomLsb(uuid); for (int i = 0; i < DEFAULT_LOOP_MAX; i++) { - uuid = creator.createGuid(); + uuid = creator.create(); } long lastLsb = creator.extractRandomLsb(uuid); @@ -60,7 +60,7 @@ public class UlidBasedGuidCreatorTest { long notExpected = firstLsb + DEFAULT_LOOP_MAX + 1; creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP + 1)); - uuid = creator.createGuid(); + uuid = creator.create(); lastLsb = uuid.getLeastSignificantBits(); 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); for (int i = 0; i < DEFAULT_LOOP_MAX; i++) { - uuid = creator.createGuid(); + uuid = creator.create(); } long expectedLsb = lsb + DEFAULT_LOOP_MAX; @@ -96,7 +96,7 @@ public class UlidBasedGuidCreatorTest { UUID uuid = new UUID(0, 0); for (int i = 0; i < DEFAULT_LOOP_MAX; i++) { - uuid = creator.createGuid(); + uuid = creator.create(); } long expectedMsb = msb; @@ -120,11 +120,11 @@ public class UlidBasedGuidCreatorTest { creator.withTimestampStrategy(new FixedTimestampStretegy(TIMESTAMP)); for (int i = 0; i < DEFAULT_LOOP_MAX - 1; i++) { - creator.createGuid(); + creator.create(); } try { - creator.createGuid(); + creator.create(); fail("It should throw an overflow exception."); } catch (UlidCreatorException e) { // success @@ -147,7 +147,7 @@ public class UlidBasedGuidCreatorTest { UUID uuid = new UUID(0, 0); for (int i = 0; i < DEFAULT_LOOP_MAX - 1; i++) { - uuid = creator.createGuid(); + uuid = creator.create(); } long expectedLsb = (lsbMax - 1) & UlidBasedGuidCreatorMock.HALF_RANDOM_COMPONENT; @@ -159,7 +159,7 @@ public class UlidBasedGuidCreatorTest { assertEquals("Incorrect MSB after loop.", expectedMsb, randomMsb); try { - creator.createGuid(); + creator.create(); fail("It should throw an overflow exception."); } catch (UlidCreatorException e) { // success