#include "CUniqueId.h" #if defined(__GUNC__) #include #include #define EPOCHFILETIME 11644473600000000ULL #else #include #include #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 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; }