CUniqueId.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "CUniqueId.h"
  2. #if defined(__GUNC__)
  3. #include <sys/time.h>
  4. #include <unistd.h>
  5. #define EPOCHFILETIME 11644473600000000ULL
  6. #else
  7. #include <Windows.h>
  8. #include <time.h>
  9. #define EPOCHFILETIME 11644473600000000Ui64
  10. #endif
  11. unsigned long long CUniqueId::_lasttimestamp = 0;
  12. unsigned long long get_time()
  13. {
  14. #ifdef __GUNC__
  15. struct timeval tv;
  16. gettimeofday(&tv, NULL);
  17. uint64 time = tv.tv_usec;
  18. time /= 1000;
  19. time += ((uint64_t)tv.tv_sec * 1000);
  20. return time;
  21. #else
  22. FILETIME filetime;
  23. uint64_t time = 0;
  24. GetSystemTimeAsFileTime(&filetime);
  25. time |= filetime.dwHighDateTime;
  26. time <<= 32;
  27. time |= filetime.dwLowDateTime;
  28. time /= 10;
  29. time -= EPOCHFILETIME;
  30. return time / 1000;
  31. #endif
  32. }
  33. CUniqueId::CUniqueId() :_workerId(0), _datacenterId(0), _sequence(0)
  34. {
  35. }
  36. CUniqueId::~CUniqueId()
  37. {
  38. }
  39. unsigned long long CUniqueId::next_timestamp()
  40. {
  41. __time64_t timestamp = get_time();
  42. while (timestamp <= _lasttimestamp)
  43. {
  44. timestamp = get_time();
  45. }
  46. return timestamp;
  47. }
  48. void CUniqueId::setWorkerId(const unsigned char &workerId)
  49. {
  50. _workerId = workerId;
  51. }
  52. void CUniqueId::setDatacenterId(const unsigned char & datacenterId)
  53. {
  54. _datacenterId = datacenterId;
  55. }
  56. unsigned long long CUniqueId::get_unique_id()
  57. {
  58. #ifndef USE_C0X
  59. std::unique_lock <std::mutex> lock{ _mutex };
  60. __time64_t timestamp = 0;
  61. #else
  62. // 获取当前日历时间(1900-01-01开始的Unix时间戳);
  63. static std::atomic<__time64_t> timestamp = 0;
  64. #endif
  65. timestamp = get_time();
  66. if (timestamp < _lasttimestamp)
  67. return -1;
  68. if (timestamp == _lasttimestamp)
  69. {// 相同时间戳下,序列值自增(最大4095);
  70. _sequence = (++_sequence) & _sequenceMask;
  71. if (_sequence == 0)
  72. {// 该时间戳内已用完,;
  73. timestamp = next_timestamp();
  74. }
  75. }
  76. else
  77. {// 不同时间戳下,重置序列值;
  78. _sequence = 0;
  79. }
  80. _lasttimestamp = timestamp;
  81. return ((timestamp - _twepoch) << _timestampleftShift) | (_datacenterId << _datacenterIdShift) | (_workerId << _workerIdBits) | _sequence;
  82. }