From 02d6c286f11b21247ba477209d590ac890834443 Mon Sep 17 00:00:00 2001 From: Fabio Lima Date: Sun, 7 Jul 2024 01:41:23 -0300 Subject: [PATCH] Refactor UUIDv7 factory method with an instant parameter --- .../com/github/f4b6a3/uuid/UuidCreator.java | 8 +---- .../f4b6a3/uuid/factory/UuidFactory.java | 27 ++++++++++++++++ .../standard/TimeOrderedEpochFactory.java | 31 ++++++++++++++++--- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/github/f4b6a3/uuid/UuidCreator.java b/src/main/java/com/github/f4b6a3/uuid/UuidCreator.java index c781c78e..98575d9b 100644 --- a/src/main/java/com/github/f4b6a3/uuid/UuidCreator.java +++ b/src/main/java/com/github/f4b6a3/uuid/UuidCreator.java @@ -24,7 +24,6 @@ package com.github.f4b6a3.uuid; -import java.security.SecureRandom; import java.time.Instant; import java.util.Objects; import java.util.UUID; @@ -605,12 +604,7 @@ public static UUID getTimeOrderedEpochPlusN() { * @since 5.3.3 */ public static UUID getTimeOrderedEpoch(Instant instant) { - Objects.requireNonNull(instant, "Null instant"); - final long time = instant.toEpochMilli(); - SecureRandom random = new SecureRandom(); - final long msb = (time << 16) | (random.nextLong() & 0x0fffL) | 0x7000L; - final long lsb = (random.nextLong() & 0x3fffffffffffffffL) | 0x8000000000000000L; - return new UUID(msb, lsb); + return UUID7.create(Parameters.builder().withInstant(instant).build()); } /** diff --git a/src/main/java/com/github/f4b6a3/uuid/factory/UuidFactory.java b/src/main/java/com/github/f4b6a3/uuid/factory/UuidFactory.java index eff1bfb4..b56c9c83 100644 --- a/src/main/java/com/github/f4b6a3/uuid/factory/UuidFactory.java +++ b/src/main/java/com/github/f4b6a3/uuid/factory/UuidFactory.java @@ -25,6 +25,7 @@ package com.github.f4b6a3.uuid.factory; import java.nio.charset.StandardCharsets; +import java.time.Instant; import java.util.Arrays; import java.util.Objects; import java.util.UUID; @@ -100,6 +101,11 @@ public UuidVersion getVersion() { */ public static class Parameters { + /** + * Instant to be used. + */ + private final Instant instant; + /** * Name space byte array. */ @@ -127,12 +133,17 @@ public static class Parameters { */ public Parameters(Builder builder) { Objects.requireNonNull(builder); + this.instant = builder.instant; this.namespace = builder.namespace; this.name = builder.name; this.localDomain = builder.localDomain; this.localIdentifier = builder.localIdentifier; } + public Instant getInstant() { + return this.instant; + } + /** * Get the name space bytes. * @@ -183,6 +194,11 @@ public static Builder builder() { */ public static class Builder { + /** + * Instant to be used. + */ + private Instant instant; + /** * Name space byte array. */ @@ -206,6 +222,17 @@ public static class Builder { private Builder() { } + /** + * Use the instant provided. + * + * @param instant an instant + * @return the builder + */ + public Builder withInstant(Instant instant) { + this.instant = instant; + return this; + } + /** * Use the name space UUID. * diff --git a/src/main/java/com/github/f4b6a3/uuid/factory/standard/TimeOrderedEpochFactory.java b/src/main/java/com/github/f4b6a3/uuid/factory/standard/TimeOrderedEpochFactory.java index 23c50d4d..7c0aabaa 100644 --- a/src/main/java/com/github/f4b6a3/uuid/factory/standard/TimeOrderedEpochFactory.java +++ b/src/main/java/com/github/f4b6a3/uuid/factory/standard/TimeOrderedEpochFactory.java @@ -25,11 +25,13 @@ package com.github.f4b6a3.uuid.factory.standard; import java.time.Clock; +import java.time.Instant; +import java.util.Objects; import java.util.Random; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; import java.util.function.LongSupplier; -import java.util.function.Supplier; import com.github.f4b6a3.uuid.enums.UuidVersion; import com.github.f4b6a3.uuid.factory.AbstCombFactory; @@ -251,11 +253,26 @@ public static Builder builder() { */ @Override public UUID create() { - UUID uuid = this.uuidFunction.get(); + UUID uuid = this.uuidFunction.apply(null); return toUuid(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits()); } - static abstract class UuidFunction implements Supplier { + /** + * Returns a time-ordered unique identifier (UUIDv7) for a given instant. + *

+ * The random component is generated with each method invocation. + * + * @return a UUIDv7 + * @param instant a given instant + */ + @Override + public UUID create(Parameters parameters) { + Objects.requireNonNull(parameters.getInstant(), "Null instant"); + UUID uuid = this.uuidFunction.apply(parameters.getInstant()); + return toUuid(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits()); + } + + static abstract class UuidFunction implements Function { protected long msb = 0L; // most significant bits protected long lsb = 0L; // least significant bits @@ -276,10 +293,16 @@ public UuidFunction(IRandom random, LongSupplier timeFunction) { } @Override - public UUID get() { + public UUID apply(Instant instant) { lock.lock(); try { + if (instant != null) { + // The user provided the time. + reset(instant.toEpochMilli()); + return new UUID(this.msb, this.lsb); + } + final long lastTime = this.time(); final long time = timeFunction.getAsLong();