第十一個工具類: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;
新聞熱點
疑難解答