|
@@ -112,21 +112,64 @@ func RandomUUID() (UUID, error) {
|
|
|
|
|
|
|
|
var timeBase = time.Date(1582, time.October, 15, 0, 0, 0, 0, time.UTC).Unix()
|
|
var timeBase = time.Date(1582, time.October, 15, 0, 0, 0, 0, time.UTC).Unix()
|
|
|
|
|
|
|
|
|
|
+// getTimestamp converts time to UUID (version 1) timestamp.
|
|
|
|
|
+// It must be an interval of 100-nanoseconds since timeBase.
|
|
|
|
|
+func getTimestamp(t time.Time) int64 {
|
|
|
|
|
+ utcTime := t.In(time.UTC)
|
|
|
|
|
+ ts := int64(utcTime.Unix()-timeBase)*10000000 + int64(utcTime.Nanosecond()/100)
|
|
|
|
|
+
|
|
|
|
|
+ return ts
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// TimeUUID generates a new time based UUID (version 1) using the current
|
|
// TimeUUID generates a new time based UUID (version 1) using the current
|
|
|
// time as the timestamp.
|
|
// time as the timestamp.
|
|
|
func TimeUUID() UUID {
|
|
func TimeUUID() UUID {
|
|
|
return UUIDFromTime(time.Now())
|
|
return UUIDFromTime(time.Now())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// The min and max clock values for a UUID.
|
|
|
|
|
+//
|
|
|
|
|
+// Cassandra's TimeUUIDType compares the lsb parts as signed byte arrays.
|
|
|
|
|
+// Thus, the min value for each byte is -128 and the max is +127.
|
|
|
|
|
+const (
|
|
|
|
|
+ minClock = 0x8080
|
|
|
|
|
+ maxClock = 0x7f7f
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// The min and max node values for a UUID.
|
|
|
|
|
+//
|
|
|
|
|
+// See explanation about Cassandra's TimeUUIDType comparison logic above.
|
|
|
|
|
+var (
|
|
|
|
|
+ minNode = []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80}
|
|
|
|
|
+ maxNode = []byte{0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f}
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// MinTimeUUID generates a "fake" time based UUID (version 1) which will be
|
|
|
|
|
+// the smallest possible UUID generated for the provided timestamp.
|
|
|
|
|
+//
|
|
|
|
|
+// UUIDs generated by this function are not unique and are mostly suitable only
|
|
|
|
|
+// in queries to select a time range of a Cassandra's TimeUUID column.
|
|
|
|
|
+func MinTimeUUID(t time.Time) UUID {
|
|
|
|
|
+ return TimeUUIDWith(getTimestamp(t), minClock, minNode)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// MaxTimeUUID generates a "fake" time based UUID (version 1) which will be
|
|
|
|
|
+// the biggest possible UUID generated for the provided timestamp.
|
|
|
|
|
+//
|
|
|
|
|
+// UUIDs generated by this function are not unique and are mostly suitable only
|
|
|
|
|
+// in queries to select a time range of a Cassandra's TimeUUID column.
|
|
|
|
|
+func MaxTimeUUID(t time.Time) UUID {
|
|
|
|
|
+ return TimeUUIDWith(getTimestamp(t), maxClock, maxNode)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// UUIDFromTime generates a new time based UUID (version 1) as described in
|
|
// UUIDFromTime generates a new time based UUID (version 1) as described in
|
|
|
// RFC 4122. This UUID contains the MAC address of the node that generated
|
|
// RFC 4122. This UUID contains the MAC address of the node that generated
|
|
|
// the UUID, the given timestamp and a sequence number.
|
|
// the UUID, the given timestamp and a sequence number.
|
|
|
-func UUIDFromTime(aTime time.Time) UUID {
|
|
|
|
|
- utcTime := aTime.In(time.UTC)
|
|
|
|
|
- t := int64(utcTime.Unix()-timeBase)*10000000 + int64(utcTime.Nanosecond()/100)
|
|
|
|
|
|
|
+func UUIDFromTime(t time.Time) UUID {
|
|
|
|
|
+ ts := getTimestamp(t)
|
|
|
clock := atomic.AddUint32(&clockSeq, 1)
|
|
clock := atomic.AddUint32(&clockSeq, 1)
|
|
|
|
|
|
|
|
- return TimeUUIDWith(t, clock, hardwareAddr)
|
|
|
|
|
|
|
+ return TimeUUIDWith(ts, clock, hardwareAddr)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// TimeUUIDWith generates a new time based UUID (version 1) as described in
|
|
// TimeUUIDWith generates a new time based UUID (version 1) as described in
|