#include <iostream> #include <chrono> #include <stdexcept> class Snowflake { private: // 雪花算法的各个参数 static constexpr int64_t workerIdBits = 5; static constexpr int64_t datacenterIdBits = 5; static constexpr int64_t sequenceBits = 12; static constexpr int64_t maxWorkerId = -1 ^ (-1 << workerIdBits); static constexpr int64_t maxDatacenterId = -1 ^ (-1 << datacenterIdBits); static constexpr int64_t sequenceMask = -1 ^ (-1 << sequenceBits); int64_t workerId; int64_t datacenterId; int64_t sequence = 0; int64_t lastTimestamp = -1; public: Snowflake(int64_t workerId, int64_t datacenterId) : workerId(workerId), datacenterId(datacenterId) {} int64_t generateId() { // 获取当前时间戳(毫秒级) auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch()).count(); if (timestamp < lastTimestamp) { throw std::runtime_error("Invalid system clock!"); } if (timestamp == lastTimestamp) { sequence = (sequence + 1) & sequenceMask; if (sequence == 0) { timestamp = waitNextMillis(lastTimestamp); } } else { sequence = 0; } lastTimestamp = timestamp; // 生成最终的唯一ID int64_t uniqueId = (timestamp << (workerIdBits + datacenterIdBits + sequenceBits)) | (datacenterId << (workerIdBits + sequenceBits)) | (workerId << sequenceBits) | sequence; return uniqueId; } private: int64_t waitNextMillis(int64_t lastTimestamp) { auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch()).count(); while (timestamp <= lastTimestamp) { timestamp = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch()).count(); } return timestamp; } }; int main() { Snowflake snowflake(1, 1); for (int i = 0; i < 10; i++) { int64_t uniqueId = snowflake.generateId(); std::cout << uniqueId << std::endl; } return 0; }
在上面的代码中,我们使用C++编写了一个名为Snowflake
的类,用于生成Snowflake算法的唯一ID。主要属性和方法如下:
Snowflake(int64_t workerId, int64_t datacenterId)
:构造函数,用于初始化Snowflake算法的参数,包括工作节点ID(workerId)和数据中心ID(datacenterId)。int64_t generateId()
:生成下一个唯一ID的方法。int64_t waitNextMillis(int64_t lastTimestamp)
:阻塞到下一个毫秒,直到获得新的时间戳。
在主函数main()
中,我们创建了一个Snowflake
实例,并使用其generateId()
方法生成了10个唯一ID,并将其打印到控制台上。