From b004e952c48b2bbed0799c28ef65c28e680086a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Fri, 14 Jul 2023 08:48:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(serial):=E5=AE=8C=E6=88=90=E5=86=B0?= =?UTF-8?q?=E9=9B=B9ID=E7=94=9F=E6=88=90=E7=AE=97=E6=B3=95=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=94=AF=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- serial_code/hail/errors.go | 7 ++++ serial_code/hail/hail.go | 73 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 serial_code/hail/errors.go create mode 100644 serial_code/hail/hail.go diff --git a/README.md b/README.md index fa5c9d0..f865c15 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Golang 中可以使用的常用辅助功能工具箱。主要配备以下功能 - [x] pHash 图像感知算法 - [ ] BlockHash 散列算法 - 唯一序列号生成器 - - [ ] 冰雹 ID 生成器(短主机精简日期版雪花 ID) + - [x] 冰雹 ID 生成器(短主机精简日期版雪花 ID) - [x] UUID 生成器 - [x] short UUID 生成器 - 验证码生成器 diff --git a/serial_code/hail/errors.go b/serial_code/hail/errors.go new file mode 100644 index 0000000..a804527 --- /dev/null +++ b/serial_code/hail/errors.go @@ -0,0 +1,7 @@ +package hail + +type HailAlgorithmNotInitializedError struct{} + +func (e *HailAlgorithmNotInitializedError) Error() string { + return "冰雹ID生成算法尚未初始化" +} diff --git a/serial_code/hail/hail.go b/serial_code/hail/hail.go new file mode 100644 index 0000000..7a6524d --- /dev/null +++ b/serial_code/hail/hail.go @@ -0,0 +1,73 @@ +// 提供基于雪花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()) +}