📄 tnamedictionary.h
字号:
//tNameDictionary.h
/*/////////////////////////////////////////////////////////////////
Dictionary类模板
Entry结构 需要符合
{
StringTableEntry pIDName; //必须
Entry* pHashNext; //必须
//...
}
李亦
liease@163.com 4040719
2006-7-18
/*/////////////////////////////////////////////////////////////////
#ifndef _TNAMEDICTIONARY_H_
#define _TNAMEDICTIONARY_H_
#ifndef _DATACHUNKER_H_
#include "core/dataChunker.h"
#endif
#ifndef _PLATFORM_H_
#include "platform/platform.h"
#endif
template<class _T>
class NameDictionary;
//////////////////////////////////////////
//字典条目
template<class _T>
struct NameDictionaryEntry
{
friend class NameDictionary<_T>;
//private:
_T data;
//StringTableEntry pIDName;
NameDictionaryEntry<_T>* pHashNext;
};
//////////////////////////////////////////
//ID型字典管理
template<class _T>
class NameDictionary
{
protected:
U32 m_dwAmount; //单元总数
U32 m_dwHashSize;
NameDictionaryEntry<_T> **m_pHashTable;
protected:
static FreeListChunker< NameDictionaryEntry<_T> > gs_gameChunker;
//static void FreeEntry(Entry *entry);
//static Entry *AllocEntry();
void AddEntry(NameDictionaryEntry<_T>* pEntry);
void IncAmount();
void DecAmount();
void Resize(const U32 newSize);
public:
NameDictionary(U32 dwSize);
~NameDictionary();
void FreeHashTable();
_T* Insert(StringTableEntry pIDName);
void Remove(StringTableEntry pIDName);
_T* Get(StringTableEntry pIDName);
};
//////////////////////////////////////////////////////////////
//以下为模板实现
template<class _T>
FreeListChunker< NameDictionaryEntry<_T> > NameDictionary<_T>::gs_gameChunker;
//////////////////////////////////////////
//template<class _T>
//inline NameDictionary<_T>::Entry *NameDictionary<_T>::AllocEntry()
//{
// return gs_gameChunker.alloc();
//}
//template<class _T>
//inline void NameDictionary<_T>::FreeEntry(Entry *ent)
//{
// gs_gameChunker.free(ent);
//}
////////////////////////////////////////////////
//构造/析构函数
template<class _T>
NameDictionary<_T>::NameDictionary(U32 dwSize)
{
m_dwAmount = 0;
m_pHashTable = NULL;
m_dwHashSize = 0;
Resize(dwSize);
}
template<class _T>
NameDictionary<_T>::~NameDictionary()
{
FreeHashTable();
dFree(m_pHashTable);
m_dwAmount = 0;
}
template<class _T>
void NameDictionary<_T>::FreeHashTable()
{
NameDictionaryEntry<_T> *walk,
*temp;
for(U32 i = 0; i < m_dwHashSize; i++)
{
for(walk = m_pHashTable[i]; walk;)
{
temp = walk;
walk = temp->pHashNext;
gs_gameChunker.free(temp);
}
m_pHashTable[i] = NULL;
}
}
template<class _T>
void NameDictionary<_T>::AddEntry(NameDictionaryEntry<_T>* pEntry)
{
if(pEntry == NULL)
return;
_T *field = pEntry;
//U32 bucket = pEntry->dwID % m_dwHashSize;
U32 bucket = HashPointer(pEntry->data.pIDName) % m_dwHashSize;
field->pHashNext = m_pHashTable[bucket];
m_pHashTable[bucket] = field;
IncAmount();
}
template<class _T>
void NameDictionary<_T>::IncAmount()
{
m_dwAmount++;
if(m_dwAmount > m_dwHashSize * 2)
{
Resize(m_dwHashSize*4 - 1);
}
}
template<class _T>
void NameDictionary<_T>::Resize(const U32 newSize)
{
NameDictionaryEntry<_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 = (NameDictionaryEntry<_T> **) dRealloc(m_pHashTable, newSize * sizeof(NameDictionaryEntry<_T>*));
}//if(m_pHashTable)
else
{
m_pHashTable = (NameDictionaryEntry<_T> **) dMalloc(newSize * sizeof(NameDictionaryEntry<_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 = HashPointer(temp->data.pIDName) % newSize;
temp->pHashNext = m_pHashTable[dwKey];
m_pHashTable[dwKey] = temp;
}
}
template<class _T>
inline void NameDictionary<_T>::DecAmount()
{
if(m_dwAmount > 0)
m_dwAmount--;
}
template<class _T>
void NameDictionary<_T>::Remove(StringTableEntry pIDName)
{
U32 bucket = HashPointer(pIDName) % m_dwHashSize;
//U32 bucket = dwID % m_dwHashSize;
NameDictionaryEntry<_T> **walk = &m_pHashTable[bucket];
while(*walk && (*walk)->data.pIDName != pIDName)
walk = &((*walk)->pHashNext);
NameDictionaryEntry<_T> *field = *walk;
if(field)
{
*walk = field->pHashNext;
gs_gameChunker.free(field);
DecAmount();
}
}
template<class _T>
_T *NameDictionary<_T>::Get(StringTableEntry pIDName)
{
U32 bucket = HashPointer(pIDName) % m_dwHashSize;
//U32 bucket = dwID % m_dwHashSize;
for(NameDictionaryEntry<_T> *walk = m_pHashTable[bucket];walk;walk = walk->pHashNext)
{
if(walk->data.pIDName == pIDName)
{
return &walk->data;
}
}
return NULL;
}
template<class _T>
_T *NameDictionary<_T>::Insert(StringTableEntry pIDName)
{
_T* pData = Get(pIDName) ;
if(pData != NULL)
return pData;
U32 bucket = HashPointer(pIDName) % m_dwHashSize;
//U32 bucket = dwID % m_dwHashSize;
NameDictionaryEntry<_T>* pNew;
pNew = gs_gameChunker.alloc();
pNew->data.pIDName = pIDName;
pNew->pHashNext = m_pHashTable[bucket];
m_pHashTable[bucket] = pNew;
IncAmount();
return &pNew->data;
}
#endif //_TNAMEDICTIONARY_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -