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