常用类型及数据操作方法
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.4 KiB

  1. package helper
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. // Snowflake 结构体
  7. type Snowflake struct {
  8. mu sync.Mutex
  9. startTime int64 // 起始时间戳,可以根据实际需求设置
  10. machineID int64 // 机器ID
  11. sequenceNum int64 // 序列号
  12. }
  13. // NewSnowflake 创建一个Snowflake实例
  14. func NewSnowflake(machineID int64) *Snowflake {
  15. return &Snowflake{
  16. startTime: getTimeStamp(),
  17. machineID: machineID,
  18. sequenceNum: 0,
  19. }
  20. }
  21. // Generate 生成一个唯一ID
  22. func (s *Snowflake) Generate() int64 {
  23. s.mu.Lock()
  24. defer s.mu.Unlock()
  25. currentTime := getTimeStamp()
  26. // 如果当前时间小于上一次生成ID的时间,说明时钟回拨,需要等待
  27. if currentTime < s.startTime {
  28. time.Sleep(time.Duration(s.startTime - currentTime))
  29. currentTime = getTimeStamp()
  30. }
  31. // 如果是同一毫秒内生成的ID,需要增加序列号
  32. if currentTime == s.startTime {
  33. s.sequenceNum++
  34. } else {
  35. s.sequenceNum = 0
  36. s.startTime = currentTime
  37. }
  38. // 如果序列号超过了12位的最大值,等待下一毫秒再生成ID
  39. if s.sequenceNum >= 1<<12 {
  40. time.Sleep(time.Millisecond)
  41. s.startTime = getTimeStamp()
  42. s.sequenceNum = 0
  43. }
  44. // 生成ID
  45. id := (currentTime-s.startTime)<<22 | (s.machineID << 12) | s.sequenceNum
  46. return id
  47. }
  48. // 获取当前时间戳(毫秒级)
  49. func getTimeStamp() int64 {
  50. return time.Now().UnixNano() / int64(time.Millisecond)
  51. }