HHH-18377 - Support for uuid v6 and v7 generated ids

This commit is contained in:
Steve Ebersole 2024-09-23 13:53:27 -05:00
parent 2f335cd786
commit c3d7e5f0b5
2 changed files with 20 additions and 42 deletions

View File

@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.hibernate.Internal;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.UUIDGenerationStrategy;
@ -30,64 +31,51 @@ import org.hibernate.id.UUIDGenerationStrategy;
* <li>48 bits - pseudorandom data to provide uniqueness.</li>
* </ul>
*
* @apiNote This strategy is field-compatible with Version 1, with the time bits reordered for improved DB locality.
*
* @author Cedomir Igaly
*/
public class UuidVersion6Strategy implements UUIDGenerationStrategy, UuidValueGenerator {
private static final Instant EPOCH_1582;
public static final UuidVersion6Strategy INSTANCE = new UuidVersion6Strategy();
static {
EPOCH_1582 = LocalDate.of( 1582, 10, 15 )
.atStartOfDay( ZoneId.of( "UTC" ) )
.toInstant();
}
private static final Instant EPOCH_1582 = LocalDate.of( 1582, 10, 15 )
.atStartOfDay( ZoneId.of( "UTC" ) )
.toInstant();
private static class Holder {
static final SecureRandom numberGenerator = new SecureRandom();
}
public static final UuidVersion6Strategy INSTANCE = new UuidVersion6Strategy();
private final Lock lock = new ReentrantLock( true );
private final AtomicLong clockSequence = new AtomicLong( 0 );
private long currentTimestamp;
private final AtomicLong clockSequence = new AtomicLong( 0 );
@Internal
public UuidVersion6Strategy() {
this( getCurrentTimestamp(), 0 );
}
@Internal
public UuidVersion6Strategy(final long currentTimestamp, final long clockSequence) {
this.currentTimestamp = currentTimestamp;
this.clockSequence.set( clockSequence );
}
/**
* A variant 6
* Version 6
*/
@Override
public int getGeneratedVersion() {
// UUIDv6 is a field-compatible version of UUIDv1, reordered for improved DB locality
return 6;
}
/**
* Delegates to {@link #generateUuid}
*/
@Override
public UUID generateUUID(SharedSessionContractImplementor session) {
return generateUuid( session );
}
/**
* @param session session
*
* @return UUID version 6
* @see UuidValueGenerator#generateUuid(SharedSessionContractImplementor)
*/
@Override
public UUID generateUuid(SharedSessionContractImplementor session) {
final long currentTimestamp = getCurrentTimestamp();

View File

@ -12,6 +12,7 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.hibernate.Internal;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.UUIDGenerationStrategy;
@ -33,6 +34,10 @@ import static java.time.temporal.ChronoUnit.MILLIS;
* <li>48 bits - pseudorandom data to provide uniqueness.</li>
* </ul>
*
* @apiNote Version 7 features a time-ordered value field derived from the widely implemented and
* well-known Unix Epoch timestamp source, the number of milliseconds since midnight 1 Jan 1970 UTC,
* leap seconds excluded.
*
* @author Cedomir Igaly
*/
public class UuidVersion7Strategy implements UUIDGenerationStrategy, UuidValueGenerator {
@ -40,52 +45,37 @@ public class UuidVersion7Strategy implements UUIDGenerationStrategy, UuidValueGe
public static final UuidVersion7Strategy INSTANCE = new UuidVersion7Strategy();
private static class Holder {
static final SecureRandom numberGenerator = new SecureRandom();
}
private final Lock lock = new ReentrantLock( true );
private final AtomicLong clockSequence;
private Duration currentTimestamp;
private final AtomicLong clockSequence;
@Internal
public UuidVersion7Strategy() {
this( getCurrentTimestamp(), 0 );
}
@Internal
public UuidVersion7Strategy(final Duration currentTimestamp, final long clockSequence) {
this.currentTimestamp = currentTimestamp;
this.clockSequence = new AtomicLong( clockSequence );
}
/**
* A variant 7
* Version 7
*/
@Override
public int getGeneratedVersion() {
/*
* UUIDv7 features a time-ordered value field derived from the widely implemented and well-
* known Unix Epoch timestamp source, the number of milliseconds since midnight 1 Jan 1970 UTC,
* leap seconds excluded.
*/
return 7;
}
/**
* Delegates to {@link #generateUuid}
*/
@Override
public UUID generateUUID(SharedSessionContractImplementor session) {
return generateUuid( session );
}
/**
* @param session session
*
* @return UUID version 7
* @see UuidValueGenerator#generateUuid(SharedSessionContractImplementor)
*/
@Override
public UUID generateUuid(SharedSessionContractImplementor session) {
final Duration currentTimestamp = getCurrentTimestamp();