Skip to content

Commit 7bd8e3b

Browse files
committed
light code improvements to id.uuid package
1 parent dc58553 commit 7bd8e3b

File tree

5 files changed

+70
-84
lines changed

5 files changed

+70
-84
lines changed

hibernate-core/src/main/java/org/hibernate/id/uuid/CustomVersionOneStrategy.java

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
import org.hibernate.internal.build.AllowSysOut;
1212
import org.hibernate.internal.util.BytesHelper;
1313

14+
import static java.lang.System.arraycopy;
15+
import static java.lang.System.currentTimeMillis;
16+
import static org.hibernate.id.uuid.Helper.getAddressBytes;
17+
import static org.hibernate.id.uuid.Helper.getCountBytes;
18+
import static org.hibernate.id.uuid.Helper.getJvmIdentifierBytes;
19+
1420
/**
1521
* Applies a version 1 (time-based) generation strategy (using ip address rather than mac address) but applies them in a
1622
* different layout. The strategy is very similar to the legacy {@link org.hibernate.id.UUIDHexGenerator} id generator
@@ -31,22 +37,21 @@ public int getGeneratedVersion() {
3137

3238
public CustomVersionOneStrategy() {
3339
// generate the "most significant bits" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
34-
byte[] hiBits = new byte[8];
35-
// use address as first 32 bits (8 * 4 bytes)
36-
System.arraycopy( Helper.getAddressBytes(), 0, hiBits, 0, 4 );
40+
final byte[] hiBits = new byte[8];
41+
// use address as the first 32 bits (8 * 4 bytes)
42+
arraycopy( getAddressBytes(), 0, hiBits, 0, 4 );
3743
// use the "jvm identifier" as the next 32 bits
38-
System.arraycopy( Helper.getJvmIdentifierBytes(), 0, hiBits, 4, 4 );
44+
arraycopy( getJvmIdentifierBytes(), 0, hiBits, 4, 4 );
3945
// set the version (rfc term) appropriately
4046
hiBits[6] &= 0x0f;
4147
hiBits[6] |= 0x10;
42-
4348
mostSignificantBits = BytesHelper.asLong( hiBits );
4449
}
4550

4651
@Override
4752
public UUID generateUuid(SharedSessionContractImplementor session) {
48-
long leastSignificantBits = generateLeastSignificantBits( System.currentTimeMillis() );
49-
return new UUID( mostSignificantBits, leastSignificantBits );
53+
return new UUID( mostSignificantBits,
54+
generateLeastSignificantBits( currentTimeMillis() ) );
5055
}
5156

5257
@Override
@@ -59,33 +64,31 @@ public long getMostSignificantBits() {
5964
}
6065

6166
public static long generateLeastSignificantBits(long seed) {
62-
byte[] loBits = new byte[8];
63-
64-
short hiTime = (short) ( seed >>> 32 );
65-
int loTime = (int) seed;
66-
System.arraycopy( BytesHelper.fromShort( hiTime ), 0, loBits, 0, 2 );
67-
System.arraycopy( BytesHelper.fromInt( loTime ), 0, loBits, 2, 4 );
68-
System.arraycopy( Helper.getCountBytes(), 0, loBits, 6, 2 );
67+
final byte[] loBits = new byte[8];
68+
final short hiTime = (short) ( seed >>> 32 );
69+
final int loTime = (int) seed;
70+
arraycopy( BytesHelper.fromShort( hiTime ), 0, loBits, 0, 2 );
71+
arraycopy( BytesHelper.fromInt( loTime ), 0, loBits, 2, 4 );
72+
arraycopy( getCountBytes(), 0, loBits, 6, 2 );
6973
loBits[0] &= 0x3f;
70-
loBits[0] |= ((byte)2 << (byte)6 );
71-
74+
loBits[0] |= ((byte)2 << (byte)6);
7275
return BytesHelper.asLong( loBits );
7376
}
7477

7578
@AllowSysOut
7679
public static void main(String[] args) {
77-
CustomVersionOneStrategy strategy = new CustomVersionOneStrategy();
80+
final var strategy = new CustomVersionOneStrategy();
7881

7982
for ( int i = 0; i < 1000; i++ ) {
8083
System.out.println( "Generation # " + i + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
8184
byte[] loBits = new byte[8];
8285

83-
long sysTime = System.currentTimeMillis();
84-
short hiTime = (short) ( System.currentTimeMillis() >>> 32 );
86+
long sysTime = currentTimeMillis();
87+
short hiTime = (short) ( currentTimeMillis() >>> 32 );
8588
int loTime = (int) sysTime;
86-
System.arraycopy( BytesHelper.fromShort( hiTime ), 0, loBits, 0, 2 );
87-
System.arraycopy( BytesHelper.fromInt( loTime ), 0, loBits, 2, 4 );
88-
System.arraycopy( Helper.getCountBytes(), 0, loBits, 6, 2 );
89+
arraycopy( BytesHelper.fromShort( hiTime ), 0, loBits, 0, 2 );
90+
arraycopy( BytesHelper.fromInt( loTime ), 0, loBits, 2, 4 );
91+
arraycopy( getCountBytes(), 0, loBits, 6, 2 );
8992

9093
System.out.println( " before bit setting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
9194
System.out.println( " loBits[0] : " + BytesHelper.toBinaryString( loBits[0] ) );

hibernate-core/src/main/java/org/hibernate/id/uuid/Helper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ public static byte[] getCountBytes() {
9898
// Helper methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9999

100100
public static String format(int value) {
101-
final String formatted = Integer.toHexString( value );
102-
StringBuilder buf = new StringBuilder( "00000000" );
101+
final var formatted = Integer.toHexString( value );
102+
final var buf = new StringBuilder( "00000000" );
103103
buf.replace( 8 - formatted.length(), 8, formatted );
104104
return buf.toString();
105105
}
106106

107107
public static String format(short value) {
108-
String formatted = Integer.toHexString( value );
109-
StringBuilder buf = new StringBuilder( "0000" );
108+
final var formatted = Integer.toHexString( value );
109+
final var buf = new StringBuilder( "0000" );
110110
buf.replace( 4 - formatted.length(), 4, formatted );
111111
return buf.toString();
112112
}

hibernate-core/src/main/java/org/hibernate/id/uuid/UuidGenerator.java

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,15 @@ public UuidGenerator(
5757
org.hibernate.annotations.UuidGenerator config,
5858
MemberDetails memberDetails) {
5959
generator = determineValueGenerator( config, memberDetails.getDeclaringType().getName(), memberDetails.getName() );
60-
61-
final Class<?> memberType = memberDetails.getType().determineRawClass().toJavaClass();
62-
valueTransformer = determineProperTransformer( memberType );
60+
valueTransformer = determineProperTransformer( memberDetails.getType().determineRawClass().toJavaClass() );
6361
}
6462

6563
@Internal
6664
public UuidGenerator(
6765
org.hibernate.annotations.UuidGenerator config,
6866
Member idMember) {
6967
generator = determineValueGenerator( config, idMember.getDeclaringClass().getName(), idMember.getName() );
70-
71-
final Class<?> propertyType = getPropertyType( idMember );
72-
this.valueTransformer = determineProperTransformer( propertyType );
68+
valueTransformer = determineProperTransformer( getPropertyType( idMember ) );
7369
}
7470

7571
public UuidGenerator(
@@ -106,39 +102,34 @@ private static UuidValueGenerator determineValueGenerator(
106102
org.hibernate.annotations.UuidGenerator config,
107103
String memberDeclaringClassName,
108104
String memberName) {
109-
if ( config != null ) {
105+
if ( config == null ) {
106+
return StandardRandomStrategy.INSTANCE;
107+
}
108+
else {
110109
// there is an annotation
110+
final var style = config.style();
111111
if ( config.algorithm() != UuidValueGenerator.class ) {
112112
// the annotation specified a custom algorithm
113-
if ( config.style() != AUTO ) {
113+
if ( style != AUTO ) {
114114
throw new MappingException(
115115
String.format(
116116
Locale.ROOT,
117-
"Style [%s] should not be specified with custom UUID value generator : %s.%s",
118-
config.style().name(),
117+
"Style [%s] should not be specified with custom UUID value generator: %s.%s",
118+
style.name(),
119119
memberDeclaringClassName,
120120
memberName
121121
)
122122
);
123123
}
124124
return instantiateCustomGenerator( config.algorithm() );
125125
}
126-
if ( config.style() == TIME ) {
127-
return new CustomVersionOneStrategy();
128-
}
129-
if ( config.style() == VERSION_6 ) {
130-
return UuidVersion6Strategy.INSTANCE;
131-
}
132-
if ( config.style() == VERSION_7 ) {
133-
return UuidVersion7Strategy.INSTANCE;
134-
}
135-
// NOTE : AUTO falls through
126+
return switch ( style ) {
127+
case TIME -> new CustomVersionOneStrategy();
128+
case VERSION_6 -> UuidVersion6Strategy.INSTANCE;
129+
case VERSION_7 -> UuidVersion7Strategy.INSTANCE;
130+
default -> StandardRandomStrategy.INSTANCE;
131+
};
136132
}
137-
138-
// Either -
139-
// 1. there is no annotation
140-
// 2. the annotation specified AUTO (with no custom algorithm)
141-
return StandardRandomStrategy.INSTANCE;
142133
}
143134

144135
private static UuidValueGenerator instantiateCustomGenerator(Class<? extends UuidValueGenerator> algorithmClass) {
@@ -154,15 +145,14 @@ private ValueTransformer determineProperTransformer(Class<?> propertyType) {
154145
if ( UUID.class.isAssignableFrom( propertyType ) ) {
155146
return UUIDJavaType.PassThroughTransformer.INSTANCE;
156147
}
157-
158-
if ( String.class.isAssignableFrom( propertyType ) ) {
148+
else if ( String.class.isAssignableFrom( propertyType ) ) {
159149
return UUIDJavaType.ToStringTransformer.INSTANCE;
160150
}
161-
162-
if ( byte[].class.isAssignableFrom( propertyType ) ) {
151+
else if ( byte[].class.isAssignableFrom( propertyType ) ) {
163152
return UUIDJavaType.ToBytesTransformer.INSTANCE;
164153
}
165-
166-
throw new HibernateException( "Unanticipated return type [" + propertyType.getName() + "] for UUID conversion" );
154+
else {
155+
throw new HibernateException( "Unanticipated return type [" + propertyType.getName() + "] for UUID conversion" );
156+
}
167157
}
168158
}

hibernate-core/src/main/java/org/hibernate/id/uuid/UuidVersion6Strategy.java

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,16 @@ public static class Holder {
4040
static final long EPOCH_1582_SECONDS = LocalDate.of( 1582, 10, 15 )
4141
.atStartOfDay( ZoneId.of( "UTC" ) )
4242
.toInstant().getEpochSecond();
43-
4443
}
4544

4645
private record State(long lastTimestamp, int lastSequence) {
4746
public State getNextState() {
4847
final long now = instantToTimestamp();
49-
if ( this.lastTimestamp < now ) {
50-
return new State(
51-
now,
52-
randomSequence()
53-
);
48+
if ( lastTimestamp < now ) {
49+
return new State( now, randomSequence() );
5450
}
5551
else if ( lastSequence == 0x3FFF ) {
56-
return new State(
57-
this.lastTimestamp + 1,
58-
randomSequence()
59-
);
52+
return new State( lastTimestamp + 1, randomSequence() );
6053
}
6154
else {
6255
return new State( lastTimestamp, lastSequence + 1 );
@@ -68,7 +61,7 @@ private static int randomSequence() {
6861
}
6962

7063
private static long instantToTimestamp() {
71-
final Instant instant = Instant.now();
64+
final var instant = Instant.now();
7265
final long seconds = instant.getEpochSecond() - Holder.EPOCH_1582_SECONDS;
7366
return seconds * 10_000_000 + instant.getNano() / 100;
7467
}
@@ -101,20 +94,19 @@ public UUID generateUUID(final SharedSessionContractImplementor session) {
10194

10295
@Override
10396
public UUID generateUuid(final SharedSessionContractImplementor session) {
104-
final State state = lastState.updateAndGet( State::getNextState );
105-
97+
final var state = lastState.updateAndGet( State::getNextState );
10698
return new UUID(
107-
// MSB bits 0-47 - most significant 32 bits of the 60-bit starting timestamp
99+
// MSB bits 0-47 - the most significant 32 bits of the 60-bit starting timestamp
108100
state.lastTimestamp << 4 & 0xFFFF_FFFF_FFFF_0000L
109101
// MSB bits 48-51 - version = 6
110102
| 0x6000L
111-
// MSB bits 52-63 - least significant 12 bits from the 60-bit starting timestamp
103+
// MSB bits 52-63 - the least significant 12 bits from the 60-bit starting timestamp
112104
| state.lastTimestamp & 0x0FFFL,
113105
// LSB bits 0-1 - variant = 4
114106
0x8000_0000_0000_0000L
115107
// LSB bits 2-15 - clock sequence
116108
| (long) state.lastSequence << 48
117-
// LSB bits 16-63 - pseudorandom data, least significant bit of the first octet is set to 1
109+
// LSB bits 16-63 - pseudorandom data, the least significant bit of the first octet is set to 1
118110
| randomNode()
119111
);
120112
}

hibernate-core/src/main/java/org/hibernate/id/uuid/UuidVersion7Strategy.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public class UuidVersion7Strategy implements UUIDGenerationStrategy, UuidValueGe
4242
@Internal
4343
public static class Holder {
4444
private static final SecureRandom numberGenerator = new SecureRandom();
45-
4645
}
4746

4847
public record State(Instant lastTimestamp, long lastSequence, long nanos) {
@@ -60,20 +59,23 @@ private static long nanos(Instant timestamp) {
6059
}
6160

6261
public State getNextState() {
63-
final Instant now = Instant.now();
64-
if ( lastTimestamp.toEpochMilli() < now.toEpochMilli() ||
65-
lastTimestamp.toEpochMilli() == now.toEpochMilli() && nanos < nanos( now ) ) {
62+
final var now = Instant.now();
63+
if ( lastTimestampEarlierThan( now ) ) {
6664
return new State( now, randomSequence() );
6765
}
68-
final long nextSequence = lastSequence + Holder.numberGenerator.nextLong( 0xFFFF_FFFFL );
69-
if ( nextSequence > MAX_RANDOM_SEQUENCE ) {
70-
return new State( lastTimestamp.plusNanos( 250 ), randomSequence() );
71-
}
7266
else {
73-
return new State( lastTimestamp, nextSequence );
67+
final long nextSequence = lastSequence + Holder.numberGenerator.nextLong( 0xFFFF_FFFFL );
68+
return nextSequence > MAX_RANDOM_SEQUENCE
69+
? new State( lastTimestamp.plusNanos( 250 ), randomSequence() )
70+
: new State( lastTimestamp, nextSequence );
7471
}
7572
}
7673

74+
private boolean lastTimestampEarlierThan(Instant now) {
75+
return lastTimestamp.toEpochMilli() < now.toEpochMilli()
76+
|| lastTimestamp.toEpochMilli() == now.toEpochMilli() && nanos < nanos( now );
77+
}
78+
7779
private static long randomSequence() {
7880
return Holder.numberGenerator.nextLong( MAX_RANDOM_SEQUENCE );
7981
}
@@ -106,8 +108,7 @@ public UUID generateUUID(final SharedSessionContractImplementor session) {
106108

107109
@Override
108110
public UUID generateUuid(final SharedSessionContractImplementor session) {
109-
final State state = lastState.updateAndGet( State::getNextState );
110-
111+
final var state = lastState.updateAndGet( State::getNextState );
111112
return new UUID(
112113
// MSB bits 0-47 - 48-bit big-endian unsigned number of the Unix Epoch timestamp in milliseconds
113114
state.millis() << 16 & 0xFFFF_FFFF_FFFF_0000L

0 commit comments

Comments
 (0)