5
5
package org .hibernate .id .uuid ;
6
6
7
7
import java .security .SecureRandom ;
8
- import java .time .Duration ;
9
8
import java .time .Instant ;
10
9
import java .util .UUID ;
11
10
import java .util .concurrent .atomic .AtomicLong ;
16
15
import org .hibernate .engine .spi .SharedSessionContractImplementor ;
17
16
import org .hibernate .id .UUIDGenerationStrategy ;
18
17
19
- import static java .time .Instant .EPOCH ;
20
18
import static java .time .temporal .ChronoUnit .MILLIS ;
21
19
22
20
/**
@@ -50,15 +48,15 @@ private static class Holder {
50
48
51
49
private final Lock lock = new ReentrantLock ( true );
52
50
private final AtomicLong clockSequence ;
53
- private Duration currentTimestamp ;
51
+ private Instant currentTimestamp ;
54
52
55
53
@ Internal
56
54
public UuidVersion7Strategy () {
57
- this ( getCurrentTimestamp (), 0 );
55
+ this ( Instant . now (), 0 );
58
56
}
59
57
60
58
@ Internal
61
- public UuidVersion7Strategy (final Duration currentTimestamp , final long clockSequence ) {
59
+ public UuidVersion7Strategy (final Instant currentTimestamp , final long clockSequence ) {
62
60
this .currentTimestamp = currentTimestamp ;
63
61
this .clockSequence = new AtomicLong ( clockSequence );
64
62
}
@@ -78,12 +76,12 @@ public UUID generateUUID(SharedSessionContractImplementor session) {
78
76
79
77
@ Override
80
78
public UUID generateUuid (SharedSessionContractImplementor session ) {
81
- final Duration currentTimestamp = getCurrentTimestamp ();
79
+ final Instant currentTimestamp = Instant . now ();
82
80
83
81
final long seq = getSequence ( currentTimestamp );
84
82
85
- final long millis = currentTimestamp .getSeconds () * 1000 + currentTimestamp . getNano () / 1_000_000 ;
86
- final long nanosPart = Math . round ( ( currentTimestamp .getNano () % 1_000_000L ) * 0.004096 );
83
+ final long millis = currentTimestamp .toEpochMilli () ;
84
+ final long nanosPart = ( long ) ( ( currentTimestamp .getNano () % 1_000_000L ) * 0.004096 );
87
85
88
86
return new UUID (
89
87
// MSB bits 0-47 - 48-bit big-endian unsigned number of the Unix Epoch timestamp in milliseconds
@@ -101,21 +99,17 @@ public UUID generateUuid(SharedSessionContractImplementor session) {
101
99
);
102
100
}
103
101
104
- private long getSequence (final Duration currentTimestamp ) {
102
+ private long getSequence (final Instant currentTimestamp ) {
105
103
lock .lock ();
106
104
try {
107
- if ( ! this .currentTimestamp .equals ( currentTimestamp ) ) {
108
- this .currentTimestamp = currentTimestamp ;
109
- clockSequence .set ( 0 );
105
+ if ( this .currentTimestamp .toEpochMilli () < currentTimestamp . toEpochMilli ( ) ) {
106
+ this .currentTimestamp = currentTimestamp . truncatedTo ( MILLIS ) ;
107
+ clockSequence .updateAndGet ( l -> l & 0x1FFFL );
110
108
}
111
109
}
112
110
finally {
113
111
lock .unlock ();
114
112
}
115
113
return clockSequence .getAndIncrement ();
116
114
}
117
-
118
- private static Duration getCurrentTimestamp () {
119
- return Duration .between ( EPOCH , Instant .now () ).truncatedTo ( MILLIS );
120
- }
121
115
}
0 commit comments