Files
2021-09-28 11:47:19 +08:00

56 lines
1.0 KiB
Go

package utils
import (
"errors"
"sync"
"time"
)
const (
workerBits uint8 = 10
numberBits uint8 = 12
workerMax int64 = -1 ^ (-1 << workerBits)
numberMax int64 = -1 ^ (-1 << numberBits)
timeShift uint8 = workerBits + numberBits
workerShift uint8 = numberBits
startTime int64 = 1136185445000
)
type Worker struct {
mu sync.Mutex
timestamp int64
workerID int64
number int64
}
func (w *Worker) GetID() int64 {
w.mu.Lock()
defer w.mu.Unlock()
now := time.Now().UnixNano() / 1e6
if w.timestamp == now {
w.number++
if w.number > numberMax {
for now <= w.timestamp {
now = time.Now().UnixNano() / 1e6
}
}
} else {
w.number = 0
w.timestamp = now
}
return (now-startTime)<<timeShift | (w.workerID << workerShift) | (w.number)
}
func NewSnowflake(workerID int64) (*Worker, error) {
if workerID < 0 || workerID > workerMax {
return nil, errors.New("Worker ID Excess Of Quantity")
}
// 生成一个新节点
return &Worker{
timestamp: 0,
workerID: workerID,
number: 0,
}, nil
}