snowflake.go 1.1 KB

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