当前位置: 首页 > article >正文

游戏中的唯一id生成,防止合服id重复

故事背景,接手了一个烂代码,合服的时候大量id重复。你说改了id合服不就完事了吗,有那么简单吗。比如道具id重复,你把道具表的id改了,但是其他表用了道具id,其他表你也要改。如果其他表用的道具id不是单独一个字段,是一个复杂的数据呢,你怎么改。你无法通过数据库直接改。。我奇怪的是他用了长度19位,float都装不下这么长的数据,居然重复的。。。

贴源码

UINT64 TwitterSnowflake::GenerateUnique()
{
	UINT64 id = 0;
	UINT32 nowMsec = GetCurrentTimeMsec() / 1000; //修成秒

	id = (UINT64)nowMsec << 32;

	//中间m_machineIdBits位是机器ID
	id |= (UINT64)(m_machineId & (m_maxMachine - 1)) << m_sequenceBits/*15*/;

	//最后m_sequenceBits位序列号
	CXTAutoLock lock(m_locker);
	if (nowMsec < m_lastStamp)
	{
		id = 0;
		//ASSERT(false);
	}
	else if(m_lastStamp == nowMsec)
	{
		int m_sequence_old = m_sequence;
		m_sequence = ((m_sequence + 1) & (m_maxSequence - 1));
		
		if (m_sequence == 0)
		{
			printf("%d %d %d %d\n", nowMsec, m_lastStamp, m_sequence, m_sequence_old);
			nowMsec = WaitNextSec();
		}
	}
	else
	{
		m_sequence = 0;
	}

	id |= m_sequence;
	//TODO
	/*static std::map<INT64, INT32> record;
	static std::map<INT64, INT32> recordTime;
	auto it = record.find(id);
	if (it != record.end())
	{
		++it->second;
		printf("%d %d %d id =  %lld  重复次数  %d %d \n", nowMsec, m_lastStamp, recordTime[id], id, it->second, m_sequence);
	}
	else
	{
		record[id] = 1;
		recordTime[id] = nowMsec;
	}*/
	m_lastStamp = nowMsec;

	//printf("%d %d %d id =  %lld   %d \n", nowMsec, m_lastStamp, recordTime[id], id, m_sequence);
	return id;
}

生成出来大概是这样的  7293710237208084482,这么TM的大,lua的float都装不下.难受的是不同服生成出来的id,肉眼可见的回重复。

我改成了服务器id拼时间,然后自增。

void TwitterSnowflake::SetMachineId(int id)
{
	m_machineId = id;	
	m_id = m_machineId * 10000000000 + time(NULL);
}
UINT64 TwitterSnowflake::GenerateUnique()
{
	return m_id++;
}

比如1011服,生成的id 101111726036456

1011是服务器id,1是进程id,后面是时间。服务器id4位,进程id 1位,时间10位,一共长度15位。


http://www.kler.cn/a/308596.html

相关文章:

  • 机器学习在医疗健康领域的应用
  • Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
  • java八股-jvm入门-程序计数器,堆,元空间,虚拟机栈,本地方法栈,类加载器,双亲委派,类加载执行过程
  • 标准C++ 字符串
  • @ComponentScan:Spring Boot中的自动装配大师
  • WebGIS三维地图框架--Cesium
  • 成功激活mac idea 记录
  • Java封装(面向对象)
  • 104.WEB渗透测试-信息收集-FOFA语法(4)
  • 腾讯百度阿里华为常见算法面试题TOP100(4):双指针、哈希、滑动窗口
  • [go] 命令模式
  • 电信创维光猫DT741超级密码
  • 【LeetCode】每日一题 2024_9_13 预算内的最多机器人数目(滑动窗口、单调队列)
  • 文件标识符fd
  • 嵌入式Linux学习笔记(5)-进程间常见通讯方式(c语言实现)
  • 09_Python流程控制_分支
  • win10怎么配置dnat规则,访问win10的网口A ip的6443端口,映射到1.1.1.1的6443端口去
  • Android 源码集成可卸载 APP
  • go多线程
  • python-在PyCharm中使用PyQt5
  • 【C++】多态详解
  • mysql学习教程,从入门到精通,SQL IN BETWEEN 运算符(13)
  • 基于STM32F407ZGT6——看门狗
  • new/delete和malloc/free到底有什么区别
  • docker镜像结构
  • 代码随想录:动态规划4-5