332 lines
8.0 KiB
C
332 lines
8.0 KiB
C
|
|
#ifndef _STR_HASH_TABLE_H_
|
|||
|
|
#define _STR_HASH_TABLE_H_
|
|||
|
|
/************************************************************************
|
|||
|
|
* <EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD>
|
|||
|
|
*
|
|||
|
|
* <EFBFBD><EFBFBD>ϣ<EFBFBD>㷨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ѩ<EFBFBD><EFBFBD>ϣ<EFBFBD>㷨<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϣ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><EFBFBD>Ͽ<EFBFBD><EFBFBD>Լ<EFBFBD>
|
|||
|
|
* <EFBFBD><EFBFBD>ķ<EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD>ͻ<EFBFBD><EFBFBD>
|
|||
|
|
*
|
|||
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>hash<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>
|
|||
|
|
* ʼ<EFBFBD><EFBFBD><EFBFBD>ҿ<EFBFBD>λ<EFBFBD><EFBFBD>ֱ֪<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
*
|
|||
|
|
* <EFBFBD>ӱ<EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hashֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣֵ<EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>ҿ<EFBFBD>λ<EFBFBD><EFBFBD>ֱ֪<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
*
|
|||
|
|
*
|
|||
|
|
************************************************************************/
|
|||
|
|
|
|||
|
|
#include "bzhash.h"
|
|||
|
|
|
|||
|
|
template <typename T>
|
|||
|
|
class StrHashTable;
|
|||
|
|
|
|||
|
|
template <typename T>
|
|||
|
|
class StrHashTableIterator
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
StrHashTableIterator()
|
|||
|
|
{
|
|||
|
|
m_pTable = NULL;
|
|||
|
|
m_nIndex = 0;
|
|||
|
|
}
|
|||
|
|
StrHashTableIterator(const StrHashTable<T>& table)
|
|||
|
|
{
|
|||
|
|
setTable(table);
|
|||
|
|
}
|
|||
|
|
inline void setTable(const StrHashTable<T>& table)
|
|||
|
|
{
|
|||
|
|
m_pTable = &table;
|
|||
|
|
m_nIndex = 0;
|
|||
|
|
}
|
|||
|
|
inline T* first()
|
|||
|
|
{
|
|||
|
|
int nLen = (int)(m_pTable->m_nLen);
|
|||
|
|
|
|||
|
|
m_nIndex = 0;
|
|||
|
|
|
|||
|
|
while (m_nIndex < nLen)
|
|||
|
|
{
|
|||
|
|
typename StrHashTable<T>::NodeType* pNode =
|
|||
|
|
&m_pTable->m_pTable[m_nIndex];
|
|||
|
|
|
|||
|
|
m_nIndex++;
|
|||
|
|
|
|||
|
|
if (pNode->hash1)
|
|||
|
|
return &pNode->value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
inline T* next()
|
|||
|
|
{
|
|||
|
|
int nLen = (int)(m_pTable->m_nLen);
|
|||
|
|
|
|||
|
|
while (m_nIndex < nLen)
|
|||
|
|
{
|
|||
|
|
typename StrHashTable<T>::NodeType* pNode =
|
|||
|
|
&m_pTable->m_pTable[m_nIndex];
|
|||
|
|
|
|||
|
|
m_nIndex++;
|
|||
|
|
|
|||
|
|
if (pNode->hash1) return &pNode->value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
private:
|
|||
|
|
const StrHashTable<T>* m_pTable;
|
|||
|
|
int m_nIndex;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
template <typename T>
|
|||
|
|
class StrHashTable
|
|||
|
|
{
|
|||
|
|
friend class StrHashTableIterator<T>;
|
|||
|
|
public:
|
|||
|
|
typedef StrHashTable<T> ClassType;
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
StrHashTable(size_t len = 0)
|
|||
|
|
{
|
|||
|
|
m_pTable = NULL;
|
|||
|
|
m_nLen = m_nFree = 0;
|
|||
|
|
m_nInitSize = len;
|
|||
|
|
|
|||
|
|
if (len > MiniSize)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD>Ƴ<EFBFBD><C6B3>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1>㷨<EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
size_t val;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < 32; ++i)
|
|||
|
|
{
|
|||
|
|
val = size_t(1 << i);
|
|||
|
|
|
|||
|
|
if (len <= val)
|
|||
|
|
{
|
|||
|
|
m_nInitSize = val;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
m_nInitSize = MiniSize; // <20><><EFBFBD>Ƴ<EFBFBD><C6B3>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1>㷨<EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
virtual ~StrHashTable()
|
|||
|
|
{
|
|||
|
|
clear();
|
|||
|
|
}
|
|||
|
|
//<2F><>չ<EFBFBD>ϣ<EFBFBD><CFA3>
|
|||
|
|
void clear()
|
|||
|
|
{
|
|||
|
|
//ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
for (int i = (int)m_nLen - 1; i > -1; --i)
|
|||
|
|
{
|
|||
|
|
if (m_pTable[i].hash1)
|
|||
|
|
{
|
|||
|
|
m_pTable[i].value.~T();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
|
|||
|
|
if (m_pTable) realloc(m_pTable, 0);
|
|||
|
|
|
|||
|
|
m_pTable = NULL;
|
|||
|
|
m_nLen = m_nFree = 0;
|
|||
|
|
}
|
|||
|
|
//<2F><>ȡ<EFBFBD><C8A1>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
inline size_t count() const
|
|||
|
|
{
|
|||
|
|
return m_nLen - m_nFree;
|
|||
|
|
}
|
|||
|
|
protected:
|
|||
|
|
/** <20><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>ʹ<EFBFBD>õĹ<C3B5>ϣ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ݽṹ **/
|
|||
|
|
template <typename TA>
|
|||
|
|
class HashNode
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
unsigned int hash1; //<2F><>ϣֵ1
|
|||
|
|
unsigned int hash2; //<2F><>ϣֵ2
|
|||
|
|
unsigned int hash3; //<2F><>ϣֵ3
|
|||
|
|
TA value; //<2F><><EFBFBD><EFBFBD>ֵ
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
typedef HashNode<T> NodeType;
|
|||
|
|
public:
|
|||
|
|
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|||
|
|
inline T* get(const char* sKey)
|
|||
|
|
{
|
|||
|
|
int idx = getIndex(sKey);
|
|||
|
|
return (idx >= 0) ? &m_pTable[idx].value : NULL;
|
|||
|
|
}
|
|||
|
|
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|||
|
|
inline const T* get(const char* sKey) const
|
|||
|
|
{
|
|||
|
|
int idx = getIndex(sKey);
|
|||
|
|
return (idx >= 0) ? &m_pTable[idx].value : NULL;
|
|||
|
|
}
|
|||
|
|
/* ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|||
|
|
* <EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>hash<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>ҿ<EFBFBD>λ<EFBFBD><EFBFBD>ֱ֪<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
*/
|
|||
|
|
inline T* put(const char* sKey)
|
|||
|
|
{
|
|||
|
|
unsigned int hash1, idx, start;
|
|||
|
|
#ifdef _MSC_VER
|
|||
|
|
unsigned int hash2, hash3;
|
|||
|
|
#else
|
|||
|
|
unsigned int __attribute__ ((unused)) hash2, hash3;
|
|||
|
|
#endif
|
|||
|
|
//<2F>ڴ<EFBFBD>ռ䲻<D5BC>㣬<EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ռ<EFBFBD>
|
|||
|
|
if (m_nFree <= 0)
|
|||
|
|
{
|
|||
|
|
size_t oldlen = m_nLen;
|
|||
|
|
m_nLen = (oldlen <= 0) ? m_nInitSize : m_nLen << 1;//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
|
|||
|
|
m_nFree = m_nLen - oldlen;
|
|||
|
|
m_pTable = (NodeType*)realloc(m_pTable, m_nLen * sizeof(m_pTable[0]));
|
|||
|
|
memset(&m_pTable[oldlen], 0, m_nFree * sizeof(m_pTable[0]));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
hash1 = ::bzhashstr(sKey, 0);
|
|||
|
|
hash2 = ::bzhashstr(sKey, 1);
|
|||
|
|
hash3 = ::bzhashstr(sKey, 2);
|
|||
|
|
start = idx = hash1 & ((unsigned int)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
|
|||
|
|
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
NodeType* pNode = &m_pTable[idx];
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>û<EFBFBD><C3BB>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
|||
|
|
if (!pNode->hash1)
|
|||
|
|
{
|
|||
|
|
pNode->hash1 = hash1;
|
|||
|
|
pNode->hash2 = ::bzhashstr(sKey, 1);
|
|||
|
|
pNode->hash3 = ::bzhashstr(sKey, 2);
|
|||
|
|
m_nFree--;
|
|||
|
|
new(&pNode->value)T();
|
|||
|
|
return &pNode->value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifdef _DEBUG
|
|||
|
|
else if (pNode->hash1 == hash1 && pNode->hash2 == hash2 && pNode->hash3 == hash3)
|
|||
|
|
{
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>ȷʵ<C8B7><CAB5><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>
|
|||
|
|
//DebugBreak();
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
idx = (idx + 1) & ((unsigned int)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
|
|||
|
|
}
|
|||
|
|
while (start != idx);
|
|||
|
|
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|||
|
|
inline int update(const char* sKey, const T& value)
|
|||
|
|
{
|
|||
|
|
int idx = getIndex(sKey);
|
|||
|
|
|
|||
|
|
if (idx >= 0)
|
|||
|
|
m_pTable[idx].value = value;
|
|||
|
|
|
|||
|
|
return idx;
|
|||
|
|
}
|
|||
|
|
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>ֵ<EFBFBD><D6B5>û<EFBFBD><C3BB><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>-1
|
|||
|
|
inline int remove(const char* sKey)
|
|||
|
|
{
|
|||
|
|
int idx = getIndex(sKey);
|
|||
|
|
|
|||
|
|
if (idx >= 0)
|
|||
|
|
{
|
|||
|
|
NodeType* pNode = &m_pTable[idx];
|
|||
|
|
pNode->hash1 = pNode->hash2 = pNode->hash3 = 0;
|
|||
|
|
m_nFree++;
|
|||
|
|
pNode->value.~T();
|
|||
|
|
return idx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ڱ<EFBFBD><DAB1>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int getIndex(const char* sKey) const
|
|||
|
|
{
|
|||
|
|
unsigned int idx, start;
|
|||
|
|
size_t len;
|
|||
|
|
|
|||
|
|
if (m_nLen <= 0)
|
|||
|
|
return -1;
|
|||
|
|
|
|||
|
|
unsigned int hash1 = ::bzhashstr(sKey, 0);
|
|||
|
|
unsigned int hash2 = ::bzhashstr(sKey, 1);
|
|||
|
|
unsigned int hash3 = ::bzhashstr(sKey, 2);
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD>ȿ<EFBFBD>ʼ<EFBFBD>۰<EFBFBD><DBB0><EFBFBD><EFBFBD>
|
|||
|
|
len = m_nLen;
|
|||
|
|
|
|||
|
|
while (len >= m_nInitSize)
|
|||
|
|
{
|
|||
|
|
idx = hash1 & ((unsigned int)len - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
|
|||
|
|
NodeType* pNode = &m_pTable[idx];
|
|||
|
|
|
|||
|
|
if (pNode->hash1 == hash1 && pNode->hash2 == hash2 && pNode->hash3 == hash3)
|
|||
|
|
{
|
|||
|
|
return idx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
len >>= 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F>۰<EFBFBD><DBB0><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hashλ<68>ÿ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
start = idx = hash1 & ((unsigned int)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
|
|||
|
|
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
NodeType* pNode = &m_pTable[idx];
|
|||
|
|
|
|||
|
|
if (pNode->hash1 == hash1 && pNode->hash2 == hash2 && pNode->hash3 == hash3)
|
|||
|
|
{
|
|||
|
|
return idx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
idx = (idx + 1) & ((unsigned int)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
|
|||
|
|
}
|
|||
|
|
while (start != idx);
|
|||
|
|
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
//<2F>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>뺯<EFBFBD><EBBAAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>c<EFBFBD><63><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>reallocʵ<63><CAB5><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD>롢<EFBFBD><EBA1A2>չ<EFBFBD>Լ<EFBFBD><D4BC>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
|
|||
|
|
virtual void* realloc(void* p, size_t s)
|
|||
|
|
{
|
|||
|
|
#ifdef _MSC_VER
|
|||
|
|
static BaseAllocator alloc("bzhashtable");
|
|||
|
|
if (s > 0)
|
|||
|
|
{
|
|||
|
|
return alloc.ReAllocBuffer(p, s);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (p)
|
|||
|
|
{
|
|||
|
|
alloc.FreeBuffer(p);
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
return alloc.ReAllocBuffer(p, s);
|
|||
|
|
#else
|
|||
|
|
return ::realloc(p, s);
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
protected:
|
|||
|
|
size_t m_nInitSize;//<2F><><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|||
|
|
size_t m_nLen; //<2F><>ϣ<EFBFBD><CFA3><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1>㷨<EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
size_t m_nFree; //<2F><><EFBFBD>нڵ<D0BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
HashNode<T>* m_pTable; //<2F><>ϣ<EFBFBD><CFA3>
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
static const size_t MiniSize = 16;//<2F><>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1>㷨<EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
};
|
|||
|
|
#endif
|
|||
|
|
|