// 提供基于雪花ID生成算法改进的短日期短主机板冰雹ID生成算法 package hail import ( "fmt" "sync" "time" "archgrid.xyz/ag/toolsbox/types" ) // 用于记录当前冰雹ID组成内容的数据结构 type HailAlgorithm struct { hostSerial int64 lastTimestamp int64 lastSequence int64 lock sync.Mutex } var hailAlgorithmInstance *HailAlgorithm // 获取当前已经完成初始化的冰雹ID生成算法实例,如果尚未完成初始化则会返回未初始化的错误。 func Get() (*HailAlgorithm, error) { if hailAlgorithmInstance == nil { return nil, &HailAlgorithmNotInitializedError{} } return hailAlgorithmInstance, nil } // 指定一个主机编号,并完成冰雹ID生成算法的初始化。 func Initialize(hostSerial int64) { hailAlgorithmInstance = &HailAlgorithm{ hostSerial: hostSerial, lastTimestamp: types.Timestamp(), lastSequence: 0, lock: sync.Mutex{}, } } // 返回一个可用的时间戳,如果主机发生了时间回拨,那么将等待一秒钟。 func (h *HailAlgorithm) timestamp() int64 { for { timestamp := types.Timestamp() if timestamp == h.lastTimestamp { h.lastTimestamp = timestamp return timestamp } else if timestamp > h.lastTimestamp { h.lastTimestamp = timestamp h.lastSequence = 0 return timestamp } time.Sleep(1 * time.Second) } } // 生成一个冰雹ID。 func (h *HailAlgorithm) Generate() int64 { h.lock.Lock() defer h.lock.Unlock() timestamp := h.timestamp() h.lastSequence++ return (timestamp << 20) | ((h.hostSerial & 0xffff) << 16) | (h.lastSequence & 0xffff_ffff) } // 生成一个冰雹ID,并将其转换为字符串。 func (h *HailAlgorithm) GenerateString() string { return fmt.Sprintf("%017d", h.Generate()) } // 生成一个冰雹ID,将其转换为字符串并附加指定的前缀 func (h *HailAlgorithm) GeneratePrefixedString(prefix string) string { return fmt.Sprintf("%s%s", prefix, h.GenerateString()) }