Allow UlidFactory.java to accept a LongSupplier as a time source
Using a `java.time.Clock` to get the current time as milliseconds from epoch is inconvenient, as `java.time.Clock` is an abstract class requiring 3 methods to be implemented, which makes interoperability with other JVM languages e.g. Kotlin hard. By exposing overloaded factory methods that accept a LongSupplier, this problem disappears without breaking backward compatibility.
This commit is contained in:
parent
a5006743ed
commit
3ecd6c84a1
|
@ -49,7 +49,7 @@ import java.util.function.LongSupplier;
|
||||||
*/
|
*/
|
||||||
public final class UlidFactory {
|
public final class UlidFactory {
|
||||||
|
|
||||||
private final Clock clock; // for tests
|
private final LongSupplier timeMillisNow; // for tests
|
||||||
private final LongFunction<Ulid> ulidFunction;
|
private final LongFunction<Ulid> ulidFunction;
|
||||||
|
|
||||||
// ******************************
|
// ******************************
|
||||||
|
@ -64,12 +64,16 @@ public final class UlidFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private UlidFactory(LongFunction<Ulid> ulidFunction) {
|
private UlidFactory(LongFunction<Ulid> ulidFunction) {
|
||||||
this(ulidFunction, null);
|
this(ulidFunction, (LongSupplier) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UlidFactory(LongFunction<Ulid> ulidFunction, Clock clock) {
|
private UlidFactory(LongFunction<Ulid> ulidFunction, Clock clock) {
|
||||||
|
this(ulidFunction, clock != null ? clock::millis : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UlidFactory(LongFunction<Ulid> ulidFunction, LongSupplier timeMillisNow) {
|
||||||
this.ulidFunction = ulidFunction;
|
this.ulidFunction = ulidFunction;
|
||||||
this.clock = clock != null ? clock : Clock.systemUTC();
|
this.timeMillisNow = timeMillisNow != null ? timeMillisNow : Clock.systemUTC()::millis;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,6 +140,17 @@ public final class UlidFactory {
|
||||||
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(random)));
|
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(random)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new monotonic factory.
|
||||||
|
*
|
||||||
|
* @param random a {@link Random} generator
|
||||||
|
* @param timeMillisNow a function that returns the current time as milliseconds from epoch
|
||||||
|
* @return {@link UlidFactory}
|
||||||
|
*/
|
||||||
|
public static UlidFactory newMonotonicInstance(Random random, LongSupplier timeMillisNow) {
|
||||||
|
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(random), timeMillisNow), timeMillisNow);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new monotonic factory.
|
* Returns a new monotonic factory.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -160,6 +175,19 @@ public final class UlidFactory {
|
||||||
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction)));
|
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new monotonic factory.
|
||||||
|
* <p>
|
||||||
|
* The given random function must return a long value.
|
||||||
|
*
|
||||||
|
* @param randomFunction a random function that returns a long value
|
||||||
|
* @param timeMillisNow a function that returns the current time as milliseconds from epoch
|
||||||
|
* @return {@link UlidFactory}
|
||||||
|
*/
|
||||||
|
public static UlidFactory newMonotonicInstance(LongSupplier randomFunction, LongSupplier timeMillisNow) {
|
||||||
|
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction), timeMillisNow), timeMillisNow);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new monotonic factory.
|
* Returns a new monotonic factory.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -170,7 +198,20 @@ public final class UlidFactory {
|
||||||
* @return {@link UlidFactory}
|
* @return {@link UlidFactory}
|
||||||
*/
|
*/
|
||||||
static UlidFactory newMonotonicInstance(LongSupplier randomFunction, Clock clock) {
|
static UlidFactory newMonotonicInstance(LongSupplier randomFunction, Clock clock) {
|
||||||
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction), clock), clock);
|
return UlidFactory.newMonotonicInstance(randomFunction, clock::millis);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new monotonic factory.
|
||||||
|
* <p>
|
||||||
|
* The given random function must return a byte array.
|
||||||
|
*
|
||||||
|
* @param randomFunction a random function that returns a byte array
|
||||||
|
* @param timeMillisNow a function that returns the current time as milliseconds from epoch
|
||||||
|
* @return {@link UlidFactory}
|
||||||
|
*/
|
||||||
|
public static UlidFactory newMonotonicInstance(IntFunction<byte[]> randomFunction, LongSupplier timeMillisNow) {
|
||||||
|
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction), timeMillisNow), timeMillisNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,7 +224,7 @@ public final class UlidFactory {
|
||||||
* @return {@link UlidFactory}
|
* @return {@link UlidFactory}
|
||||||
*/
|
*/
|
||||||
static UlidFactory newMonotonicInstance(IntFunction<byte[]> randomFunction, Clock clock) {
|
static UlidFactory newMonotonicInstance(IntFunction<byte[]> randomFunction, Clock clock) {
|
||||||
return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction), clock), clock);
|
return UlidFactory.newMonotonicInstance(randomFunction, clock::millis);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************
|
// ******************************
|
||||||
|
@ -196,7 +237,7 @@ public final class UlidFactory {
|
||||||
* @return a ULID
|
* @return a ULID
|
||||||
*/
|
*/
|
||||||
public synchronized Ulid create() {
|
public synchronized Ulid create() {
|
||||||
return this.ulidFunction.apply(clock.millis());
|
return this.ulidFunction.apply(timeMillisNow.getAsLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -255,9 +296,13 @@ public final class UlidFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonotonicFunction(IRandom random, Clock clock) {
|
public MonotonicFunction(IRandom random, Clock clock) {
|
||||||
|
this(random, clock::millis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonotonicFunction(IRandom random, LongSupplier timeMillisNow) {
|
||||||
this.random = random;
|
this.random = random;
|
||||||
// initialize internal state
|
// initialize internal state
|
||||||
this.lastUlid = new Ulid(clock.millis(), this.random.nextBytes(Ulid.RANDOM_BYTES));
|
this.lastUlid = new Ulid(timeMillisNow.getAsLong(), this.random.nextBytes(Ulid.RANDOM_BYTES));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue