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 {
|
||||
|
||||
private final Clock clock; // for tests
|
||||
private final LongSupplier timeMillisNow; // for tests
|
||||
private final LongFunction<Ulid> ulidFunction;
|
||||
|
||||
// ******************************
|
||||
|
@ -64,12 +64,16 @@ public final class UlidFactory {
|
|||
}
|
||||
|
||||
private UlidFactory(LongFunction<Ulid> ulidFunction) {
|
||||
this(ulidFunction, null);
|
||||
this(ulidFunction, (LongSupplier) null);
|
||||
}
|
||||
|
||||
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.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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
|
@ -160,6 +175,19 @@ public final class UlidFactory {
|
|||
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.
|
||||
* <p>
|
||||
|
@ -170,7 +198,20 @@ public final class UlidFactory {
|
|||
* @return {@link UlidFactory}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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) {
|
||||
this(random, clock::millis);
|
||||
}
|
||||
|
||||
public MonotonicFunction(IRandom random, LongSupplier timeMillisNow) {
|
||||
this.random = random;
|
||||
// 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
|
||||
|
|
Loading…
Reference in New Issue