基于snowflake的序列号生成器

该博客介绍了如何使用C++实现基于Snowflake算法的分布式ID序列号生成器,包括构造函数、生成序列ID的方法,并提供了一个简单的静态方法用于快速生成ID。代码示例展示了如何设置数据中心ID和工作机器ID,以及如何利用时间戳、工作机器ID和序列号来确保全局唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、C++实现

snowflake.h

#pragma once
#include <stdint.h>

namespace algorithm
{
/**
 * @brief snowflake序列号生成器
 */
class Snowflake
{
public:
    /**
     * @brief 构造函数
     * @param datacenterId 数据中心ID(5位), 例如: 0~99999
     * @param workerId 工作机器ID(5位), 例如: 0~99999
     */
    Snowflake(uint64_t datacenterId = 0, uint64_t workerId = 0);

    /**
     * @brief 生成序列ID
     * @return 序列ID, 例如: 6814090057511600129
     */
    uint64_t generate(void);

    /**
     * @brief 生成序列ID(自动构造对象)
     * @return 序列ID, 例如: 6814090057511600129
     */
    static uint64_t easyGenerate();

private:
    uint64_t m_flag; /* 符号位(1位),为0,通常不用 */
    uint64_t m_timestamp; /* 时间戳(41位),精确到毫秒,支持2^41/365/24/60/60/1000=69.7年 */
    /* 整个分布式系统内不会产生ID碰撞(由datacenterId和workerId作区分),支持1024个进程 */
    uint64_t m_datacenterId; /* 数据中心ID(5位) */
    uint64_t m_workerId; /* 工作机器ID(5位) */
    uint64_t m_sequence; /* 序列号(12位),每毫秒从0开始自增,支持4096个编号 */
};
} // namespace algorithm

snowflake.cpp

#include "snowflake.h"

#include <atomic>
#include <chrono>
#include <random>

namespace algorithm
{
Snowflake::Snowflake(uint64_t datacenterId, uint64_t workerId)
    : m_flag(0), m_datacenterId(datacenterId), m_workerId(workerId), m_sequence(0)
{
    auto ntp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
    m_timestamp = (ntp.time_since_epoch().count() & 0x1FFFFFFFFFF);
}

uint64_t Snowflake::generate(void)
{
    auto ntp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
    uint64_t newTime = (ntp.time_since_epoch().count() & 0x1FFFFFFFFFF);
    if (newTime == m_timestamp)
    {
        ++m_sequence;
    }
    else
    {
        m_sequence = 0;
        m_timestamp = newTime;
    }
    return (m_timestamp << 22) + ((m_datacenterId & 0x1F) << 17) + ((m_workerId & 0x1F) << 12) + (m_sequence & 0xFFF);
}

uint64_t Snowflake::easyGenerate(void)
{
    static std::uniform_int_distribution<std::mt19937::result_type> s_dist(1, 99999);
    static std::mt19937 s_rng;
    s_rng.seed(std::random_device()());
    static Snowflake s_sf(s_dist(s_rng), s_dist(s_rng));
    static std::atomic_flag s_glock = ATOMIC_FLAG_INIT;
    uint64_t req = 0;
    while (s_glock.test_and_set()) /* 等待原子锁 */
        ;
    req = s_sf.generate();
    s_glock.clear();
    return req;
}
} // namespace algorithm

二、链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值