Initialize the monotonic factory with the minimum timestamp
Now the `MonotonicFunction` inner class is initialized with the instant 1970-01-01 00:00:00.000 UTC, which is represented by the value 0L. Also updated the documentation and the unit tests.
This commit is contained in:
parent
c7191c6e27
commit
dbf31d3be7
|
@ -149,10 +149,14 @@ public final class Ulid implements Serializable, Comparable<Ulid> {
|
|||
/**
|
||||
* Creates a new ULID.
|
||||
* <p>
|
||||
* Time parameter is the number of milliseconds since 1970-01-01 (Unix epoch).
|
||||
* It must be a positive number not larger than 2^48-1.
|
||||
* The time parameter is the number of milliseconds since 1970-01-01, also known
|
||||
* as Unix epoch. It must be a positive number not larger than 2^48-1.
|
||||
* <p>
|
||||
* Random parameter must be an array of 10 bytes.
|
||||
* The random parameter must be an arbitrary array of 10 bytes.
|
||||
* <p>
|
||||
* Note: ULIDs cannot be composed of dates before 1970-01-01, as their embedded
|
||||
* timestamp is internally treated as an unsigned integer, i.e., it can only
|
||||
* represent the set of natural numbers including zero, up to 2^48-1.
|
||||
*
|
||||
* @param time the number of milliseconds since 1970-01-01
|
||||
* @param random an array of 10 bytes
|
||||
|
|
|
@ -360,7 +360,8 @@ public final class UlidFactory {
|
|||
}
|
||||
|
||||
void initialize(LongSupplier timeFunction) {
|
||||
this.lastUlid = new Ulid(timeFunction.getAsLong(), this.random.nextBytes(Ulid.RANDOM_BYTES));
|
||||
// initialize the factory with the instant 1970-01-01 00:00:00.000 UTC
|
||||
this.lastUlid = new Ulid(0L, this.random.nextBytes(Ulid.RANDOM_BYTES));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,8 +39,7 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
|||
|
||||
long diff = UlidFactory.MonotonicFunction.CLOCK_DRIFT_TOLERANCE;
|
||||
long time = Instant.parse("2021-12-31T23:59:59.000Z").toEpochMilli();
|
||||
long times[] = { /* init */ 0L, time + 0, time + 1, time + 2, time + 3, time + 4 - diff, time + 5 - diff,
|
||||
time + 6 - diff };
|
||||
long times[] = { time + 0, time + 1, time + 2, time + 3, time + 4 - diff, time + 5 - diff, time + 6 - diff };
|
||||
|
||||
Clock clock = new Clock() {
|
||||
private int i;
|
||||
|
@ -113,8 +112,11 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
|||
@Test
|
||||
public void testGetMonotonicUlidAfterLeapSecond() {
|
||||
|
||||
// The best article about leap seconds:
|
||||
// (Unfortunately it can't be translated)
|
||||
// https://ntp.br/conteudo/artigo-leap-second/
|
||||
long time = Instant.parse("2021-12-31T23:59:59.000Z").toEpochMilli();
|
||||
long leap = time - 1000; // simulate a leap second
|
||||
long leap = time - 1000; // moving the clock hands 1 second backwards
|
||||
long times[] = { time, leap };
|
||||
|
||||
Clock clock = new Clock() {
|
||||
|
@ -144,28 +146,26 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
|||
LongSupplier randomFunction = () -> 0;
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(randomFunction, clock);
|
||||
|
||||
// the clock moved normally
|
||||
Ulid ulid1 = factory.create();
|
||||
Ulid ulid2 = factory.create();
|
||||
|
||||
long t1 = ulid1.getTime();
|
||||
long t2 = ulid2.getTime(); // leap second
|
||||
|
||||
long r1 = ulid1.getLeastSignificantBits();
|
||||
long r2 = ulid2.getLeastSignificantBits(); // leap second
|
||||
|
||||
assertEquals(time, t1);
|
||||
assertEquals(time, t2); // leap second
|
||||
|
||||
assertEquals(1, r1);
|
||||
assertEquals(2, r2);
|
||||
assertEquals(0, r1);
|
||||
|
||||
// the clock moved backwards
|
||||
Ulid ulid2 = factory.create();
|
||||
long t2 = ulid2.getTime();
|
||||
long r2 = ulid2.getLeastSignificantBits();
|
||||
assertEquals(time, t2); // should freeze
|
||||
assertEquals(1, r2); // should increment
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMonotonicUlidAfterRandomBitsOverflowFollowedByTimeBitsIncrement() {
|
||||
|
||||
long time = Instant.parse("2021-12-31T23:59:59.999Z").toEpochMilli();
|
||||
long times[] = { /* init */ 0L, time + 1, time + 2, time + 3, time, time, time };
|
||||
long times[] = { time + 1, time + 2, time + 3, time, time, time };
|
||||
|
||||
Clock clock = new Clock() {
|
||||
private int i;
|
||||
|
@ -194,8 +194,6 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest {
|
|||
LongSupplier randomSupplier = () -> 0xffffffffffffffffL;
|
||||
UlidFactory factory = UlidFactory.newMonotonicInstance(randomSupplier, clock);
|
||||
|
||||
// System.out.println("time: " + time); // 1640995199999
|
||||
|
||||
Ulid ulid1 = factory.create();
|
||||
Ulid ulid2 = factory.create();
|
||||
Ulid ulid3 = factory.create();
|
||||
|
|
Loading…
Reference in New Issue