forked from bakanis/uuid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
timestamp.go
81 lines (68 loc) · 1.86 KB
/
timestamp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package uuid
/****************
* Date: 14/02/14
* Time: 7:46 PM
***************/
import (
"time"
)
const (
// A tick is 100 ns
ticksPerSecond = 10000000
// Difference between
gregorianToUNIXOffset uint64 = 0x01B21DD213814000
// set the following to the number of 100ns ticks of the actual
// resolution of your system's clock
idsPerTimestamp = 1024
)
var (
lastTimestamp Timestamp
idsThisTimestamp = idsPerTimestamp
)
// ********************************************** Timestamp
type Timestamp uint64
// TODO Create c version same as package runtime and time
func Now() (sec int64, nsec int32) {
t := time.Now()
sec = t.Unix()
nsec = int32(t.Nanosecond())
return
}
// Converts Unix formatted time to RFC4122 UUID formatted times
// UUID UTC base time is October 15, 1582.
// Unix base time is January 1, 1970.
// Converts time to 100 nanosecond ticks since epoch
// There are 1000000000 nanoseconds in a second,
// 1000000000 / 100 = 10000000 tiks per second
func timestamp() Timestamp {
sec, nsec := Now()
return Timestamp(uint64(sec)*ticksPerSecond +
uint64(nsec)/100 + gregorianToUNIXOffset)
}
func (o Timestamp) Unix() time.Time {
t := uint64(o) - gregorianToUNIXOffset
return time.Unix(0, int64(t*100))
}
// Get time as 60-bit 100ns ticks since UUID epoch.
// Compensate for the fact that real clock resolution is
// less than 100ns.
func currentUUIDTimestamp() Timestamp {
var timeNow Timestamp
for {
timeNow = timestamp()
// if clock reading changed since last UUID generated
if lastTimestamp != timeNow {
// reset count of UUIDs with this timestamp
idsThisTimestamp = 0
lastTimestamp = timeNow
break
}
if idsThisTimestamp < idsPerTimestamp {
idsThisTimestamp++
break
}
// going too fast for the clock; spin
}
// add the count of UUIDs to low order bits of the clock reading
return timeNow + Timestamp(idsThisTimestamp)
}