63 lines
1.1 KiB
Go
63 lines
1.1 KiB
Go
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)
|
|
// 每次 from 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)
|
|
}
|