mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-16 05:40:49 +08:00
86 lines
1.7 KiB
Go
86 lines
1.7 KiB
Go
package idgenerator
|
|
|
|
import (
|
|
"hash/fnv"
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
workerIdBits int64 = 5
|
|
datacenterIdBits int64 = 5
|
|
sequenceBits int64 = 12
|
|
|
|
maxWorkerId int64 = -1 ^ (-1 << uint64(workerIdBits))
|
|
maxDatacenterId int64 = -1 ^ (-1 << uint64(datacenterIdBits))
|
|
maxSequence int64 = -1 ^ (-1 << uint64(sequenceBits))
|
|
|
|
timeLeft uint8 = 22
|
|
dataLeft uint8 = 17
|
|
workLeft uint8 = 12
|
|
|
|
twepoch int64 = 1525705533000
|
|
)
|
|
|
|
type IdGenerator struct {
|
|
mu *sync.Mutex
|
|
lastStamp int64
|
|
workerId int64
|
|
dataCenterId int64
|
|
sequence int64
|
|
}
|
|
|
|
func MakeGenerator(cluster string, node string) *IdGenerator {
|
|
fnv64 := fnv.New64()
|
|
_, _ = fnv64.Write([]byte(cluster))
|
|
dataCenterId := int64(fnv64.Sum64())
|
|
|
|
fnv64.Reset()
|
|
_, _ = fnv64.Write([]byte(node))
|
|
workerId := int64(fnv64.Sum64())
|
|
|
|
return &IdGenerator{
|
|
mu: &sync.Mutex{},
|
|
lastStamp: -1,
|
|
dataCenterId: dataCenterId,
|
|
workerId: workerId,
|
|
sequence: 1,
|
|
}
|
|
}
|
|
|
|
func (w *IdGenerator) getCurrentTime() int64 {
|
|
return time.Now().UnixNano() / 1e6
|
|
}
|
|
|
|
func (w *IdGenerator) NextId() int64 {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
|
|
timestamp := w.getCurrentTime()
|
|
if timestamp < w.lastStamp {
|
|
log.Fatal("can not generate id")
|
|
}
|
|
if w.lastStamp == timestamp {
|
|
w.sequence = (w.sequence + 1) & maxSequence
|
|
if w.sequence == 0 {
|
|
for timestamp <= w.lastStamp {
|
|
timestamp = w.getCurrentTime()
|
|
}
|
|
}
|
|
} else {
|
|
w.sequence = 0
|
|
}
|
|
w.lastStamp = timestamp
|
|
|
|
return ((timestamp - twepoch) << timeLeft) | (w.dataCenterId << dataLeft) | (w.workerId << workLeft) | w.sequence
|
|
}
|
|
|
|
func (w *IdGenerator) tilNextMillis() int64 {
|
|
timestamp := w.getCurrentTime()
|
|
if timestamp <= w.lastStamp {
|
|
timestamp = w.getCurrentTime()
|
|
}
|
|
return timestamp
|
|
}
|