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