Browse Source

增加雪花算法实现方法

master v0.8.0
guzeng 1 year ago
parent
commit
814bdf7d29
2 changed files with 78 additions and 0 deletions
  1. +62
    -0
      snowflake.go
  2. +16
    -0
      snowflake_test.go

+ 62
- 0
snowflake.go View File

@ -0,0 +1,62 @@
package helper
import (
"sync"
"time"
)
// Snowflake 结构体
type Snowflake struct {
mu sync.Mutex
startTime int64 // 起始时间戳,可以根据实际需求设置
machineID int64 // 机器ID
sequenceNum int64 // 序列号
}
// NewSnowflake 创建一个Snowflake实例
func NewSnowflake(machineID int64) *Snowflake {
return &Snowflake{
startTime: getTimeStamp(),
machineID: machineID,
sequenceNum: 0,
}
}
// Generate 生成一个唯一ID
func (s *Snowflake) Generate() int64 {
s.mu.Lock()
defer s.mu.Unlock()
currentTime := getTimeStamp()
// 如果当前时间小于上一次生成ID的时间,说明时钟回拨,需要等待
if currentTime < s.startTime {
time.Sleep(time.Duration(s.startTime - currentTime))
currentTime = getTimeStamp()
}
// 如果是同一毫秒内生成的ID,需要增加序列号
if currentTime == s.startTime {
s.sequenceNum++
} else {
s.sequenceNum = 0
s.startTime = currentTime
}
// 如果序列号超过了12位的最大值,等待下一毫秒再生成ID
if s.sequenceNum >= 1<<12 {
time.Sleep(time.Millisecond)
s.startTime = getTimeStamp()
s.sequenceNum = 0
}
// 生成ID
id := (currentTime-s.startTime)<<22 | (s.machineID << 12) | s.sequenceNum
return id
}
// 获取当前时间戳(毫秒级)
func getTimeStamp() int64 {
return time.Now().UnixNano() / int64(time.Millisecond)
}

+ 16
- 0
snowflake_test.go View File

@ -0,0 +1,16 @@
package helper
import (
"testing"
)
func Test_snowflake(t *testing.T) {
// 创建一个Snowflake实例
snowflake := NewSnowflake(169379266710)
// 生成10个唯一ID并输出
for i := 0; i < 10; i++ {
id := snowflake.Generate()
t.Log(id)
}
}

Loading…
Cancel
Save