go-gun/gun/state.go

51 lines
1.1 KiB
Go
Raw Normal View History

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
}
}