Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions uuid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,29 @@ func BenchmarkUUID_NewPooled(b *testing.B) {
})
}

func BenchmarkUUID_NewV7(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := NewV7()
if err != nil {
b.Fatal(err)
}
}
})
}

func BenchmarkUUID_NewV7Pooled(b *testing.B) {
EnableRandPool()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := NewV7()
if err != nil {
b.Fatal(err)
}
}
})
}

func BenchmarkUUIDs_Strings(b *testing.B) {
uuid1, err := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if err != nil {
Expand Down
31 changes: 16 additions & 15 deletions version7.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package uuid

import (
"io"
"sync/atomic"
)

// UUID version 7 features a time-ordered value field derived from the widely
Expand Down Expand Up @@ -77,28 +78,28 @@ func makeV7(uuid []byte) {
// lastV7time is the last time we returned stored as:
//
// 52 bits of time in milliseconds since epoch
// 12 bits of (fractional nanoseconds) >> 8
var lastV7time int64
// 12 bits of sequence number.
var lastV7time atomic.Int64

const nanoPerMilli = 1000000

// getV7Time returns the time in milliseconds and nanoseconds / 256.
// getV7Time returns the time in milliseconds and the sequence number.
// The returned (milli << 12 + seq) is guaranteed to be greater than
// (milli << 12 + seq) returned by any previous call to getV7Time.
func getV7Time() (milli, seq int64) {
timeMu.Lock()
defer timeMu.Unlock()
milli = timeNow().UnixMilli()

nano := timeNow().UnixNano()
milli = nano / nanoPerMilli
// Sequence number is between 0 and 3906 (nanoPerMilli>>8)
seq = (nano - milli*nanoPerMilli) >> 8
now := milli<<12 + seq
if now <= lastV7time {
now = lastV7time + 1
milli = now >> 12
seq = now & 0xfff
for {
oldVal := lastV7time.Load()
if milli <= (oldVal+1)>>12 {
break
}
lastV7time.CompareAndSwap(oldVal, (milli<<12)-1)
}
lastV7time = now

result := lastV7time.Add(1)
milli = result >> 12
seq = result & 0xfff

return milli, seq
}