c++实现的唯一ID生成器

设计背景

用作游戏服务器给每个角色生成UID,给物品生成唯一ID,有多个服务器类型,例如:游戏服,中心服,网关服等等;每个类型的服务器有多个,比如10个游戏服,20个网关服等

设计思想 

1. 思路参考雪花算法,即多个字段拼接成一个64位的数字

2. 最高位不用,4位服务器类型,7位服务器ID,32位时间戳,20位自增ID

3. 服务器类型占4位,所以有2的4次方,即16种不同的服务器类型

4. 服务器ID占7位,所以有2的7次方,即同一类型的服务器最多可以有128个

5. 时间戳占32位,精确到秒

6. 自增ID占20位,即2的20次方,每秒最多产生1048576个唯一ID

备注

使用时可以根据实际情况修改各个字段的占位数

代码下载地址:

windows版: https://download.csdn.net/download/yzf279533105/11955287

运行结果如下图(实验时只产生了一次UID,并打印出来):

代码如下:

使用代码:

int main()
{
	// 使用前先初始化
	IDGenerate::getSingleton().Init(ST_GAME,1);

	// 使用
	uint64_t uid = IDGenerate::getSingleton().GenerateUID();
	cout<<uid<<endl;

	getchar();
	return 0;
}

头文件

* All rights reserved.
* 文件名称: IDGenerate.h
* 作    者: yzf
* 摘    要: UID生成器
* 目前规则:1位保留 + 4位服务器类型 + 7位服务器ID + 32位时间戳 + 20位自增ID
*		  每秒可以生产2的20次方,也就是1048576个UID
*         使用前需先初始化,否则返回0(也可以在GenerateUID()内部判断,若未初始化,则进行初始化,这样接口更少)
* 完成日期: 2019-11-3
********************************************************************/

#ifndef  __ID_GENERATE_H__
#define  __ID_GENERATE_H__

#include <stdio.h>
#include "define.h"
#include "singleton.h"

//////////////////////////////////////////////////////////////////////////

class IDGenerate : public Singleton<IDGenerate>
{
public:
	IDGenerate();
	virtual ~IDGenerate();
public:
    // 生成一个全局唯一的UID
    uint64_t	GenerateUID();

	/**
	@purpose  : 初始化
	@param	 serverType     : 服务器类型
	@param   serverID       : 服务器ID
	*/
	void		Init(SERVER_TYPE serverType, int serverID);
protected:
	bool			m_bInit;        // 是否已初始化
    SERVER_TYPE		m_serverType;   // 服务器类型
    int				m_serverID;     // 服务器ID,同一类型的服务器中需唯一
    int				m_lastSecond;   // 上次产生ID时的时间戳,单位:秒
    int				m_addID;        // 自增ID
};

源文件

#include <time.h>
#include "IDGenerate.h"

//////////////////////////////////////////////////////////////////////////
IDGenerate::IDGenerate()
{
	m_bInit = false;
	m_addID = 0;
}

//////////////////////////////////////////////////////////////////////////
IDGenerate::~IDGenerate()
{
}

// 生成一个全局唯一的UID
uint64_t IDGenerate::GenerateUID()
{
	if (!m_bInit)
	{
		printf("IDGenerate::GenerateUID(), m_bInit = false !!!!!");
		return 0;
	}

	// 当前时间
	unsigned int curSecond = time(NULL);

	// 若秒数不同了,则自增ID重新从0开始
	if(curSecond != m_lastSecond)
	{
		m_lastSecond = curSecond;
		m_addID = 0;
	}

	return ((uint64_t)m_serverType<<59) + ((uint64_t)m_serverID<<52) + ((uint64_t)curSecond<<20) + ((uint64_t)m_addID++);
}

/**
@purpose          : 初始化
@param	 serverType     : 服务器类型
@param   serverID       : 服务器ID
*/
void    IDGenerate::Init(SERVER_TYPE serverType, int serverID)
{
	m_serverType 	= serverType;
	m_serverID  	= serverID;
	m_bInit			= true;
}


SINGLETON_INIT(IDGenerate)
发布了105 篇原创文章 · 获赞 58 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/yzf279533105/article/details/102874327