Skip to content

Instantly share code, notes, and snippets.

@thesyncim
Last active June 9, 2019 07:34
Show Gist options
  • Save thesyncim/a46fcf4872c029b0a55c577717702992 to your computer and use it in GitHub Desktop.
Save thesyncim/a46fcf4872c029b0a55c577717702992 to your computer and use it in GitHub Desktop.
package main
import (
"time"
)
type ReadState uint64
func (rs *ReadState) UnreadCounts() uint8 {
return uint8(*rs >> 56)
}
func (rs *ReadState) SetCount(count uint8) {
sec, ns := timestamp(*rs)
*rs = pack(sec, ns, count)
}
func (rs *ReadState) SetLastRead(lastRead time.Time) {
sec, us := toUnixSecondsAndMicroseconds(lastRead)
*rs = pack(sec, us, rs.UnreadCounts())
}
func (rs *ReadState) LastRead() time.Time {
sec, us := timestamp(*rs)
return time.Unix(int64(sec), int64(us*1000))
}
func timestamp(rs ReadState) (sec uint32, us uint32) {
sec = uint32(rs & 0xFFFFFFFF) //low
us = uint32(rs >> 32) //high
//clear (counter) last 8 bit
us &^= 1 << 31
us &^= 1 << 30
us &^= 1 << 29
us &^= 1 << 28
us &^= 1 << 27
us &^= 1 << 26
us &^= 1 << 25
us &^= 1 << 24
return sec, us
}
func NewReadStateUint(count uint8, lastRead time.Time) ReadState {
seconds, microseconds := toUnixSecondsAndMicroseconds(lastRead)
return pack(seconds, microseconds, count)
}
func toUnixSecondsAndMicroseconds(lastRead time.Time) (uint32, uint32) {
microseconds := uint32((lastRead.Nanosecond()) / 1000)
seconds := uint32(lastRead.Unix())
return uint32(seconds), microseconds
}
func pack(seconds uint32, microseconds uint32, count uint8) ReadState {
return ReadState(
//unix seconds
uint64(seconds) | uint64(seconds>>8)<<8 | uint64(seconds>>16)<<16 | uint64(seconds<<24)<<24 |
//microseconds
uint64(microseconds)<<32 | uint64(microseconds>>8)<<40 | uint64(microseconds>>16)<<48 |
//counter
uint64(count)<<56,
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment