-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add uuid version 6 and 7 #139
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright 2023 Google Inc. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package uuid | ||
|
||
import "encoding/binary" | ||
|
||
// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. | ||
// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs. | ||
// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead. | ||
// | ||
// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6 | ||
// | ||
// NewV6 returns a Version 6 UUID based on the current NodeID and clock | ||
// sequence, and the current time. If the NodeID has not been set by SetNodeID | ||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot | ||
// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by | ||
// SetClockSequence then it will be set automatically. If GetTime fails to | ||
// return the current NewV6 returns Nil and an error. | ||
func NewV6() (UUID, error) { | ||
var uuid UUID | ||
now, seq, err := GetTime() | ||
if err != nil { | ||
return uuid, err | ||
} | ||
|
||
/* | ||
0 1 2 3 | ||
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 | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| time_high | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| time_mid | time_low_and_version | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|clk_seq_hi_res | clk_seq_low | node (0-1) | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| node (2-5) | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
*/ | ||
|
||
binary.BigEndian.PutUint64(uuid[0:], uint64(now)) | ||
binary.BigEndian.PutUint16(uuid[8:], seq) | ||
|
||
uuid[6] = 0x60 | (uuid[6] & 0x0F) | ||
uuid[8] = 0x80 | (uuid[8] & 0x3F) | ||
|
||
nodeMu.Lock() | ||
if nodeID == zeroID { | ||
setNodeInterface("") | ||
} | ||
copy(uuid[10:], nodeID[:]) | ||
nodeMu.Unlock() | ||
|
||
return uuid, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2023 Google Inc. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package uuid | ||
|
||
import ( | ||
"io" | ||
) | ||
|
||
// UUID version 7 features a time-ordered value field derived from the widely | ||
// implemented and well known Unix Epoch timestamp source, | ||
// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. | ||
// As well as improved entropy characteristics over versions 1 or 6. | ||
// | ||
// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7 | ||
// | ||
// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible. | ||
// | ||
// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch). | ||
// Uses the randomness pool if it was enabled with EnableRandPool. | ||
// NewV7 use NewRandom fill random bits, if error, NewV7 returns Nil and an error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no need to specify the internal implementation. Line 22 should be: // On error, NewV7 returns Nil and an error. |
||
func NewV7() (UUID, error) { | ||
uuid, err := NewRandom() | ||
if err != nil { | ||
return uuid, err | ||
} | ||
makeV7(uuid[:]) | ||
return uuid, nil | ||
} | ||
|
||
// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch). | ||
// it use NewRandomFromReader fill random bits, if error, NewV7FromReader returns Nil and an error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // On error, NewV7FromReader returns Nil and an error. |
||
func NewV7FromReader(r io.Reader) (UUID, error) { | ||
uuid, err := NewRandomFromReader(r) | ||
if err != nil { | ||
return uuid, err | ||
} | ||
|
||
makeV7(uuid[:]) | ||
return uuid, nil | ||
} | ||
|
||
// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6]) | ||
// uuid[8] already has the right version number (Variant is 10) | ||
// see function NewV7 and NewV7FromReader | ||
func makeV7(uuid []byte) { | ||
/* | ||
0 1 2 3 | ||
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 | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| unix_ts_ms | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| unix_ts_ms | ver | rand_a | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|var| rand_b | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| rand_b | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
*/ | ||
_ = uuid[15] // bounds check | ||
|
||
t := timeNow().UnixMilli() | ||
|
||
uuid[0] = byte(t >> 40) | ||
uuid[1] = byte(t >> 32) | ||
uuid[2] = byte(t >> 24) | ||
uuid[3] = byte(t >> 16) | ||
uuid[4] = byte(t >> 8) | ||
uuid[5] = byte(t) | ||
|
||
uuid[6] = 0x70 | (uuid[6] & 0x0F) | ||
// uuid[8] has already has right version | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1, 2, 6 and 7.