merged changes from SH:TinyHash

This commit is contained in:
Borja Ferrer 2006-01-06 18:52:12 +00:00
parent 86c033a922
commit 04113f8a02

View File

@ -13,38 +13,41 @@
#include "sh_list.h"
#define _T_INIT_HASH_SIZE 128
#define _T_INIT_HASH_SIZE 512
//namespace SourceHook
//{
template <class K>
int HashFunction(const K & k);
template <class K>
int HashFunction(const K & k);
template <class K>
int Compare(const K & k1, const K & k2);
template <class K>
int Compare(const K & k1, const K & k2);
/**
* This is a tiny, growable hash class.
* Meant for quick and dirty dictionaries only!
*/
template <class K, class V>
class THash
{
public:
/**
* This is a tiny, growable hash class.
* Meant for quick and dirty dictionaries only!
*/
template <class K, class V>
class THash
{
public:
struct THashNode
{
THashNode(const K & k, const V & v) :
key(k), val(v)
{
};
~THashNode()
THashNode & operator =(const THashNode &other)
{
key = other.key;
val = other.val;
}
K key;
V val;
};
typedef List<THashNode> * NodePtr;
public:
typedef List<THashNode *> * NodePtr;
public:
class const_iterator;
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f), m_NumItems(0)
{
_Refactor();
@ -90,13 +93,21 @@
THashNode *pNode = _FindOrInsert(key);
return pNode->val;
}
private:
private:
void _Clear()
{
typename List<THashNode *>::iterator iter, end;
for (size_t i=0; i<m_numBuckets; i++)
{
if (m_Buckets[i])
{
end = m_Buckets[i]->end();
iter = m_Buckets[i]->begin();
while (iter != end)
{
delete (*iter);
iter++;
}
delete m_Buckets[i];
m_Buckets[i] = NULL;
}
@ -113,33 +124,25 @@
THashNode *pNode = NULL;
if (!m_Buckets[place])
{
m_Buckets[place] = new List<THashNode>;
m_Buckets[place]->push_back(THashNode(key, V()));
m_Buckets[place] = new List<THashNode *>;
pNode = new THashNode(key, V());
m_Buckets[place]->push_back(pNode);
m_percentUsed += (1.0f / (float)m_numBuckets);
m_NumItems++;
typename List<THashNode>::iterator iter;
iter = m_Buckets[place]->end();
iter--;
pNode = &(*iter);
} else {
typename List<THashNode>::iterator iter, end=m_Buckets[place]->end();
for (iter=m_Buckets[place]->begin(); iter!=end; iter++)
typename List<THashNode *>::iterator iter;
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
{
if (Compare((*iter).key, key) == 0)
return &(*iter);
if (Compare((*iter)->key, key) == 0)
return (*iter);
}
//node does not exist
m_Buckets[place]->push_back(THashNode(key, V()));
pNode = new THashNode(key, V());
m_Buckets[place]->push_back(pNode);
m_NumItems++;
iter = m_Buckets[place]->end();
iter--;
pNode = &(*iter);
}
if (PercentUsed() > 0.75f)
{
_Refactor();
return _FindOrInsert(key);
}
return pNode;
}
void _Refactor()
@ -154,7 +157,7 @@
} else {
size_t oldSize = m_numBuckets;
m_numBuckets *= 2;
typename List<THashNode>::iterator iter, end;
typename List<THashNode *>::iterator iter;
size_t place;
THashNode *pHashNode;
NodePtr *temp = new NodePtr[m_numBuckets];
@ -167,19 +170,18 @@
if (m_Buckets[i])
{
//go through the list of items
end = m_Buckets[i]->end();
for (iter = m_Buckets[i]->begin(); iter!=end; iter++)
for (iter = m_Buckets[i]->begin(); iter != m_Buckets[i]->end(); iter++)
{
pHashNode = &(*iter);
pHashNode = (*iter);
//rehash it with the new bucket filter
place = HashFunction(pHashNode->key) % m_numBuckets;
//add it to the new hash table
if (!temp[place])
{
temp[place] = new List<THashNode>;
temp[place] = new List<THashNode *>;
m_percentUsed += (1.0f / (float)m_numBuckets);
}
temp[place]->push_back((*iter));
temp[place]->push_back(pHashNode);
}
//delete that bucket!
delete m_Buckets[i];
@ -191,7 +193,7 @@
m_Buckets = temp;
}
}
public:
public:
friend class iterator;
friend class const_iterator;
class iterator
@ -223,19 +225,19 @@
}
const THashNode & operator * () const
{
return (*iter);
return *(*iter);
}
THashNode & operator * ()
{
return (*iter);
return *(*iter);
}
const THashNode * operator ->() const
{
return &(*iter);
return (*iter);
}
THashNode * operator ->()
{
return &(*iter);
return (*iter);
}
bool operator ==(const iterator &where) const
{
@ -262,6 +264,7 @@
// Remove this element and move to the next one
iterator tmp = *this;
++tmp;
delete (*iter);
hash->m_Buckets[curbucket]->erase(iter);
*this = tmp;
m_NumItems--;
@ -312,7 +315,7 @@
}
private:
int curbucket;
typename List<THashNode>::iterator iter;
typename List<THashNode *>::iterator iter;
THash *hash;
bool end;
};
@ -415,7 +418,7 @@
const THash *hash;
bool end;
};
public:
public:
iterator begin()
{
return iterator(this);
@ -476,12 +479,12 @@
return;
iter.erase();
}
private:
private:
NodePtr *m_Buckets;
size_t m_numBuckets;
float m_percentUsed;
size_t m_NumItems;
};
};
//};
#endif //_INCLUDE_SH_TINYHASH_H_