Add constructors in UlidFactory for random generators #12
New constructors: - public UlidFactory(Random random) { } - public UlidFactory(RandomGenerator randomGenerator) { }
This commit is contained in:
parent
0e1fe3f162
commit
0f431d01b1
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -4,12 +4,18 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
## [3.2.0] - 2021-07-17
|
||||
|
||||
- Fixed typos in `CHANGELOG.md`
|
||||
Simplified the use of `UlidFactory` with other random generators.
|
||||
|
||||
### Added
|
||||
|
||||
- Added constructors in `UlidFactory` for random generators.
|
||||
|
||||
## [3.1.1] - 2021-07-17
|
||||
|
||||
Creates a module name be used in Java 9+.
|
||||
|
||||
### Added
|
||||
|
||||
- Added module name for Java 9+
|
||||
|
@ -233,7 +239,8 @@ Project created as an alternative Java implementation of [ULID spec](https://git
|
|||
- Added `LICENSE`
|
||||
- Added test cases
|
||||
|
||||
[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-3.1.1...HEAD
|
||||
[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-3.2.0...HEAD
|
||||
[3.1.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-3.1.1...ulid-creator-3.2.0
|
||||
[3.1.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-3.1.0...ulid-creator-3.1.1
|
||||
[3.1.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-3.0.1...ulid-creator-3.1.0
|
||||
[3.0.1]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-3.0.0...ulid-creator-3.0.1
|
||||
|
|
19
README.md
19
README.md
|
@ -35,7 +35,7 @@ Add these lines to your `pom.xml`.
|
|||
<dependency>
|
||||
<groupId>com.github.f4b6a3</groupId>
|
||||
<artifactId>ulid-creator</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
```
|
||||
See more options in [maven.org](https://search.maven.org/artifact/com.github.f4b6a3/ulid-creator).
|
||||
|
@ -194,22 +194,20 @@ byte[] random = ulid.getRandom(); // 10 bytes (80 bits)
|
|||
byte[] random = Ulid.getRandom("0123456789ABCDEFGHJKMNPQRS"); // 10 bytes (80 bits)
|
||||
```
|
||||
|
||||
Use a `UlidFactory` instance with `java.util.Random` to generate ULIDs:
|
||||
Use a `UlidFactory` with `java.util.Random`:
|
||||
|
||||
```java
|
||||
Random random = new Random();
|
||||
UlidFactory factory = UlidCreator.getDefaultFactory().withRandomGenerator(random::nextBytes);
|
||||
|
||||
// use a `Random` instance
|
||||
UlidFactory factory = new DefaultFactory(new Random());
|
||||
Ulid ulid = factory.create();
|
||||
```
|
||||
|
||||
Use a `UlidFactory` instance with any random generator you like(*) to generate ULIDs:
|
||||
Use a `UlidFactory` with a random generator of your choice:
|
||||
|
||||
```java
|
||||
// use a method of any RNG with this signature: `void nextBytes(byte[])`
|
||||
import com.github.niceguy.random.AwesomeRandom; // a hypothetical RNG
|
||||
AwesomeRandom awesomeRandom = new AwesomeRandom();
|
||||
UlidFactory factory = UlidCreator.getDefaultFactory().withRandomGenerator(awesomeRandom::nextBytes);
|
||||
|
||||
UlidFactory factory = new DefaultFactory(new AwesomeRandom()::nextBytes);
|
||||
Ulid ulid = factory.create();
|
||||
```
|
||||
|
||||
|
@ -244,5 +242,6 @@ See: [uuid-creator-benchmark](https://github.com/fabiolimace/uuid-creator-benchm
|
|||
Other generators
|
||||
-------------------------------------------
|
||||
* [UUID Creator](https://github.com/f4b6a3/uuid-creator): for generating UUIDs
|
||||
* [TSID Creator](https://github.com/f4b6a3/tsid-creator): for generating Time Sortable IDs
|
||||
* [TSID Creator](https://github.com/f4b6a3/tsid-creator): for generating TSIDs
|
||||
* [KSUID Creator](https://github.com/f4b6a3/ksuid-creator): for generating KSUIDs
|
||||
|
||||
|
|
|
@ -365,7 +365,8 @@ public final class Ulid implements Serializable, Comparable<Ulid> {
|
|||
* The output string is 26 characters long and contains only characters from
|
||||
* Crockford's base 32 alphabet.
|
||||
*
|
||||
* It is at least twice as fast as {@code Ulid.toString().toLowerCase()}.
|
||||
* It is a shorthand at least twice as fast as
|
||||
* {@code Ulid.toString().toLowerCase()}.
|
||||
*
|
||||
* See: https://www.crockford.com/base32.html
|
||||
*
|
||||
|
@ -542,7 +543,7 @@ public final class Ulid implements Serializable, Comparable<Ulid> {
|
|||
bytes[0x2] = (byte) (random0 >>> 16);
|
||||
bytes[0x3] = (byte) (random0 >>> 8);
|
||||
bytes[0x4] = (byte) (random0);
|
||||
|
||||
|
||||
bytes[0x5] = (byte) (random1 >>> 32);
|
||||
bytes[0x6] = (byte) (random1 >>> 24);
|
||||
bytes[0x7] = (byte) (random1 >>> 16);
|
||||
|
@ -619,7 +620,13 @@ public final class Ulid implements Serializable, Comparable<Ulid> {
|
|||
/**
|
||||
* Converts the ULID into a canonical string in upper case.
|
||||
*
|
||||
* It is the same as {@code Ulid.toUpperCase()}.
|
||||
* The output string is 26 characters long and contains only characters from
|
||||
* Crockford's base 32 alphabet.
|
||||
*
|
||||
* For lower case string, use the shorthand {@code Ulid#toLowerCase()}, instead
|
||||
* of {@code Ulid#toString()#toLowerCase()}.
|
||||
*
|
||||
* See: https://www.crockford.com/base32.html
|
||||
*
|
||||
* @return a ULID string
|
||||
*/
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
|
||||
package com.github.f4b6a3.ulid;
|
||||
|
||||
import com.github.f4b6a3.ulid.factory.DefaultUlidFactory;
|
||||
import com.github.f4b6a3.ulid.factory.MonotonicUlidFactory;
|
||||
import com.github.f4b6a3.ulid.factory.DefaultFactory;
|
||||
import com.github.f4b6a3.ulid.factory.MonotonicFactory;
|
||||
import com.github.f4b6a3.ulid.factory.UlidFactory;
|
||||
|
||||
/**
|
||||
|
@ -92,29 +92,11 @@ public final class UlidCreator {
|
|||
return MonotonicFactoryHolder.INSTANCE.create(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the Default ULID factory.
|
||||
*
|
||||
* @return a ULID factory
|
||||
*/
|
||||
public static UlidFactory getDefaultFactory() {
|
||||
return new DefaultUlidFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the Monotonic ULID factory.
|
||||
*
|
||||
* @return a ULID factory
|
||||
*/
|
||||
public static UlidFactory getMonotonicFactory() {
|
||||
return new MonotonicUlidFactory();
|
||||
}
|
||||
|
||||
private static class DefaultFactoryHolder {
|
||||
static final UlidFactory INSTANCE = getDefaultFactory();
|
||||
static final UlidFactory INSTANCE = new DefaultFactory();
|
||||
}
|
||||
|
||||
private static class MonotonicFactoryHolder {
|
||||
static final UlidFactory INSTANCE = getMonotonicFactory();
|
||||
static final UlidFactory INSTANCE = new MonotonicFactory();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,16 +24,44 @@
|
|||
|
||||
package com.github.f4b6a3.ulid.factory;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.github.f4b6a3.ulid.Ulid;
|
||||
import com.github.f4b6a3.ulid.random.RandomGenerator;
|
||||
|
||||
/**
|
||||
* Factory that generates default ULIDs.
|
||||
* Factory that generates ULIDs.
|
||||
*
|
||||
* The random component is always reset to a new random value.
|
||||
*
|
||||
* The maximum ULIDs that can be generated per millisecond is 2^80.
|
||||
*/
|
||||
public class DefaultUlidFactory extends UlidFactory {
|
||||
public class DefaultFactory extends UlidFactory {
|
||||
|
||||
/**
|
||||
* Use the default {@link java.security.SecureRandom}.
|
||||
*/
|
||||
public DefaultFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a random generator that inherits from {@link Random}.
|
||||
*
|
||||
* @param random a {@link Random} instance
|
||||
*/
|
||||
public DefaultFactory(Random random) {
|
||||
this(random::nextBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a random generator that inherits from {@link RandomGenerator}.
|
||||
*
|
||||
* @param randomGenerator a {@link RandomGenerator} instance
|
||||
*/
|
||||
public DefaultFactory(RandomGenerator randomGenerator) {
|
||||
super(randomGenerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ULID.
|
|
@ -24,23 +24,52 @@
|
|||
|
||||
package com.github.f4b6a3.ulid.factory;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.github.f4b6a3.ulid.Ulid;
|
||||
import com.github.f4b6a3.ulid.random.RandomGenerator;
|
||||
|
||||
/**
|
||||
* Factory that generates Monotonic ULIDs.
|
||||
*
|
||||
* The random component is reset to a new value every time the millisecond changes.
|
||||
* The random component is reset to a new value every time the millisecond
|
||||
* changes.
|
||||
*
|
||||
* If more than one ULID is generated within the same millisecond, the random
|
||||
* component is incremented by one.
|
||||
*
|
||||
* The maximum ULIDs that can be generated per millisecond is 2^80.
|
||||
*/
|
||||
public final class MonotonicUlidFactory extends UlidFactory {
|
||||
public final class MonotonicFactory extends UlidFactory {
|
||||
|
||||
private long lastTime = -1;
|
||||
private Ulid lastUlid = null;
|
||||
|
||||
/**
|
||||
* Use the default {@link java.security.SecureRandom}.
|
||||
*/
|
||||
public MonotonicFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a random generator that inherits from {@link Random}.
|
||||
*
|
||||
* @param random a {@link Random} instance
|
||||
*/
|
||||
public MonotonicFactory(Random random) {
|
||||
this(random::nextBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a random generator that inherits from {@link RandomGenerator}.
|
||||
*
|
||||
* @param randomGenerator a {@link RandomGenerator} instance
|
||||
*/
|
||||
public MonotonicFactory(RandomGenerator randomGenerator) {
|
||||
super(randomGenerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ULID.
|
||||
*
|
|
@ -24,10 +24,9 @@
|
|||
|
||||
package com.github.f4b6a3.ulid.factory;
|
||||
|
||||
import java.util.Random;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import com.github.f4b6a3.ulid.Ulid;
|
||||
import com.github.f4b6a3.ulid.random.DefaultRandomGenerator;
|
||||
import com.github.f4b6a3.ulid.random.RandomGenerator;
|
||||
|
||||
/**
|
||||
|
@ -39,8 +38,20 @@ public abstract class UlidFactory {
|
|||
|
||||
protected RandomGenerator randomGenerator;
|
||||
|
||||
/**
|
||||
* Use the default {@link java.security.SecureRandom}.
|
||||
*/
|
||||
public UlidFactory() {
|
||||
this.randomGenerator = new DefaultRandomGenerator();
|
||||
this(new SecureRandom()::nextBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a random generator that inherits from {@link RandomGenerator}.
|
||||
*
|
||||
* @param randomGenerator a {@link RandomGenerator} instance
|
||||
*/
|
||||
public UlidFactory(RandomGenerator randomGenerator) {
|
||||
this.randomGenerator = randomGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,21 +72,4 @@ public abstract class UlidFactory {
|
|||
* @return a ULID
|
||||
*/
|
||||
public abstract Ulid create(final long time);
|
||||
|
||||
/**
|
||||
* Replaces the default random generator with another.
|
||||
*
|
||||
* The default random generator uses {@link java.security.SecureRandom}.
|
||||
*
|
||||
* See {@link Random}.
|
||||
*
|
||||
* @param <T> the type parameter
|
||||
* @param randomGenerator a random generator
|
||||
* @return {@link UlidFactory}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized <T extends UlidFactory> T withRandomGenerator(RandomGenerator randomGenerator) {
|
||||
this.randomGenerator = randomGenerator;
|
||||
return (T) this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018-2020 Fabio Lima
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.github.f4b6a3.ulid.random;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* It uses an instance of {@link java.security.SecureRandom}.
|
||||
*/
|
||||
public final class DefaultRandomGenerator implements RandomGenerator {
|
||||
|
||||
private static final Random SECURE_RANDOM = new SecureRandom();
|
||||
|
||||
@Override
|
||||
public void nextBytes(byte[] bytes) {
|
||||
SECURE_RANDOM.nextBytes(bytes);
|
||||
}
|
||||
}
|
|
@ -3,13 +3,13 @@ package com.github.f4b6a3.ulid;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
import com.github.f4b6a3.ulid.factory.DefaultUlidFactoryTest;
|
||||
import com.github.f4b6a3.ulid.factory.MonotonicUlidFactoryTest;
|
||||
import com.github.f4b6a3.ulid.factory.DefaultFactoryTest;
|
||||
import com.github.f4b6a3.ulid.factory.MonotonicFactoryTest;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
MonotonicUlidFactoryTest.class,
|
||||
DefaultUlidFactoryTest.class,
|
||||
MonotonicFactoryTest.class,
|
||||
DefaultFactoryTest.class,
|
||||
UlidTest.class,
|
||||
})
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public class UlidTest {
|
|||
}
|
||||
|
||||
try {
|
||||
long time = 0x1000000000000000L; // negative number
|
||||
long time = 0x8000000000000000L; // negative number
|
||||
byte[] bytes = new byte[Ulid.RANDOM_BYTES_LENGTH];
|
||||
new Ulid(time, bytes);
|
||||
fail("Should throw an exception");
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.github.f4b6a3.ulid;
|
||||
|
||||
import java.util.HashSet;
|
||||
import com.github.f4b6a3.ulid.UlidCreator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.github.f4b6a3.ulid.factory.MonotonicFactory;
|
||||
import com.github.f4b6a3.ulid.factory.UlidFactory;
|
||||
|
||||
/**
|
||||
|
@ -117,8 +119,7 @@ public class UniquenessTest {
|
|||
}
|
||||
|
||||
public static void execute(boolean verbose, int threadCount, int requestCount) {
|
||||
UlidFactory factory = UlidCreator.getMonotonicFactory();
|
||||
|
||||
UlidFactory factory = new MonotonicFactory(new Random());
|
||||
UniquenessTest test = new UniquenessTest(threadCount, requestCount, factory, verbose);
|
||||
test.start();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import static org.junit.Assert.*;
|
|||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
|
||||
public class DefaultUlidFactoryTest extends UlidFactoryTest {
|
||||
public class DefaultFactoryTest extends UlidFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testGetUlid() {
|
||||
|
@ -67,8 +67,7 @@ public class DefaultUlidFactoryTest extends UlidFactoryTest {
|
|||
|
||||
// Instantiate and start many threads
|
||||
for (int i = 0; i < THREAD_TOTAL; i++) {
|
||||
Random random = new Random();
|
||||
UlidFactory factory = UlidCreator.getDefaultFactory().withRandomGenerator(random::nextBytes);
|
||||
UlidFactory factory = new DefaultFactory(new Random());
|
||||
threads[i] = new TestThread(factory, DEFAULT_LOOP_MAX);
|
||||
threads[i].start();
|
||||
}
|
|
@ -12,7 +12,7 @@ import java.util.Arrays;
|
|||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
|
||||
public class MonotonicUlidFactoryTest extends UlidFactoryTest {
|
||||
public class MonotonicFactoryTest extends UlidFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testGetUlid() {
|
||||
|
@ -78,8 +78,7 @@ public class MonotonicUlidFactoryTest extends UlidFactoryTest {
|
|||
|
||||
// Instantiate and start many threads
|
||||
for (int i = 0; i < THREAD_TOTAL; i++) {
|
||||
Random random = new Random();
|
||||
UlidFactory factory = UlidCreator.getMonotonicFactory().withRandomGenerator(random::nextBytes);
|
||||
UlidFactory factory = new MonotonicFactory(new Random());
|
||||
threads[i] = new TestThread(factory, DEFAULT_LOOP_MAX);
|
||||
threads[i].start();
|
||||
}
|
Loading…
Reference in New Issue