Use monotonic clock if available from the package runtime
This commit is contained in:
parent
68117e6bbe
commit
564a60a44c
22
snowflake.go
22
snowflake.go
@ -14,7 +14,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
// Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC
|
// Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC
|
||||||
// You may customize this to set a different epoch for your application.
|
// You may customize this to set a different epoch for your application.
|
||||||
Epoch int64 = 1288834974657
|
Epoch = time.Date(2010, time.November, 4, 1, 42, 54, 0, time.UTC)
|
||||||
|
|
||||||
// Number of bits to use for Node
|
// Number of bits to use for Node
|
||||||
// Remember, you have a total 22 bits to share between Node/Step
|
// Remember, you have a total 22 bits to share between Node/Step
|
||||||
@ -76,7 +76,7 @@ var ErrInvalidBase32 = errors.New("invalid base32")
|
|||||||
// node
|
// node
|
||||||
type Node struct {
|
type Node struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
time int64
|
time time.Time
|
||||||
node int64
|
node int64
|
||||||
step int64
|
step int64
|
||||||
}
|
}
|
||||||
@ -95,13 +95,13 @@ func NewNode(node int64) (*Node, error) {
|
|||||||
stepMask = -1 ^ (-1 << StepBits)
|
stepMask = -1 ^ (-1 << StepBits)
|
||||||
timeShift = NodeBits + StepBits
|
timeShift = NodeBits + StepBits
|
||||||
nodeShift = StepBits
|
nodeShift = StepBits
|
||||||
|
|
||||||
if node < 0 || node > nodeMax {
|
if node < 0 || node > nodeMax {
|
||||||
return nil, errors.New("Node number must be between 0 and " + strconv.FormatInt(nodeMax, 10))
|
return nil, errors.New("Node number must be between 0 and " + strconv.FormatInt(nodeMax, 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Node{
|
return &Node{
|
||||||
time: 0,
|
// time: 0,
|
||||||
node: node,
|
node: node,
|
||||||
step: 0,
|
step: 0,
|
||||||
}, nil
|
}, nil
|
||||||
@ -112,14 +112,14 @@ func (n *Node) Generate() ID {
|
|||||||
|
|
||||||
n.mu.Lock()
|
n.mu.Lock()
|
||||||
|
|
||||||
now := time.Now().UnixNano() / 1000000
|
now := time.Now()
|
||||||
|
|
||||||
if n.time == now {
|
if now.Sub(n.time) < time.Millisecond {
|
||||||
n.step = (n.step + 1) & stepMask
|
n.step = (n.step + 1) & stepMask
|
||||||
|
|
||||||
if n.step == 0 {
|
if n.step == 0 {
|
||||||
for now <= n.time {
|
for now.Sub(n.time) < time.Millisecond {
|
||||||
now = time.Now().UnixNano() / 1000000
|
now = time.Now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -128,7 +128,7 @@ func (n *Node) Generate() ID {
|
|||||||
|
|
||||||
n.time = now
|
n.time = now
|
||||||
|
|
||||||
r := ID((now-Epoch)<<timeShift |
|
r := ID((now.Sub(Epoch).Nanoseconds()/1000000)<<timeShift |
|
||||||
(n.node << nodeShift) |
|
(n.node << nodeShift) |
|
||||||
(n.step),
|
(n.step),
|
||||||
)
|
)
|
||||||
@ -252,9 +252,9 @@ func (f ID) IntBytes() [8]byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time returns an int64 unix timestamp of the snowflake ID time
|
// Time returns an int64 unix timestamp in miliseconds of the snowflake ID time
|
||||||
func (f ID) Time() int64 {
|
func (f ID) Time() int64 {
|
||||||
return (int64(f) >> timeShift) + Epoch
|
return (int64(f) >> timeShift) + (Epoch.UnixNano() / 1000000)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node returns an int64 of the snowflake ID node number
|
// Node returns an int64 of the snowflake ID node number
|
||||||
|
Loading…
x
Reference in New Issue
Block a user