Add support for RandomGenerator in Java 17 #19
This commit is contained in:
parent
3b6a135fd3
commit
f80eb4029c
|
@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
Nothing unreleased.
|
||||
|
||||
## [5.0.0] - 2022-07-09
|
||||
|
||||
Add support for RandomGenerator in Java 17. #19
|
||||
|
||||
## [4.2.1] - 2022-04-21
|
||||
|
||||
Handle clock drift. #18
|
||||
|
@ -286,7 +290,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-4.2.1...HEAD
|
||||
[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.0...HEAD
|
||||
[5.0.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.2.1...ulid-creator-5.0.0
|
||||
[4.2.1]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.2.0...ulid-creator-4.2.1
|
||||
[4.2.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.2...ulid-creator-4.2.0
|
||||
[4.1.2]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.1...ulid-creator-4.1.2
|
||||
|
|
34
README.md
34
README.md
|
@ -39,7 +39,7 @@ Add these lines to your `pom.xml`.
|
|||
<dependency>
|
||||
<groupId>com.github.f4b6a3</groupId>
|
||||
<artifactId>ulid-creator</artifactId>
|
||||
<version>4.2.1</version>
|
||||
<version>5.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
See more options in [maven.org](https://search.maven.org/artifact/com.github.f4b6a3/ulid-creator).
|
||||
|
@ -198,12 +198,38 @@ Ulid ulid = factory.create();
|
|||
|
||||
---
|
||||
|
||||
A `UlidFactory` with `ThreadLocalRandom` inside of a `Supplier<byte[]>`:
|
||||
A `UlidFactory` with `SplittableRandom`:
|
||||
|
||||
```java
|
||||
// use a random function that returns a long value
|
||||
SplittableRandom random = new SplittableRandom();
|
||||
UlidFactory factory = UlidFactory.newInstance(() -> random.nextLong());
|
||||
|
||||
// use the factory
|
||||
Ulid ulid = factory.create();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
A `UlidFactory` with `RandomGenerator` (JDK 17+):
|
||||
|
||||
```java
|
||||
// use a random function that returns a long value
|
||||
RandomGenerator random = RandomGenerator.getDefault();
|
||||
UlidFactory factory = UlidFactory.newInstance(() -> random.nextLong());
|
||||
|
||||
// use the factory
|
||||
Ulid ulid = factory.create();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
A `UlidFactory` with `ThreadLocalRandom`:
|
||||
|
||||
```java
|
||||
// use a random supplier that returns an array of 10 bytes
|
||||
UlidFactory factory = UlidFactory.newInstance(() -> {
|
||||
final byte[] bytes = new byte[Ulid.RANDOM_BYTES];
|
||||
UlidFactory factory = UlidFactory.newInstance((length) -> {
|
||||
final byte[] bytes = new byte[length];
|
||||
ThreadLocalRandom.current().nextBytes(bytes);
|
||||
return bytes;
|
||||
});
|
||||
|
|
|
@ -27,8 +27,9 @@ package com.github.f4b6a3.ulid;
|
|||
import java.security.SecureRandom;
|
||||
import java.time.Clock;
|
||||
import java.util.Random;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.LongFunction;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.LongSupplier;
|
||||
|
||||
/**
|
||||
* Factory that generates ULIDs.
|
||||
|
@ -47,7 +48,7 @@ public final class UlidFactory {
|
|||
private final LongFunction<Ulid> ulidFunction;
|
||||
|
||||
public UlidFactory() {
|
||||
this(new UlidFunction(getRandomSupplier(null)));
|
||||
this(new UlidFunction());
|
||||
}
|
||||
|
||||
private UlidFactory(LongFunction<Ulid> ulidFunction) {
|
||||
|
@ -67,7 +68,7 @@ public final class UlidFactory {
|
|||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newInstance() {
|
||||
return newInstance(getRandomSupplier(null));
|
||||
return new UlidFactory(new UlidFunction());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,19 +78,31 @@ public final class UlidFactory {
|
|||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newInstance(Random random) {
|
||||
return newInstance(getRandomSupplier(random));
|
||||
return new UlidFactory(new UlidFunction(random));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new factory.
|
||||
*
|
||||
* The given random supplier must return an array of 10 bytes.
|
||||
* The given random function must return a long value.
|
||||
*
|
||||
* @param randomSupplier a random supplier that returns 10 bytes
|
||||
* @param randomFunction a random function that returns a long value
|
||||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newInstance(Supplier<byte[]> randomSupplier) {
|
||||
return new UlidFactory(new UlidFunction(randomSupplier));
|
||||
public static UlidFactory newInstance(LongSupplier randomFunction) {
|
||||
return new UlidFactory(new UlidFunction(randomFunction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new factory.
|
||||
*
|
||||
* The given random function must return a byte array.
|
||||
*
|
||||
* @param randomFunction a random function that returns a byte array
|
||||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newInstance(IntFunction<byte[]> randomFunction) {
|
||||
return new UlidFactory(new UlidFunction(randomFunction));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +111,7 @@ public final class UlidFactory {
|
|||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newMonotonicInstance() {
|
||||
return newMonotonicInstance(getRandomSupplier(null));
|
||||
return new UlidFactory(new MonotonicFunction());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,32 +121,57 @@ public final class UlidFactory {
|
|||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newMonotonicInstance(Random random) {
|
||||
return newMonotonicInstance(getRandomSupplier(random));
|
||||
return new UlidFactory(new MonotonicFunction(random));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new monotonic factory.
|
||||
*
|
||||
* The given random supplier must return an array of 10 bytes.
|
||||
* The given random function must return a long value.
|
||||
*
|
||||
* @param randomSupplier a random supplier that returns 10 bytes
|
||||
* @param randomFunction a random function that returns a long value
|
||||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newMonotonicInstance(Supplier<byte[]> randomSupplier) {
|
||||
return new UlidFactory(new MonotonicFunction(randomSupplier));
|
||||
public static UlidFactory newMonotonicInstance(LongSupplier randomFunction) {
|
||||
return new UlidFactory(new MonotonicFunction(randomFunction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new monotonic factory.
|
||||
*
|
||||
* The given random supplier must return an array of 10 bytes.
|
||||
* The given random function must return a byte array.
|
||||
*
|
||||
* @param randomSupplier a random supplier that returns 10 bytes
|
||||
* @param randomFunction a random function that returns a byte array
|
||||
* @return {@link UlidFactory}
|
||||
*/
|
||||
public static UlidFactory newMonotonicInstance(IntFunction<byte[]> randomFunction) {
|
||||
return new UlidFactory(new MonotonicFunction(randomFunction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new monotonic factory.
|
||||
*
|
||||
* The given random function must return a long value.
|
||||
*
|
||||
* @param randomFunction a random function that returns a long value
|
||||
* @param clock a custom clock instance for tests
|
||||
* @return {@link UlidFactory}
|
||||
*/
|
||||
protected static UlidFactory newMonotonicInstance(Supplier<byte[]> randomSupplier, Clock clock) {
|
||||
return new UlidFactory(new MonotonicFunction(randomSupplier), clock);
|
||||
protected static UlidFactory newMonotonicInstance(LongSupplier randomFunction, Clock clock) {
|
||||
return new UlidFactory(new MonotonicFunction(randomFunction), clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new monotonic factory.
|
||||
*
|
||||
* The given random function must return a byte array.
|
||||
*
|
||||
* @param randomFunction a random function that returns a byte array
|
||||
* @param clock a custom clock instance for tests
|
||||
* @return {@link UlidFactory}
|
||||
*/
|
||||
protected static UlidFactory newMonotonicInstance(IntFunction<byte[]> randomFunction, Clock clock) {
|
||||
return new UlidFactory(new MonotonicFunction(randomFunction), clock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,8 +179,8 @@ public final class UlidFactory {
|
|||
*
|
||||
* @return a ULID
|
||||
*/
|
||||
public Ulid create() {
|
||||
return create(clock.millis());
|
||||
public synchronized Ulid create() {
|
||||
return this.ulidFunction.apply(clock.millis());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,7 +191,7 @@ public final class UlidFactory {
|
|||
* @param time a given time
|
||||
* @return a ULID
|
||||
*/
|
||||
public Ulid create(final long time) {
|
||||
public synchronized Ulid create(final long time) {
|
||||
return this.ulidFunction.apply(time);
|
||||
}
|
||||
|
||||
|
@ -162,16 +200,33 @@ public final class UlidFactory {
|
|||
*/
|
||||
protected static final class UlidFunction implements LongFunction<Ulid> {
|
||||
|
||||
// it must return an array of 10 bytes
|
||||
private Supplier<byte[]> randomSupplier;
|
||||
private final IRandom random;
|
||||
|
||||
public UlidFunction(Supplier<byte[]> randomSupplier) {
|
||||
this.randomSupplier = randomSupplier;
|
||||
public UlidFunction() {
|
||||
this.random = new ByteRandom();
|
||||
}
|
||||
|
||||
public UlidFunction(Random random) {
|
||||
this.random = IRandom.newInstance(random);
|
||||
}
|
||||
|
||||
public UlidFunction(IntFunction<byte[]> randomFunction) {
|
||||
this.random = new ByteRandom(randomFunction);
|
||||
}
|
||||
|
||||
public UlidFunction(LongSupplier randomFunction) {
|
||||
this.random = new LongRandom(randomFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ulid apply(final long time) {
|
||||
return new Ulid(time, this.randomSupplier.get());
|
||||
if (this.random instanceof ByteRandom) {
|
||||
return new Ulid(time, this.random.nextBytes(Ulid.RANDOM_BYTES));
|
||||
} else {
|
||||
final long msb = (time << 16) | (this.random.nextLong() & 0xffffL);
|
||||
final long lsb = this.random.nextLong();
|
||||
return new Ulid(msb, lsb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,20 +238,35 @@ public final class UlidFactory {
|
|||
private long lastTime;
|
||||
private Ulid lastUlid;
|
||||
|
||||
private final IRandom random;
|
||||
|
||||
// Used to preserve monotonicity when the system clock is
|
||||
// adjusted by NTP after a small clock drift or when the
|
||||
// system clock jumps back by 1 second due to leap second.
|
||||
protected static final int CLOCK_DRIFT_TOLERANCE = 10_000;
|
||||
|
||||
// it must return an array of 10 bytes
|
||||
private Supplier<byte[]> randomSupplier;
|
||||
public MonotonicFunction() {
|
||||
this(new ByteRandom());
|
||||
}
|
||||
|
||||
public MonotonicFunction(Supplier<byte[]> randomSupplier) {
|
||||
this.randomSupplier = randomSupplier;
|
||||
public MonotonicFunction(Random random) {
|
||||
this(IRandom.newInstance(random));
|
||||
}
|
||||
|
||||
public MonotonicFunction(IntFunction<byte[]> randomFunction) {
|
||||
this(new ByteRandom(randomFunction));
|
||||
}
|
||||
|
||||
public MonotonicFunction(LongSupplier randomFunction) {
|
||||
this(new LongRandom(randomFunction));
|
||||
}
|
||||
|
||||
private MonotonicFunction(IRandom random) {
|
||||
this.random = random;
|
||||
|
||||
// initialize internal state
|
||||
this.lastTime = Clock.systemUTC().millis();
|
||||
this.lastUlid = new Ulid(lastTime, randomSupplier.get());
|
||||
this.lastUlid = new Ulid(lastTime, random.nextBytes(Ulid.RANDOM_BYTES));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -209,26 +279,122 @@ public final class UlidFactory {
|
|||
this.lastUlid = lastUlid.increment();
|
||||
} else {
|
||||
this.lastTime = time;
|
||||
this.lastUlid = new Ulid(time, this.randomSupplier.get());
|
||||
if (this.random instanceof ByteRandom) {
|
||||
this.lastUlid = new Ulid(time, this.random.nextBytes(Ulid.RANDOM_BYTES));
|
||||
} else {
|
||||
final long msb = (time << 16) | (this.random.nextLong() & 0xffffL);
|
||||
final long lsb = this.random.nextLong();
|
||||
this.lastUlid = new Ulid(msb, lsb);
|
||||
}
|
||||
}
|
||||
|
||||
return new Ulid(this.lastUlid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It instantiates a supplier that returns an array of 10 bytes.
|
||||
*
|
||||
* @param random a {@link Random} generator
|
||||
* @return a random supplier that returns 10 bytes
|
||||
*/
|
||||
protected static Supplier<byte[]> getRandomSupplier(Random random) {
|
||||
Random entropy = random != null ? random : new SecureRandom();
|
||||
return () -> {
|
||||
byte[] payload = new byte[Ulid.RANDOM_BYTES];
|
||||
entropy.nextBytes(payload);
|
||||
return payload;
|
||||
};
|
||||
protected static interface IRandom {
|
||||
|
||||
public long nextLong();
|
||||
|
||||
public byte[] nextBytes(int length);
|
||||
|
||||
static IRandom newInstance(Random random) {
|
||||
if (random == null) {
|
||||
return new ByteRandom();
|
||||
} else {
|
||||
if (random instanceof SecureRandom) {
|
||||
return new ByteRandom(random);
|
||||
} else {
|
||||
return new LongRandom(random);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static class LongRandom implements IRandom {
|
||||
|
||||
private final LongSupplier randomFunction;
|
||||
|
||||
public LongRandom() {
|
||||
this(newRandomFunction(null));
|
||||
}
|
||||
|
||||
public LongRandom(Random random) {
|
||||
this(newRandomFunction(random));
|
||||
}
|
||||
|
||||
public LongRandom(LongSupplier randomFunction) {
|
||||
this.randomFunction = randomFunction != null ? randomFunction : newRandomFunction(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextLong() {
|
||||
return randomFunction.getAsLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] nextBytes(int length) {
|
||||
|
||||
int shift = 0;
|
||||
long random = 0;
|
||||
final byte[] bytes = new byte[length];
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (shift < Byte.SIZE) {
|
||||
shift = Long.SIZE;
|
||||
random = randomFunction.getAsLong();
|
||||
}
|
||||
shift -= Byte.SIZE; // 56, 48, 42...
|
||||
bytes[i] = (byte) (random >>> shift);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
protected static LongSupplier newRandomFunction(Random random) {
|
||||
final Random entropy = random != null ? random : new SecureRandom();
|
||||
return entropy::nextLong;
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ByteRandom implements IRandom {
|
||||
|
||||
private final IntFunction<byte[]> randomFunction;
|
||||
|
||||
public ByteRandom() {
|
||||
this(newRandomFunction(null));
|
||||
}
|
||||
|
||||
public ByteRandom(Random random) {
|
||||
this(newRandomFunction(random));
|
||||
}
|
||||
|
||||
public ByteRandom(IntFunction<byte[]> randomFunction) {
|
||||
this.randomFunction = randomFunction != null ? randomFunction : newRandomFunction(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextLong() {
|
||||
long number = 0;
|
||||
byte[] bytes = this.randomFunction.apply(Long.BYTES);
|
||||
for (int i = 0; i < Long.BYTES; i++) {
|
||||
number = (number << 8) | (bytes[i] & 0xff);
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] nextBytes(int length) {
|
||||
return this.randomFunction.apply(length);
|
||||
}
|
||||
|
||||
protected static IntFunction<byte[]> newRandomFunction(Random random) {
|
||||
final Random entropy = random != null ? random : new SecureRandom();
|
||||
return (final int length) -> {
|
||||
final byte[] bytes = new byte[length];
|
||||
entropy.nextBytes(bytes);
|
||||
return bytes;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,16 @@ package com.github.f4b6a3.ulid;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.github.f4b6a3.ulid.Ulid;
|
||||
import com.github.f4b6a3.ulid.UlidCreator;
|
||||
import com.github.f4b6a3.ulid.UlidFactory;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.SplittableRandom;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.LongSupplier;
|
||||
|
||||
public class UlidFactoryDefaultfTest extends UlidFactoryTest {
|
||||
|
||||
|
@ -59,4 +62,188 @@ public class UlidFactoryDefaultfTest extends UlidFactoryTest {
|
|||
assertEquals(time, ulid.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefault() {
|
||||
UlidFactory factory = new UlidFactory();
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandom() {
|
||||
{
|
||||
Random random = new Random();
|
||||
UlidFactory factory = UlidFactory.newInstance(random);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
{
|
||||
SecureRandom random = new SecureRandom();
|
||||
UlidFactory factory = UlidFactory.newInstance(random);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandomNull() {
|
||||
UlidFactory factory = UlidFactory.newInstance((Random) null);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandomFunction() {
|
||||
{
|
||||
SplittableRandom random = new SplittableRandom();
|
||||
LongSupplier function = () -> random.nextLong();
|
||||
UlidFactory factory = UlidFactory.newInstance(function);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
{
|
||||
IntFunction<byte[]> function = (length) -> {
|
||||
byte[] bytes = new byte[length];
|
||||
ThreadLocalRandom.current().nextBytes(bytes);
|
||||
return bytes;
|
||||
};
|
||||
UlidFactory factory = UlidFactory.newInstance(function);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandomFunctionNull() {
|
||||
{
|
||||
UlidFactory factory = UlidFactory.newInstance((LongSupplier) null);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
{
|
||||
UlidFactory factory = UlidFactory.newInstance((IntFunction<byte[]>) null);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteRandomNextLong() {
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
byte[] bytes = new byte[Long.BYTES];
|
||||
(new Random()).nextBytes(bytes);
|
||||
long number = ByteBuffer.wrap(bytes).getLong();
|
||||
UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> bytes);
|
||||
assertEquals(number, random.nextLong());
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
int longs = 10;
|
||||
int size = Long.BYTES * longs;
|
||||
|
||||
byte[] bytes = new byte[size];
|
||||
(new Random()).nextBytes(bytes);
|
||||
ByteBuffer buffer1 = ByteBuffer.wrap(bytes);
|
||||
ByteBuffer buffer2 = ByteBuffer.wrap(bytes);
|
||||
|
||||
UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> {
|
||||
byte[] octects = new byte[x];
|
||||
buffer1.get(octects);
|
||||
return octects;
|
||||
});
|
||||
|
||||
for (int j = 0; j < longs; j++) {
|
||||
assertEquals(buffer2.getLong(), random.nextLong());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteRandomNextBytes() {
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
byte[] bytes = new byte[Long.BYTES];
|
||||
(new Random()).nextBytes(bytes);
|
||||
UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> bytes);
|
||||
assertEquals(Arrays.toString(bytes), Arrays.toString(random.nextBytes(Long.BYTES)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
int ints = 10;
|
||||
int size = Long.BYTES * ints;
|
||||
|
||||
byte[] bytes = new byte[size];
|
||||
(new Random()).nextBytes(bytes);
|
||||
ByteBuffer buffer1 = ByteBuffer.wrap(bytes);
|
||||
ByteBuffer buffer2 = ByteBuffer.wrap(bytes);
|
||||
|
||||
UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> {
|
||||
byte[] octects = new byte[x];
|
||||
buffer1.get(octects);
|
||||
return octects;
|
||||
});
|
||||
|
||||
for (int j = 0; j < ints; j++) {
|
||||
byte[] octects = new byte[Long.BYTES];
|
||||
buffer2.get(octects);
|
||||
assertEquals(Arrays.toString(octects), Arrays.toString(random.nextBytes(Long.BYTES)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogRandomNextLong() {
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
byte[] bytes = new byte[Long.BYTES];
|
||||
(new Random()).nextBytes(bytes);
|
||||
long number = ByteBuffer.wrap(bytes).getLong();
|
||||
UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> number);
|
||||
assertEquals(number, random.nextLong());
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
int ints = 10;
|
||||
int size = Long.BYTES * ints;
|
||||
|
||||
byte[] bytes = new byte[size];
|
||||
(new Random()).nextBytes(bytes);
|
||||
ByteBuffer buffer1 = ByteBuffer.wrap(bytes);
|
||||
ByteBuffer buffer2 = ByteBuffer.wrap(bytes);
|
||||
|
||||
UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> buffer1.getLong());
|
||||
|
||||
for (int j = 0; j < ints; j++) {
|
||||
assertEquals(buffer2.getLong(), random.nextLong());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogRandomNextBytes() {
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
byte[] bytes = new byte[Long.BYTES];
|
||||
(new Random()).nextBytes(bytes);
|
||||
long number = ByteBuffer.wrap(bytes).getLong();
|
||||
UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> number);
|
||||
assertEquals(Arrays.toString(bytes), Arrays.toString(random.nextBytes(Long.BYTES)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
int ints = 10;
|
||||
int size = Long.BYTES * ints;
|
||||
|
||||
byte[] bytes = new byte[size];
|
||||
(new Random()).nextBytes(bytes);
|
||||
ByteBuffer buffer1 = ByteBuffer.wrap(bytes);
|
||||
ByteBuffer buffer2 = ByteBuffer.wrap(bytes);
|
||||
|
||||
UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> buffer1.getLong());
|
||||
|
||||
for (int j = 0; j < ints; j++) {
|
||||
byte[] octects = new byte[Long.BYTES];
|
||||
buffer2.get(octects);
|
||||
assertEquals(Arrays.toString(octects), Arrays.toString(random.nextBytes(Long.BYTES)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@ package com.github.f4b6a3.ulid;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.github.f4b6a3.ulid.Ulid;
|
||||
import com.github.f4b6a3.ulid.UlidCreator;
|
||||
import com.github.f4b6a3.ulid.UlidFactory;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.time.Clock;
|
||||
|
@ -13,7 +9,10 @@ import java.time.Instant;
|
|||
import java.time.ZoneId;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.SplittableRandom;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.LongSupplier;
|
||||
|
||||
public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
||||
|
||||
|
@ -66,7 +65,7 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
|||
}
|
||||
};
|
||||
|
||||
Supplier<byte[]> randomSupplier = UlidFactory.getRandomSupplier(new Random());
|
||||
IntFunction<byte[]> randomSupplier = UlidFactory.ByteRandom.newRandomFunction(new Random());
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(randomSupplier, clock);
|
||||
|
||||
long ms1 = factory.create().getTime(); // time
|
||||
|
@ -115,7 +114,7 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
|||
}
|
||||
};
|
||||
|
||||
Supplier<byte[]> randomSupplier = UlidFactory.getRandomSupplier(new Random());
|
||||
IntFunction<byte[]> randomSupplier = UlidFactory.ByteRandom.newRandomFunction(new Random());
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(randomSupplier, clock);
|
||||
|
||||
long ms1 = factory.create().getTime(); // second
|
||||
|
@ -163,4 +162,63 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
|||
assertEquals(time, ulid.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandom() {
|
||||
Random random = new Random();
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(random);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandomNull() {
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance((Random) null);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandomFunction() {
|
||||
{
|
||||
SplittableRandom random = new SplittableRandom();
|
||||
LongSupplier function = () -> random.nextLong();
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(function);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
{
|
||||
SplittableRandom random = new SplittableRandom();
|
||||
LongSupplier function = () -> random.nextLong();
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(function, Clock.systemDefaultZone());
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
{
|
||||
IntFunction<byte[]> function = (length) -> {
|
||||
byte[] bytes = new byte[length];
|
||||
ThreadLocalRandom.current().nextBytes(bytes);
|
||||
return bytes;
|
||||
};
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(function);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
{
|
||||
IntFunction<byte[]> function = (length) -> {
|
||||
byte[] bytes = new byte[length];
|
||||
ThreadLocalRandom.current().nextBytes(bytes);
|
||||
return bytes;
|
||||
};
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(function, Clock.systemDefaultZone());
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRandomFunctionNull() {
|
||||
{
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance((LongSupplier) null);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
{
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance((IntFunction<byte[]>) null);
|
||||
assertNotNull(factory.create());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@ import java.util.Random;
|
|||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.github.f4b6a3.ulid.UlidFactory;
|
||||
|
||||
public abstract class UlidFactoryTest {
|
||||
|
||||
protected static final int DEFAULT_LOOP_MAX = 10_000;
|
||||
|
|
|
@ -15,8 +15,6 @@ import java.util.UUID;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.github.f4b6a3.ulid.Ulid;
|
||||
|
||||
public class UlidTest {
|
||||
|
||||
private static final int DEFAULT_LOOP_MAX = 1_000;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package com.github.f4b6a3.ulid;
|
||||
package com.github.f4b6a3.ulid.uniq;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
|
||||
import com.github.f4b6a3.ulid.TestSuite;
|
||||
import com.github.f4b6a3.ulid.Ulid;
|
||||
import com.github.f4b6a3.ulid.UlidFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* This test starts many threads that keep requesting thousands of ULIDs to a
|
Loading…
Reference in New Issue