📄 tobjdictionary.h
字号:
//tObjDictionary.h
/*/////////////////////////////////////////////////////////////////
对象 Dictionary类模板
与IDDictionary不一样,这里在进行allocEntry、freeEntry时,将调用
对象的构造函数、析构函数
Entry结构 需要符合
{
_T* pData;
Entry* pHashNext; //必须
//...
}
李亦
liease@163.com 4040719
2006-7-18
/*/////////////////////////////////////////////////////////////////
#ifndef _TOBJDICTIONARY_H_
#define _TOBJDICTIONARY_H_
#ifndef _PLATFORM_H_
#include "platform/platform.h"
#endif
#ifndef _DATACHUNKER_H_
#include "core/dataChunker.h"
#endif
template<class _T>
class OBJDictionary;
//////////////////////////////////////////
//字典条目
template<class _T>
struct OBJDictionaryEntry
{
friend class OBJDictionary<_T>;
//private:
_T object;
//U32 dwID;
OBJDictionaryEntry<_T>* pHashNext;
};
//////////////////////////////////////////
//ID型字典管理
template<class _T>
class OBJDictionary
{
protected:
U32 m_dwAmount; //单元总数
U32 m_dwHashSize;
OBJDictionaryEntry<_T> **m_pHashTable;
protected:
static FreeListChunker< OBJDictionaryEntry<_T> > gs_gameChunker;
static void FreeEntry(OBJDictionaryEntry<_T> *entry);
static OBJDictionaryEntry<_T> *AllocEntry();
void AddEntry(OBJDictionaryEntry<_T>* pEntry);
void IncAmount();
void DecAmount();
void Resize(const U32 newSize);
_T* _New(U32 dwID);
public:
OBJDictionary(U32 dwSize);
~OBJDictionary();
void FreeHashTable();
_T* New(BOOL bAutoReg);
_T* Insert(U32 dwID);
_T* Reg(U32 dwID);
void Remove(U32 dwID);
void Remove(_T* pObject);
void Unreg(U32 dwID);
void Unreg(_T* pObject);
_T* Get(U32 dwID);
};
//////////////////////////////////////////////////////////////
//以下为模板实现
template<class _T>
FreeListChunker< OBJDictionaryEntry<_T> > OBJDictionary<_T>::gs_gameChunker;
////////////////////////////////////////////////
//构造/析构函数
template<class _T>
OBJDictionary<_T>::OBJDictionary(U32 dwSize)
{
m_dwAmount = 0;
m_pHashTable = NULL;
m_dwHashSize = 0;
Resize(dwSize);
}
template<class _T>
OBJDictionary<_T>::~OBJDictionary()
{
FreeHashTable();
dFree(m_pHashTable);
m_dwAmount = 0;
}
template<class _T>
void OBJDictionary<_T>::FreeHashTable()
{
OBJDictionaryEntry<_T> *walk,
*temp;
for(U32 i = 0; i < m_dwHashSize; i++)
{
for(walk = m_pHashTable[i]; walk;)
{
temp = walk;
walk = temp->pHashNext;
FreeEntry(temp);
//gs_gameChunker.free(temp);
}
m_pHashTable[i] = NULL;
}
}
template<class _T>
inline void OBJDictionary<_T>::FreeEntry(OBJDictionaryEntry<_T> *pEntry)
{
pEntry->object.OnDeleteAtDictionary();
destructInPlace(&pEntry->object);
gs_gameChunker.free(pEntry);
}
template<class _T>
OBJDictionaryEntry<_T> *OBJDictionary<_T>::AllocEntry()
{
OBJDictionaryEntry<_T> *pNew;
pNew = gs_gameChunker.alloc();
constructInPlace(&pNew->object);
return pNew;
}
template<class _T>
void OBJDictionary<_T>::AddEntry(OBJDictionaryEntry<_T>* pEntry)
{
if(pEntry == NULL)
return;
_T *field = pEntry;
U32 bucket = pEntry->object.GetID() % m_dwHashSize;
field->pHashNext = m_pHashTable[bucket];
m_pHashTable[bucket] = field;
IncAmount();
}
template<class _T>
void OBJDictionary<_T>::IncAmount()
{
m_dwAmount++;
if(m_dwAmount > m_dwHashSize * 2)
{
Resize(m_dwHashSize*4 - 1);
}
}
template<class _T>
void OBJDictionary<_T>::Resize(const U32 newSize)
{
OBJDictionaryEntry<_T> *head = NULL, *walk, *temp;
U32 i;
U32 dwKey;
if(m_pHashTable)
{
//先把数据备份起来
for(i = 0; i < m_dwHashSize; i++)
{
walk = m_pHashTable[i];
while(walk)
{
temp = walk->pHashNext;
walk->pHashNext = head;
head = walk;
walk = temp;
}
}
//生成新的Hash空间
m_pHashTable = (OBJDictionaryEntry<_T> **) dRealloc(m_pHashTable, newSize * sizeof(OBJDictionaryEntry<_T>*));
}//if(m_pHashTable)
else
{
m_pHashTable = (OBJDictionaryEntry<_T> **) dMalloc(newSize * sizeof(OBJDictionaryEntry<_T>*));
head = NULL;
}
for(i = 0; i < newSize; i++)
{
m_pHashTable[i] = 0;
}
//重新关联单元
m_dwHashSize = newSize;
walk = head;
while(walk)
{
temp = walk;
walk = walk->pHashNext;
dwKey = temp->object.GetID() % newSize;
temp->pHashNext = m_pHashTable[dwKey];
m_pHashTable[dwKey] = temp;
}
}
template<class _T>
inline void OBJDictionary<_T>::DecAmount()
{
if(m_dwAmount > 0)
m_dwAmount--;
}
template<class _T>
void OBJDictionary<_T>::Remove(U32 dwID)
{
//U32 bucket = HashPointer(slotName) % m_dwHashSize;
U32 bucket = dwID % m_dwHashSize;
OBJDictionaryEntry<_T> **walk = &m_pHashTable[bucket];
while(*walk && (*walk)->object.GetID() != dwID)
walk = &((*walk)->pHashNext);
OBJDictionaryEntry<_T> *field = *walk;
if(field)
{
*walk = field->pHashNext;
FreeEntry(field);
//gs_gameChunker.free(field);
DecAmount();
}
}
template<class _T>
inline void OBJDictionary<_T>::Remove(_T* pObject)
{
AssertWarn(pObject,"pObject不能为空");
Remove(pObject->GetID());
}
template<class _T>
void OBJDictionary<_T>::Unreg(U32 dwID)
{
_T* pData = Get(dwID) ;
if(pData != NULL)
{
pData->unregisterObject();
pData->OnUnreg();
Remove(dwID);
}
}
template<class _T>
inline void OBJDictionary<_T>::Unreg(_T* pObject)
{
AssertWarn(pObject,"pObject不能为空");
Unreg(pObject->GetID());
}
template<class _T>
_T *OBJDictionary<_T>::Get(U32 dwID)
{
//U32 bucket = HashPointer(slotName) % m_dwHashSize;
U32 bucket = dwID % m_dwHashSize;
for(OBJDictionaryEntry<_T> *walk = m_pHashTable[bucket];walk;walk = walk->pHashNext)
{
if(walk->object.GetID() == dwID)
{
return &walk->object;
}
}
return NULL;
}
template<class _T>
_T* OBJDictionary<_T>::Reg(U32 dwID)
{
_T* pData = Get(dwID) ;
if(pData != NULL)
return pData;
pData = _New(dwID);
if(pData->OnReg())
{
pData->registerObject();
return pData;
}
return NULL;
}
template<class _T>
_T *OBJDictionary<_T>::Insert(U32 dwID)
{
_T* pData = Get(dwID) ;
if(pData != NULL)
return pData;
return _New(dwID);
}
template<class _T>
_T *OBJDictionary<_T>::_New(U32 dwID)
{
U32 bucket = dwID % m_dwHashSize;
OBJDictionaryEntry<_T>* pNew;
pNew = AllocEntry();
pNew->pHashNext = m_pHashTable[bucket];
m_pHashTable[bucket] = pNew;
pNew->object.SetID(dwID);
IncAmount();
return &pNew->object;
}
template<class _T>
_T *OBJDictionary<_T>::New(BOOL bAutoReg)
{
OBJDictionaryEntry<_T>* pNew;
U32 dwID;
for(dwID=1; dwID; dwID++)
{
if(Get(dwID) == NULL)
{
if(bAutoReg)
return Reg(dwID);
return _New(dwID);
}
}
return NULL;
}
#endif //_TOBJDICTIONARY_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -