1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- package util
- import (
- "errors"
- "sync"
- "time"
- )
- const (
- // MaxSequence max sequence in one time
- MaxSequence = 1000
- // WorkerBit worker bit
- WorkerBit = 10
- // SequenceBit sequence bit
- SequenceBit = 10
- )
- // SnowFlake snow flake
- type SnowFlake struct {
- sync.Mutex
- lastTimestamp int64
- sequence int64
- workerID int64
- }
- // NewSnowFlake new
- func NewSnowFlake() *SnowFlake {
- return &SnowFlake{
- workerID: time.Now().UnixNano() % 1000,
- }
- }
- // Generate generate
- func (s *SnowFlake) Generate() (int64, error) {
- s.Lock()
- defer s.Unlock()
- now := time.Now().UnixNano() / 1e6
- if now == s.lastTimestamp {
- s.sequence = (s.sequence + 1) % MaxSequence
- if s.sequence == 0 {
- now = s.waitNextMill(now)
- }
- } else {
- s.sequence = 0
- }
- if now < s.lastTimestamp {
- return 0, errors.New("inner time error")
- }
- s.lastTimestamp = now
- return s.generate() % 1000000000, nil
- }
- func (s *SnowFlake) generate() int64 {
- return (s.lastTimestamp << (WorkerBit + SequenceBit)) | (s.workerID << SequenceBit) | s.sequence
- }
- func (s *SnowFlake) waitNextMill(t int64) int64 {
- for t == s.lastTimestamp {
- time.Sleep(100 * time.Microsecond)
- t = time.Now().UnixNano() / 1e6
- }
- return t
- }
|