@@ -6,6 +6,7 @@ package uuid
66
77import (
88 "io"
9+ "sync/atomic"
910)
1011
1112// UUID version 7 features a time-ordered value field derived from the widely
@@ -77,28 +78,28 @@ func makeV7(uuid []byte) {
7778// lastV7time is the last time we returned stored as:
7879//
7980// 52 bits of time in milliseconds since epoch
80- // 12 bits of (fractional nanoseconds) >> 8
81- var lastV7time int64
81+ // 12 bits of sequence number.
82+ var lastV7time atomic. Int64
8283
8384const nanoPerMilli = 1000000
8485
85- // getV7Time returns the time in milliseconds and nanoseconds / 256 .
86+ // getV7Time returns the time in milliseconds and a sequence number .
8687// The returned (milli << 12 + seq) is guaranteed to be greater than
8788// (milli << 12 + seq) returned by any previous call to getV7Time.
8889func getV7Time () (milli , seq int64 ) {
89- timeMu .Lock ()
90- defer timeMu .Unlock ()
90+ milli = timeNow ().UnixMilli ()
9191
92- nano := timeNow ().UnixNano ()
93- milli = nano / nanoPerMilli
94- // Sequence number is between 0 and 3906 (nanoPerMilli>>8)
95- seq = (nano - milli * nanoPerMilli ) >> 8
96- now := milli << 12 + seq
97- if now <= lastV7time {
98- now = lastV7time + 1
99- milli = now >> 12
100- seq = now & 0xfff
92+ for {
93+ oldVal := lastV7time .Load ()
94+ if milli <= (oldVal + 1 )>> 12 {
95+ break
96+ }
97+ lastV7time .CompareAndSwap (oldVal , (milli << 12 )- 1 )
10198 }
102- lastV7time = now
99+
100+ result := lastV7time .Add (1 )
101+ milli = result >> 12
102+ seq = result & 0xfff
103+
103104 return milli , seq
104105}
0 commit comments