|
@@ -0,0 +1,95 @@
|
|
|
+#include "CUniqueId.h"
|
|
|
+#if defined(__GUNC__)
|
|
|
+#include <sys/time.h>
|
|
|
+#include <unistd.h>
|
|
|
+#define EPOCHFILETIME 11644473600000000ULL
|
|
|
+#else
|
|
|
+#include <Windows.h>
|
|
|
+#include <time.h>
|
|
|
+#define EPOCHFILETIME 11644473600000000Ui64
|
|
|
+#endif
|
|
|
+unsigned long long CUniqueId::_lasttimestamp = 0;
|
|
|
+
|
|
|
+unsigned long long get_time()
|
|
|
+{
|
|
|
+#ifdef __GUNC__
|
|
|
+ struct timeval tv;
|
|
|
+ gettimeofday(&tv, NULL);
|
|
|
+ uint64 time = tv.tv_usec;
|
|
|
+ time /= 1000;
|
|
|
+ time += ((uint64_t)tv.tv_sec * 1000);
|
|
|
+ return time;
|
|
|
+#else
|
|
|
+ FILETIME filetime;
|
|
|
+ uint64_t time = 0;
|
|
|
+ GetSystemTimeAsFileTime(&filetime);
|
|
|
+
|
|
|
+ time |= filetime.dwHighDateTime;
|
|
|
+ time <<= 32;
|
|
|
+ time |= filetime.dwLowDateTime;
|
|
|
+
|
|
|
+ time /= 10;
|
|
|
+ time -= EPOCHFILETIME;
|
|
|
+ return time / 1000;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+CUniqueId::CUniqueId() :_workerId(0), _datacenterId(0), _sequence(0)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+CUniqueId::~CUniqueId()
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+unsigned long long CUniqueId::next_timestamp()
|
|
|
+{
|
|
|
+ __time64_t timestamp = get_time();
|
|
|
+ while (timestamp <= _lasttimestamp)
|
|
|
+ {
|
|
|
+ timestamp = get_time();
|
|
|
+ }
|
|
|
+ return timestamp;
|
|
|
+}
|
|
|
+
|
|
|
+void CUniqueId::setWorkerId(const unsigned char &workerId)
|
|
|
+{
|
|
|
+ _workerId = workerId;
|
|
|
+}
|
|
|
+
|
|
|
+void CUniqueId::setDatacenterId(const unsigned char & datacenterId)
|
|
|
+{
|
|
|
+ _datacenterId = datacenterId;
|
|
|
+}
|
|
|
+
|
|
|
+unsigned long long CUniqueId::get_unique_id()
|
|
|
+{
|
|
|
+#ifndef USE_C0X
|
|
|
+ std::unique_lock <std::mutex> lock{ _mutex };
|
|
|
+ __time64_t timestamp = 0;
|
|
|
+#else
|
|
|
+ // 获取当前日历时间(1900-01-01开始的Unix时间戳);
|
|
|
+ static std::atomic<__time64_t> timestamp = 0;
|
|
|
+#endif
|
|
|
+ timestamp = get_time();
|
|
|
+ if (timestamp < _lasttimestamp)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ if (timestamp == _lasttimestamp)
|
|
|
+ {// 相同时间戳下,序列值自增(最大4095);
|
|
|
+ _sequence = (++_sequence) & _sequenceMask;
|
|
|
+ if (_sequence == 0)
|
|
|
+ {// 该时间戳内已用完,;
|
|
|
+ timestamp = next_timestamp();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {// 不同时间戳下,重置序列值;
|
|
|
+ _sequence = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ _lasttimestamp = timestamp;
|
|
|
+
|
|
|
+ return ((timestamp - _twepoch) << _timestampleftShift) | (_datacenterId << _datacenterIdShift) | (_workerId << _workerIdBits) | _sequence;
|
|
|
+}
|