第十一个工具类:ObjectMap
ObjectMap 是一个上篇提到的 objectid64 的一个id<->id映射关系表,由map实现
该类用于需求中时常会出现的 1对1 或者 1对多 映射关系,
比如:
1对1:一个网络链接对象 对应 一个玩家数据对象, 一个玩家数据对象 也对应一个 网络链接对象
1对多:一个玩家对象 对应 一个游戏公会对象
同时:
1、继承boost::noncopyable,禁止ObjectMap对象间拷贝赋值
2、ObjectMap加了锁,确保操作是线程安全了
3、实现了当一个线程在对ObjectMap进行迭代,其他线程在对ObjectMap进行添加/删除,确保迭代不失效
如何实现保证迭代不失效:
ObjectMap中保存了迭代时当前的迭代器std::map::iterator对象
当做删除操作时,先检查下要删除的这个对象是否就是当前正在遍历的那个对象
是的话,则保存的迭代器后移,再删除
提供的主要接口:
1、增加一个id<->id的映射关系:void AddObject(objectid64 key, objectid64 value);
2、查找一个id<->id映射关系(没找到返回NULL_ID):objectid64 FindObject(objectid64 key);
3、判断一个id<->id映射关系是否存在:bool IsExistsObject(objectid64 key);
4、删除一个id<->id映射关系:void FreeObject(objectid64 key);
5、获取id<->id映射关系的数量:unsigned int GetSize();
6、迭代:objectid64 BeginObject(); objectid64 NextObject();
上代码:
ObjectMap.h
#ifndef __ObjectMap_h__#define __ObjectMap_h__#include <boost/noncopyable.hpp>#include <map>#include "ToolDefine.h"namespace common{ namespace tool{ // 纯uint64的键值对池 // 主要用于id对id的索引 class ObjectMap : PRivate boost::noncopyable { public: ObjectMap(); ~ObjectMap(); // 使用一个空闲结点 void AddObject(objectid64 key, objectid64 value); // 随机一个结点(分配第一个结点,空列表返回空) objectid64 RandObject(); // 查找一个结点(没找到返回空) objectid64 FindObject(objectid64 key); bool IsExistsObject(objectid64 key); // 释放一个结点 void FreeObject(objectid64 key); // 获取对象个数 unsigned int GetSize(); // 迭代 objectid64 BeginObject(); objectid64 NextObject(); private: rw_mutex m_object_list_lock; typedef std::map<objectid64, objectid64> MapType; typedef std::map<objectid64, objectid64>::iterator MapTypeIterator; MapType m_object_list; MapTypeIterator m_object_it; }; }}#endifObjectMap.cpp#include "ObjectMap.h"namespace common{ namespace tool{ ObjectMap::ObjectMap() { write_lock lock(m_object_list_lock); m_object_list.clear(); m_object_it = m_object_list.begin(); } ObjectMap::~ObjectMap() { write_lock lock(m_object_list_lock); m_object_list.clear(); m_object_it = m_object_list.begin(); } void ObjectMap::AddObject(objectid64 key, objectid64 value) { write_lock lock(m_object_list_lock); m_object_list[key] = value; } objectid64 ObjectMap::RandObject() { read_lock lock(m_object_list_lock); MapTypeIterator it = m_object_list.begin(); if (it != m_object_list.end()) { return it->second; } else { return NULL_ID; } } objectid64 ObjectMap::FindObject(objectid64 key) { read_lock lock(m_object_list_lock); MapTypeIterator it = m_object_list.find(key); if (it != m_object_list.end()) { return it->second; } else { return NULL_ID; } } bool ObjectMap::IsExistsObject(objectid64 key) { read_lock lock(m_object_list_lock); MapTypeIterator it = m_object_list.find(key); if (it != m_object_list.end()) { return true; } else { return false; } } void ObjectMap::FreeObject(objectid64 key) { write_lock lock(m_object_list_lock); MapTypeIterator it = m_object_list.find(key); if (it != m_object_list.end()) { // 删除结点 if (m_object_it == it) { m_object_list.erase(m_object_it++); } else { m_object_list.erase(it); } } } unsigned int ObjectMap::GetSize() { read_lock lock(m_object_list_lock); return m_object_list.size(); } objectid64 ObjectMap::BeginObject() { write_lock lock(m_object_list_lock); m_object_it = m_object_list.begin(); if (m_object_it != m_object_list.end()) { return (m_object_it++)->second; } else { return NULL_ID; } } objectid64 ObjectMap::NextObject() { write_lock lock(m_object_list_lock); if (m_object_it != m_object_list.end()) { return (m_object_it++)->second; } else { return NULL_ID; } } }}其中ToolDefine.h增加了定义读写锁
//读写锁typedef boost::shared_mutex rw_mutex;typedef boost::shared_lock<rw_mutex> read_lock;typedef boost::unique_lock<rw_mutex> write_lock;
新闻热点
疑难解答