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();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Create a ULID as byte sequence:
 | 
			
		||||
 | 
			
		||||
```java
 | 
			
		||||
byte[] ulid = UlidCreator.getBytes();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Maven dependency
 | 
			
		||||
 | 
			
		||||
Add these lines to your `pom.xml`.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<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);
 | 
			
		||||
		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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue