2019-02-20 20:54:46 +00:00
|
|
|
package gun
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync/atomic"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2019-02-25 05:14:26 +00:00
|
|
|
type State uint64
|
|
|
|
|
|
|
|
func StateNow() State { return State(timeNowUnixMs()) }
|
|
|
|
|
|
|
|
// timeFromUnixMs returns zero'd time if ms is 0
|
|
|
|
func timeFromUnixMs(ms int64) time.Time {
|
2019-02-20 20:54:46 +00:00
|
|
|
if ms == 0 {
|
|
|
|
return time.Time{}
|
|
|
|
}
|
|
|
|
return time.Unix(0, ms*int64(time.Millisecond))
|
|
|
|
}
|
|
|
|
|
2019-02-25 05:14:26 +00:00
|
|
|
// timeToUnixMs returns 0 if t.IsZero
|
|
|
|
func timeToUnixMs(t time.Time) int64 {
|
2019-02-20 20:54:46 +00:00
|
|
|
if t.IsZero() {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return t.UnixNano() / int64(time.Millisecond)
|
|
|
|
}
|
|
|
|
|
2019-02-25 05:14:26 +00:00
|
|
|
func timeNowUnixMs() int64 {
|
|
|
|
return timeToUnixMs(time.Now())
|
2019-02-20 20:54:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var lastNano int64
|
|
|
|
|
|
|
|
// uniqueNano is 0 if ms is first time seen, otherwise a unique num in combination with ms
|
2019-02-25 05:14:26 +00:00
|
|
|
func timeNowUniqueUnix() (ms int64, uniqueNum int64) {
|
2019-02-20 20:54:46 +00:00
|
|
|
now := time.Now()
|
|
|
|
newNano := now.UnixNano()
|
|
|
|
for {
|
|
|
|
prevLastNano := lastNano
|
|
|
|
if prevLastNano < newNano && atomic.CompareAndSwapInt64(&lastNano, prevLastNano, newNano) {
|
|
|
|
ms = newNano / int64(time.Millisecond)
|
|
|
|
// If was same ms as seen before, set uniqueNum to the nano part
|
|
|
|
if prevLastNano/int64(time.Millisecond) == ms {
|
|
|
|
uniqueNum = newNano%int64(time.Millisecond) + 1
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
newNano = prevLastNano + 1
|
|
|
|
}
|
|
|
|
}
|