snow_flake.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package util
  2. import (
  3. "errors"
  4. "sync"
  5. "time"
  6. )
  7. const (
  8. // MaxSequence max sequence in one time
  9. MaxSequence = 1000
  10. // WorkerBit worker bit
  11. WorkerBit = 10
  12. // SequenceBit sequence bit
  13. SequenceBit = 10
  14. )
  15. // SnowFlake snow flake
  16. type SnowFlake struct {
  17. sync.Mutex
  18. lastTimestamp int64
  19. sequence int64
  20. workerID int64
  21. }
  22. // NewSnowFlake new
  23. func NewSnowFlake() *SnowFlake {
  24. return &SnowFlake{
  25. workerID: time.Now().UnixNano() % 1000,
  26. }
  27. }
  28. // Generate generate
  29. func (s *SnowFlake) Generate() (int64, error) {
  30. s.Lock()
  31. defer s.Unlock()
  32. now := time.Now().UnixNano() / 1e6
  33. if now == s.lastTimestamp {
  34. s.sequence = (s.sequence + 1) % MaxSequence
  35. if s.sequence == 0 {
  36. now = s.waitNextMill(now)
  37. }
  38. } else {
  39. s.sequence = 0
  40. }
  41. if now < s.lastTimestamp {
  42. return 0, errors.New("inner time error")
  43. }
  44. s.lastTimestamp = now
  45. return s.generate() % 1000000000, nil
  46. }
  47. func (s *SnowFlake) generate() int64 {
  48. return (s.lastTimestamp << (WorkerBit + SequenceBit)) | (s.workerID << SequenceBit) | s.sequence
  49. }
  50. func (s *SnowFlake) waitNextMill(t int64) int64 {
  51. for t == s.lastTimestamp {
  52. time.Sleep(100 * time.Microsecond)
  53. t = time.Now().UnixNano() / 1e6
  54. }
  55. return t
  56. }