前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >facebook-雪花算法-分布式ID-C++实现

facebook-雪花算法-分布式ID-C++实现

作者头像
lexingsen
发布2022-02-25 09:08:53
1.1K0
发布2022-02-25 09:08:53
举报
文章被收录于专栏:乐行僧的博客乐行僧的博客
代码语言:javascript
复制
#include <stdint.h>
#include <sys/time.h>
#include <stdexcept>
#include <mutex>
#include <thread>
#include "lightlog.h"

class SnowFlake {
private:
	static const uint64_t m_start_time_stamp = 1480166465631; // 初始时间戳 给一个随机值
	static const uint64_t m_sequence_bit = 12;
	static const uint64_t m_machine_bit = 5;
	static const uint64_t m_datacenter_bit = 5;
	
	// 获取位数的最大值
	static const uint64_t m_max_datacenter_num = -1 ^ (uint64_t(-1) << m_datacenter_bit);
	static const uint64_t m_max_machine_num = -1 ^ (uint64_t(-1) << m_machine_bit);
	static const uint64_t m_max_sequence_num = -1 ^ (uint64_t(-1) << m_sequence_bit);
	
	// 下标
	static const uint64_t m_machine_left = m_sequence_bit;
	static const uint64_t m_datacenter_left = m_sequence_bit + m_machine_bit;
	static const uint64_t m_timestamp_left = m_sequence_bit + m_machine_bit + m_datacenter_bit;
	
	
	uint64_t m_datacenterId;
	uint64_t m_machineId;
	uint64_t m_sequence;
	uint64_t m_last_time_stamp;
	
	std::mutex m_mtx;
	
	uint64_t GetNextMill() {
		uint64_t mill = GetNewTimeStamp();
		while (mill <= m_last_time_stamp) {
			mill = GetNewTimeStamp();
		}
		return mill;
	}
	
	uint64_t GetNewTimeStamp() {
		struct timeval tv;
		gettimeofday(&tv, NULL);
		uint64_t time = tv.tv_sec;
		time /= 1000;
		time += (tv.tv_sec * 1000);
		return time;	
	}
public:
	SnowFlake(int datacenterId, int machineId)
	{
		// 参数校验
		if ((uint64_t)datacenterId > m_max_datacenter_num || (uint64_t)datacenterId < 0) {
			LLOG(ERRO) << "datacenterId can't be greater than max_datacenter_num_ or less than 0";
			exit(0);
		}
		
		if ((uint64_t)machineId > m_max_machine_num || (uint64_t)machineId < 0) {
			LLOG(ERRO) << "machineId can't be greater than max_machine_num_or less than 0";
			exit(0);
		}
		m_datacenterId = datacenterId;
		m_machineId = machineId;
		m_sequence = 0L;
		m_last_time_stamp = 0L;
	}
	
	
	uint64_t NextId() {
		std::unique_lock<std::mutex> lock(m_mtx);
		uint64_t curTimeStamp = GetNewTimeStamp();
		if (curTimeStamp < m_last_time_stamp) {
			LLOG(ERRO) << "clock moved backwards. refusing to generate id";
			exit(0);
		}
		
		if (curTimeStamp == m_last_time_stamp) {
			m_sequence = (m_sequence + 1) & m_max_sequence_num;
			if (m_sequence == 0) {
				curTimeStamp = GetNextMill();
			}
		} else {
			m_sequence = 0;
		}
		
		m_last_time_stamp = curTimeStamp;
		return (curTimeStamp - m_start_time_stamp) << m_timestamp_left
			| m_datacenterId << m_datacenter_left
			| m_machineId << m_machine_left
			| m_sequence;
	}
};


void func(void* arg) {
	SnowFlake* sf = (SnowFlake*)arg;
	for (int i = 0; i < 10; i++) {
		LLOG(INFO) << sf->NextId();
	}
	return;
}


int main() {
	SnowFlake sf(2, 3);
	std::thread t1(func, &sf);
	t1.join();
	return 0;
}

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1jaldbd5jadaj

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档