@@ -44,15 +44,15 @@ func NewV7FromReader(r io.Reader) (UUID, error) {
44
44
45
45
// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6])
46
46
// uuid[8] already has the right version number (Variant is 10)
47
- // see function NewV7 and NewV7FromReader
47
+ // see function NewV7 and NewV7FromReader
48
48
func makeV7 (uuid []byte ) {
49
49
/*
50
50
0 1 2 3
51
51
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
52
52
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53
53
| unix_ts_ms |
54
54
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55
- | unix_ts_ms | ver | rand_a |
55
+ | unix_ts_ms | ver | rand_a (12 bit seq) |
56
56
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
57
|var| rand_b |
58
58
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -61,7 +61,7 @@ func makeV7(uuid []byte) {
61
61
*/
62
62
_ = uuid [15 ] // bounds check
63
63
64
- t := timeNow (). UnixMilli ()
64
+ t , s := getV7Time ()
65
65
66
66
uuid [0 ] = byte (t >> 40 )
67
67
uuid [1 ] = byte (t >> 32 )
@@ -70,6 +70,35 @@ func makeV7(uuid []byte) {
70
70
uuid [4 ] = byte (t >> 8 )
71
71
uuid [5 ] = byte (t )
72
72
73
- uuid [6 ] = 0x70 | (uuid [6 ] & 0x0F )
74
- // uuid[8] has already has right version
73
+ uuid [6 ] = 0x70 | (0x0F & byte (s >> 8 ))
74
+ uuid [7 ] = byte (s )
75
+ }
76
+
77
+ // lastV7time is the last last time we returned stored as:
78
+ //
79
+ // 52 bits of time in milliseconds since epoch
80
+ // 12 bits of (fractional nanoseconds) >> 8
81
+ var lastV7time int64
82
+
83
+ const nanoPerMilli = 1000000
84
+
85
+ // getV7Time returns the time in milliseconds and nanoseconds / 256.
86
+ // The returned (milli << 12 + seq) is guarenteed to be greater than
87
+ // (milli << 12 + seq) returned by any previous call to getV7Time.
88
+ func getV7Time () (milli , seq int64 ) {
89
+ timeMu .Lock ()
90
+ defer timeMu .Unlock ()
91
+
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
101
+ }
102
+ lastV7time = now
103
+ return milli , seq
75
104
}
0 commit comments