openreplay/backend/pkg/flakeid/flaker.go
2021-07-20 23:57:37 +08:00

47 lines
873 B
Go

package flakeid
import (
"errors"
"sync"
)
type Flaker struct {
shardID uint16
seqID uint8
seqMutex *sync.Mutex
}
func NewFlaker(shardID uint16) *Flaker {
return &Flaker{
shardID: shardID,
seqID: 0,
seqMutex: &sync.Mutex{},
}
}
func (flaker *Flaker) nextSeqID() uint8 {
flaker.seqMutex.Lock()
defer flaker.seqMutex.Unlock()
seqID := flaker.seqID
if seqID == SEQ_ID_MAX {
flaker.seqID = 0
} else {
flaker.seqID = seqID + 1
}
return seqID
}
func (flaker *Flaker) Compose(timestamp uint64) (uint64, error) {
if timestamp <= EPOCH {
return 0, errors.New("epoch is not in the past")
}
timestamp -= EPOCH
if timestamp > TIMESTAMP_MAX {
return 0, errors.New("epoch is too small")
}
return compose(timestamp, flaker.shardID, flaker.nextSeqID()), nil
}
func ExtractTimestamp(id uint64) uint64 {
return extractTimestamp(id) + EPOCH
}