redis/id.go

63 lines
1.1 KiB
Go
Raw Permalink Normal View History

package redis
import (
"fmt"
"sync"
"apigo.cc/go/id"
)
type IdMaker struct {
rd *Redis
secCurrent uint64
secIndexMax uint64
secIndexNext uint64
lock sync.Mutex
maker *id.IDMaker
}
func NewIdMaker(rd *Redis) *IdMaker {
im := &IdMaker{rd: rd}
im.maker = id.NewIDMaker(im.makeSecIndex)
return im
}
func (im *IdMaker) makeSecIndex(sec uint64) uint64 {
im.lock.Lock()
defer im.lock.Unlock()
if im.secCurrent == sec && im.secIndexNext <= im.secIndexMax {
idx := im.secIndexNext
im.secIndexNext++
return idx
}
im.secCurrent = sec
key := fmt.Sprintf("_SecIdx_%d", sec)
// 每次从 Redis 预取 100 个序列号
max := uint64(im.rd.INCRBY(key, 100))
if max < 100 {
return 0
}
im.secIndexMax = max
im.secIndexNext = max - 99
idx := im.secIndexNext
im.secIndexNext++
if max <= 100 {
im.rd.EXPIRE(key, 10)
}
return idx
}
func (im *IdMaker) Get(size int) string {
return im.maker.Get(size)
}
func (im *IdMaker) GetForMysql(size int) string {
return im.maker.GetForMysql(size)
}
func (im *IdMaker) GetForPostgreSQL(size int) string {
return im.maker.GetForPostgreSQL(size)
}