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) }