易云轻量版服务端
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

3 年前
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // idgenerator
  2. package utils
  3. import (
  4. "errors"
  5. "sync"
  6. "time"
  7. )
  8. var currentNode *Worker
  9. const (
  10. workerBits uint8 = 10
  11. numberBits uint8 = 12
  12. workerMax int64 = -1 ^ (-1 << workerBits)
  13. numberMax int64 = -1 ^ (-1 << numberBits)
  14. timeShift uint8 = workerBits + numberBits
  15. workerShift uint8 = numberBits
  16. startTime int64 = 1525705533000 // 如果在程序跑了一段时间修改了epoch这个值 可能会导致生成相同的ID
  17. )
  18. type Worker struct {
  19. mu sync.Mutex
  20. timestamp int64
  21. workerId int64
  22. number int64
  23. }
  24. func NewWorker(workerId int64) (*Worker, error) {
  25. if workerId < 0 || workerId > workerMax {
  26. return nil, errors.New("Worker ID excess of quantity")
  27. }
  28. // 生成一个新节点
  29. return &Worker{
  30. timestamp: 0,
  31. workerId: workerId,
  32. number: 0,
  33. }, nil
  34. }
  35. func (w *Worker) GetId() int64 {
  36. w.mu.Lock()
  37. defer w.mu.Unlock()
  38. now := time.Now().UnixNano() / 1e6
  39. if w.timestamp == now {
  40. w.number++
  41. if w.number > numberMax {
  42. for now <= w.timestamp {
  43. now = time.Now().UnixNano() / 1e6
  44. }
  45. }
  46. } else {
  47. w.number = 0
  48. w.timestamp = now
  49. }
  50. ID := int64((now-startTime)<<timeShift | (w.workerId << workerShift) | (w.number))
  51. return ID
  52. }
  53. func InitWorker(workerId int64){
  54. // 生成节点实例
  55. node, err := NewWorker(workerId)
  56. if err != nil {
  57. panic(err)
  58. }
  59. currentNode = node
  60. }
  61. func GeneratorId() int64 {
  62. return currentNode.GetId()
  63. }