sync
This commit is contained in:
parent
44db80bc75
commit
cb291dbdd5
|
@ -17,287 +17,269 @@
|
||||||
|
|
||||||
//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:
|
|
||||||
struct THashNode
|
|
||||||
{
|
{
|
||||||
THashNode(const K & k, const V & v) :
|
public:
|
||||||
key(k), val(v)
|
struct THashNode
|
||||||
{
|
|
||||||
};
|
|
||||||
THashNode & operator =(const THashNode &other)
|
|
||||||
{
|
|
||||||
key = other.key;
|
|
||||||
val = other.val;
|
|
||||||
}
|
|
||||||
K key;
|
|
||||||
V val;
|
|
||||||
};
|
|
||||||
typedef List<THashNode *> * NodePtr;
|
|
||||||
public:
|
|
||||||
class const_iterator;
|
|
||||||
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f), m_NumItems(0)
|
|
||||||
{
|
|
||||||
_Refactor();
|
|
||||||
}
|
|
||||||
THash(const THash &other) : m_Buckets(new NodePtr[other.m_numBuckets]),
|
|
||||||
m_numBuckets(other.m_numBuckets), m_percentUsed(other.m_percentUsed)
|
|
||||||
{
|
|
||||||
for (size_t i=0; i<m_numBuckets; i++)
|
|
||||||
m_Buckets[i] = NULL;
|
|
||||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
|
||||||
_FindOrInsert(iter->key)->val = iter->val;
|
|
||||||
}
|
|
||||||
void operator=(const THash &other)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
|
||||||
_FindOrInsert(iter->key)->val = iter->val;
|
|
||||||
}
|
|
||||||
|
|
||||||
~THash()
|
|
||||||
{
|
|
||||||
_Clear();
|
|
||||||
}
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
_Clear();
|
|
||||||
_Refactor();
|
|
||||||
}
|
|
||||||
size_t GetBuckets()
|
|
||||||
{
|
|
||||||
return m_numBuckets;
|
|
||||||
}
|
|
||||||
float PercentUsed()
|
|
||||||
{
|
|
||||||
return m_percentUsed;
|
|
||||||
}
|
|
||||||
size_t size()
|
|
||||||
{
|
|
||||||
return m_NumItems;
|
|
||||||
}
|
|
||||||
V & operator [](const K & key)
|
|
||||||
{
|
|
||||||
THashNode *pNode = _FindOrInsert(key);
|
|
||||||
return pNode->val;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void _Clear()
|
|
||||||
{
|
|
||||||
typename List<THashNode *>::iterator iter, end;
|
|
||||||
for (size_t i=0; i<m_numBuckets; i++)
|
|
||||||
{
|
{
|
||||||
if (m_Buckets[i])
|
THashNode(const K & k, const V & v) :
|
||||||
{
|
key(k), val(v)
|
||||||
end = m_Buckets[i]->end();
|
|
||||||
iter = m_Buckets[i]->begin();
|
|
||||||
while (iter != end)
|
|
||||||
{
|
{
|
||||||
delete (*iter);
|
};
|
||||||
iter++;
|
THashNode & operator =(const THashNode &other)
|
||||||
}
|
|
||||||
delete m_Buckets[i];
|
|
||||||
m_Buckets[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_Buckets)
|
|
||||||
delete [] m_Buckets;
|
|
||||||
m_Buckets = NULL;
|
|
||||||
m_numBuckets = 0;
|
|
||||||
m_NumItems = 0;
|
|
||||||
}
|
|
||||||
THashNode *_FindOrInsert(const K & key)
|
|
||||||
{
|
|
||||||
size_t place = HashFunction(key) % m_numBuckets;
|
|
||||||
THashNode *pNode = NULL;
|
|
||||||
if (!m_Buckets[place])
|
|
||||||
{
|
|
||||||
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++;
|
|
||||||
} else {
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
|
|
||||||
{
|
{
|
||||||
if (Compare((*iter)->key, key) == 0)
|
key = other.key;
|
||||||
return (*iter);
|
val = other.val;
|
||||||
}
|
}
|
||||||
//node does not exist
|
K key;
|
||||||
pNode = new THashNode(key, V());
|
V val;
|
||||||
m_Buckets[place]->push_back(pNode);
|
};
|
||||||
m_NumItems++;
|
typedef List<THashNode *> * NodePtr;
|
||||||
}
|
public:
|
||||||
if (PercentUsed() > 0.75f)
|
class const_iterator;
|
||||||
|
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f), m_items(0)
|
||||||
|
{
|
||||||
_Refactor();
|
_Refactor();
|
||||||
return pNode;
|
}
|
||||||
}
|
THash(const THash &other) : m_Buckets(new NodePtr[other.m_numBuckets]),
|
||||||
void _Refactor()
|
m_numBuckets(other.m_numBuckets), m_percentUsed(other.m_percentUsed), m_items(0)
|
||||||
{
|
|
||||||
m_percentUsed = 0.0f;
|
|
||||||
if (!m_numBuckets)
|
|
||||||
{
|
{
|
||||||
m_numBuckets = _T_INIT_HASH_SIZE;
|
|
||||||
m_Buckets = new NodePtr[m_numBuckets];
|
|
||||||
for (size_t i=0; i<m_numBuckets; i++)
|
for (size_t i=0; i<m_numBuckets; i++)
|
||||||
m_Buckets[i] = NULL;
|
m_Buckets[i] = NULL;
|
||||||
} else {
|
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
||||||
size_t oldSize = m_numBuckets;
|
_FindOrInsert(iter->key)->val = iter->val;
|
||||||
m_numBuckets *= 2;
|
}
|
||||||
typename List<THashNode *>::iterator iter;
|
void operator=(const THash &other)
|
||||||
size_t place;
|
{
|
||||||
THashNode *pHashNode;
|
clear();
|
||||||
NodePtr *temp = new NodePtr[m_numBuckets];
|
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
||||||
|
_FindOrInsert(iter->key)->val = iter->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
~THash()
|
||||||
|
{
|
||||||
|
_Clear();
|
||||||
|
}
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
_Clear();
|
||||||
|
_Refactor();
|
||||||
|
}
|
||||||
|
size_t size()
|
||||||
|
{
|
||||||
|
return m_items;
|
||||||
|
}
|
||||||
|
size_t GetBuckets()
|
||||||
|
{
|
||||||
|
return m_numBuckets;
|
||||||
|
}
|
||||||
|
float PercentUsed()
|
||||||
|
{
|
||||||
|
return m_percentUsed;
|
||||||
|
}
|
||||||
|
V & operator [](const K & key)
|
||||||
|
{
|
||||||
|
THashNode *pNode = _FindOrInsert(key);
|
||||||
|
return pNode->val;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
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++)
|
||||||
temp[i] = NULL;
|
|
||||||
//look in old hash table
|
|
||||||
for (size_t i=0; i<oldSize; i++)
|
|
||||||
{
|
{
|
||||||
//does a bucket have anything?
|
|
||||||
if (m_Buckets[i])
|
if (m_Buckets[i])
|
||||||
{
|
{
|
||||||
//go through the list of items
|
end = m_Buckets[i]->end();
|
||||||
for (iter = m_Buckets[i]->begin(); iter != m_Buckets[i]->end(); iter++)
|
iter = m_Buckets[i]->begin();
|
||||||
|
while (iter != end)
|
||||||
{
|
{
|
||||||
pHashNode = (*iter);
|
delete (*iter);
|
||||||
//rehash it with the new bucket filter
|
iter++;
|
||||||
place = HashFunction(pHashNode->key) % m_numBuckets;
|
|
||||||
//add it to the new hash table
|
|
||||||
if (!temp[place])
|
|
||||||
{
|
|
||||||
temp[place] = new List<THashNode *>;
|
|
||||||
m_percentUsed += (1.0f / (float)m_numBuckets);
|
|
||||||
}
|
|
||||||
temp[place]->push_back(pHashNode);
|
|
||||||
}
|
}
|
||||||
//delete that bucket!
|
|
||||||
delete m_Buckets[i];
|
delete m_Buckets[i];
|
||||||
m_Buckets[i] = NULL;
|
m_Buckets[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//reassign bucket table
|
if (m_Buckets)
|
||||||
delete [] m_Buckets;
|
delete [] m_Buckets;
|
||||||
m_Buckets = temp;
|
m_Buckets = NULL;
|
||||||
|
m_numBuckets = 0;
|
||||||
|
m_items = 0;
|
||||||
}
|
}
|
||||||
}
|
THashNode *_FindOrInsert(const K & key)
|
||||||
public:
|
|
||||||
friend class iterator;
|
|
||||||
friend class const_iterator;
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
friend class THash;
|
|
||||||
public:
|
|
||||||
iterator() : curbucket(-1), hash(NULL), end(true)
|
|
||||||
{
|
{
|
||||||
};
|
size_t place = HashFunction(key) % m_numBuckets;
|
||||||
iterator(THash *h) : curbucket(-1), hash(h), end(false)
|
THashNode *pNode = NULL;
|
||||||
{
|
if (!m_Buckets[place])
|
||||||
if (!h->m_Buckets)
|
|
||||||
end = true;
|
|
||||||
else
|
|
||||||
_Inc();
|
|
||||||
};
|
|
||||||
//pre increment
|
|
||||||
iterator & operator++()
|
|
||||||
{
|
|
||||||
_Inc();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//post increment
|
|
||||||
iterator operator++(int)
|
|
||||||
{
|
|
||||||
iterator old(*this);
|
|
||||||
_Inc();
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
const THashNode & operator * () const
|
|
||||||
{
|
|
||||||
return *(*iter);
|
|
||||||
}
|
|
||||||
THashNode & operator * ()
|
|
||||||
{
|
|
||||||
return *(*iter);
|
|
||||||
}
|
|
||||||
const THashNode * operator ->() const
|
|
||||||
{
|
|
||||||
return (*iter);
|
|
||||||
}
|
|
||||||
THashNode * operator ->()
|
|
||||||
{
|
|
||||||
return (*iter);
|
|
||||||
}
|
|
||||||
bool operator ==(const iterator &where) const
|
|
||||||
{
|
|
||||||
if (where.hash == this->hash
|
|
||||||
&& where.end == this->end
|
|
||||||
&&
|
|
||||||
(this->end ||
|
|
||||||
((where.curbucket == this->curbucket)
|
|
||||||
&& (where.iter == iter))
|
|
||||||
))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool operator !=(const iterator &where) const
|
|
||||||
{
|
|
||||||
return !( (*this) == where );
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase()
|
|
||||||
{
|
|
||||||
if (end || !hash || curbucket < 0 || curbucket >= static_cast<int>(hash->m_numBuckets))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 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--;
|
|
||||||
|
|
||||||
// :TODO: Maybe refactor to a lower size if required
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void _Inc()
|
|
||||||
{
|
|
||||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
|
||||||
return;
|
|
||||||
if (curbucket < 0)
|
|
||||||
{
|
{
|
||||||
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
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_items++;
|
||||||
|
} else {
|
||||||
|
typename List<THashNode *>::iterator iter;
|
||||||
|
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
|
||||||
{
|
{
|
||||||
if (hash->m_Buckets[i])
|
if (Compare((*iter)->key, key) == 0)
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
//node does not exist
|
||||||
|
pNode = new THashNode(key, V());
|
||||||
|
m_Buckets[place]->push_back(pNode);
|
||||||
|
m_items++;
|
||||||
|
}
|
||||||
|
if (PercentUsed() > 0.75f)
|
||||||
|
_Refactor();
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
void _Refactor()
|
||||||
|
{
|
||||||
|
m_percentUsed = 0.0f;
|
||||||
|
if (!m_numBuckets)
|
||||||
|
{
|
||||||
|
m_numBuckets = _T_INIT_HASH_SIZE;
|
||||||
|
m_Buckets = new NodePtr[m_numBuckets];
|
||||||
|
for (size_t i=0; i<m_numBuckets; i++)
|
||||||
|
m_Buckets[i] = NULL;
|
||||||
|
} else {
|
||||||
|
size_t oldSize = m_numBuckets;
|
||||||
|
m_numBuckets *= 2;
|
||||||
|
typename List<THashNode *>::iterator iter;
|
||||||
|
size_t place;
|
||||||
|
THashNode *pHashNode;
|
||||||
|
NodePtr *temp = new NodePtr[m_numBuckets];
|
||||||
|
for (size_t i=0; i<m_numBuckets; i++)
|
||||||
|
temp[i] = NULL;
|
||||||
|
//look in old hash table
|
||||||
|
for (size_t i=0; i<oldSize; i++)
|
||||||
|
{
|
||||||
|
//does a bucket have anything?
|
||||||
|
if (m_Buckets[i])
|
||||||
{
|
{
|
||||||
iter = hash->m_Buckets[i]->begin();
|
//go through the list of items
|
||||||
if (iter == hash->m_Buckets[i]->end())
|
for (iter = m_Buckets[i]->begin(); iter != m_Buckets[i]->end(); iter++)
|
||||||
continue;
|
{
|
||||||
curbucket = i;
|
pHashNode = (*iter);
|
||||||
break;
|
//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 *>;
|
||||||
|
m_percentUsed += (1.0f / (float)m_numBuckets);
|
||||||
|
}
|
||||||
|
temp[place]->push_back(pHashNode);
|
||||||
|
}
|
||||||
|
//delete that bucket!
|
||||||
|
delete m_Buckets[i];
|
||||||
|
m_Buckets[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curbucket < 0)
|
//reassign bucket table
|
||||||
|
delete [] m_Buckets;
|
||||||
|
m_Buckets = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
friend class iterator;
|
||||||
|
friend class const_iterator;
|
||||||
|
class iterator
|
||||||
|
{
|
||||||
|
friend class THash;
|
||||||
|
public:
|
||||||
|
iterator() : curbucket(-1), hash(NULL), end(true)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
iterator(THash *h) : curbucket(-1), hash(h), end(false)
|
||||||
|
{
|
||||||
|
if (!h->m_Buckets)
|
||||||
end = true;
|
end = true;
|
||||||
} else {
|
else
|
||||||
if (iter != hash->m_Buckets[curbucket]->end())
|
_Inc();
|
||||||
iter++;
|
};
|
||||||
if (iter == hash->m_Buckets[curbucket]->end())
|
//pre increment
|
||||||
|
iterator & operator++()
|
||||||
|
{
|
||||||
|
_Inc();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//post increment
|
||||||
|
iterator operator++(int)
|
||||||
|
{
|
||||||
|
iterator old(*this);
|
||||||
|
_Inc();
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
const THashNode & operator * () const
|
||||||
|
{
|
||||||
|
return *(*iter);
|
||||||
|
}
|
||||||
|
THashNode & operator * ()
|
||||||
|
{
|
||||||
|
return *(*iter);
|
||||||
|
}
|
||||||
|
const THashNode * operator ->() const
|
||||||
|
{
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
THashNode * operator ->()
|
||||||
|
{
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
bool operator ==(const iterator &where) const
|
||||||
|
{
|
||||||
|
if (where.hash == this->hash
|
||||||
|
&& where.end == this->end
|
||||||
|
&&
|
||||||
|
(this->end ||
|
||||||
|
((where.curbucket == this->curbucket)
|
||||||
|
&& (where.iter == iter))
|
||||||
|
))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool operator !=(const iterator &where) const
|
||||||
|
{
|
||||||
|
return !( (*this) == where );
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase()
|
||||||
|
{
|
||||||
|
if (end || !hash || curbucket < 0 || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove this element and move to the next one
|
||||||
|
iterator tmp = *this;
|
||||||
|
++tmp;
|
||||||
|
delete (*iter);
|
||||||
|
hash->m_Buckets[curbucket]->erase(iter);
|
||||||
|
*this = tmp;
|
||||||
|
|
||||||
|
// :TODO: Maybe refactor to a lower size if required
|
||||||
|
|
||||||
|
m_items--;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void _Inc()
|
||||||
|
{
|
||||||
|
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||||
|
return;
|
||||||
|
if (curbucket < 0)
|
||||||
{
|
{
|
||||||
int oldbucket = curbucket;
|
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
||||||
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
|
||||||
{
|
{
|
||||||
if (hash->m_Buckets[i])
|
if (hash->m_Buckets[i])
|
||||||
{
|
{
|
||||||
|
@ -308,95 +290,95 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curbucket == oldbucket)
|
if (curbucket < 0)
|
||||||
end = true;
|
end = true;
|
||||||
}
|
} else {
|
||||||
}
|
if (iter != hash->m_Buckets[curbucket]->end())
|
||||||
}
|
iter++;
|
||||||
private:
|
if (iter == hash->m_Buckets[curbucket]->end())
|
||||||
int curbucket;
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
THash *hash;
|
|
||||||
bool end;
|
|
||||||
};
|
|
||||||
class const_iterator
|
|
||||||
{
|
|
||||||
friend class THash;
|
|
||||||
public:
|
|
||||||
const_iterator() : curbucket(-1), hash(NULL), end(true)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
const_iterator(const THash *h) : curbucket(-1), hash(h), end(false)
|
|
||||||
{
|
|
||||||
if (!h->m_Buckets)
|
|
||||||
end = true;
|
|
||||||
else
|
|
||||||
_Inc();
|
|
||||||
};
|
|
||||||
//pre increment
|
|
||||||
const_iterator & operator++()
|
|
||||||
{
|
|
||||||
_Inc();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//post increment
|
|
||||||
const_iterator operator++(int)
|
|
||||||
{
|
|
||||||
iterator old(*this);
|
|
||||||
_Inc();
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
const THashNode & operator * () const
|
|
||||||
{
|
|
||||||
return *(*iter);
|
|
||||||
}
|
|
||||||
const THashNode * operator ->() const
|
|
||||||
{
|
|
||||||
return (*iter);
|
|
||||||
}
|
|
||||||
bool operator ==(const const_iterator &where) const
|
|
||||||
{
|
|
||||||
if (where.hash == this->hash
|
|
||||||
&& where.end == this->end
|
|
||||||
&&
|
|
||||||
(this->end ||
|
|
||||||
((where.curbucket == this->curbucket)
|
|
||||||
&& (where.iter == iter))
|
|
||||||
))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool operator !=(const const_iterator &where) const
|
|
||||||
{
|
|
||||||
return !( (*this) == where );
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void _Inc()
|
|
||||||
{
|
|
||||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
|
||||||
return;
|
|
||||||
if (curbucket < 0)
|
|
||||||
{
|
|
||||||
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
|
||||||
{
|
|
||||||
if (hash->m_Buckets[i])
|
|
||||||
{
|
{
|
||||||
iter = hash->m_Buckets[i]->begin();
|
int oldbucket = curbucket;
|
||||||
if (iter == hash->m_Buckets[i]->end())
|
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
||||||
continue;
|
{
|
||||||
curbucket = i;
|
if (hash->m_Buckets[i])
|
||||||
break;
|
{
|
||||||
|
iter = hash->m_Buckets[i]->begin();
|
||||||
|
if (iter == hash->m_Buckets[i]->end())
|
||||||
|
continue;
|
||||||
|
curbucket = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (curbucket == oldbucket)
|
||||||
|
end = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curbucket < 0)
|
}
|
||||||
|
private:
|
||||||
|
int curbucket;
|
||||||
|
typename List<THashNode *>::iterator iter;
|
||||||
|
THash *hash;
|
||||||
|
bool end;
|
||||||
|
};
|
||||||
|
class const_iterator
|
||||||
|
{
|
||||||
|
friend class THash;
|
||||||
|
public:
|
||||||
|
const_iterator() : curbucket(-1), hash(NULL), end(true)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
const_iterator(const THash *h) : curbucket(-1), hash(h), end(false)
|
||||||
|
{
|
||||||
|
if (!h->m_Buckets)
|
||||||
end = true;
|
end = true;
|
||||||
} else {
|
else
|
||||||
if (iter != hash->m_Buckets[curbucket]->end())
|
_Inc();
|
||||||
iter++;
|
};
|
||||||
if (iter == hash->m_Buckets[curbucket]->end())
|
//pre increment
|
||||||
|
const_iterator & operator++()
|
||||||
|
{
|
||||||
|
_Inc();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//post increment
|
||||||
|
const_iterator operator++(int)
|
||||||
|
{
|
||||||
|
iterator old(*this);
|
||||||
|
_Inc();
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
const THashNode & operator * () const
|
||||||
|
{
|
||||||
|
return *(*iter);
|
||||||
|
}
|
||||||
|
const THashNode * operator ->() const
|
||||||
|
{
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
bool operator ==(const const_iterator &where) const
|
||||||
|
{
|
||||||
|
if (where.hash == this->hash
|
||||||
|
&& where.end == this->end
|
||||||
|
&&
|
||||||
|
(this->end ||
|
||||||
|
((where.curbucket == this->curbucket)
|
||||||
|
&& (where.iter == iter))
|
||||||
|
))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool operator !=(const const_iterator &where) const
|
||||||
|
{
|
||||||
|
return !( (*this) == where );
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void _Inc()
|
||||||
|
{
|
||||||
|
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||||
|
return;
|
||||||
|
if (curbucket < 0)
|
||||||
{
|
{
|
||||||
int oldbucket = curbucket;
|
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
||||||
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
|
||||||
{
|
{
|
||||||
if (hash->m_Buckets[i])
|
if (hash->m_Buckets[i])
|
||||||
{
|
{
|
||||||
|
@ -407,84 +389,103 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curbucket == oldbucket)
|
if (curbucket < 0)
|
||||||
end = true;
|
end = true;
|
||||||
|
} else {
|
||||||
|
if (iter != hash->m_Buckets[curbucket]->end())
|
||||||
|
iter++;
|
||||||
|
if (iter == hash->m_Buckets[curbucket]->end())
|
||||||
|
{
|
||||||
|
int oldbucket = curbucket;
|
||||||
|
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
||||||
|
{
|
||||||
|
if (hash->m_Buckets[i])
|
||||||
|
{
|
||||||
|
iter = hash->m_Buckets[i]->begin();
|
||||||
|
if (iter == hash->m_Buckets[i]->end())
|
||||||
|
continue;
|
||||||
|
curbucket = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (curbucket == oldbucket)
|
||||||
|
end = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
int curbucket;
|
||||||
|
typename List<THashNode *>::iterator iter;
|
||||||
|
const THash *hash;
|
||||||
|
bool end;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
iterator begin()
|
||||||
|
{
|
||||||
|
return iterator(this);
|
||||||
|
}
|
||||||
|
iterator end()
|
||||||
|
{
|
||||||
|
iterator iter;
|
||||||
|
iter.hash = this;
|
||||||
|
return iter;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
int curbucket;
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
const THash *hash;
|
|
||||||
bool end;
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
iterator begin()
|
|
||||||
{
|
|
||||||
return iterator(this);
|
|
||||||
}
|
|
||||||
iterator end()
|
|
||||||
{
|
|
||||||
iterator iter;
|
|
||||||
iter.hash = this;
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const
|
const_iterator begin() const
|
||||||
{
|
{
|
||||||
return const_iterator(this);
|
return const_iterator(this);
|
||||||
}
|
}
|
||||||
const_iterator end() const
|
const_iterator end() const
|
||||||
{
|
{
|
||||||
const_iterator iter;
|
const_iterator iter;
|
||||||
iter.hash = this;
|
iter.hash = this;
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
iterator find(const U & u) const
|
iterator find(const U & u) const
|
||||||
{
|
|
||||||
iterator b = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (iterator iter = b; iter != e; iter++)
|
|
||||||
{
|
{
|
||||||
if ( (*iter).key == u )
|
iterator b = begin();
|
||||||
return iter;
|
iterator e = end();
|
||||||
|
for (iterator iter = b; iter != e; iter++)
|
||||||
|
{
|
||||||
|
if ( (*iter).key == u )
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
return end();
|
||||||
}
|
}
|
||||||
return end();
|
template <typename U>
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
iterator find(const U & u)
|
iterator find(const U & u)
|
||||||
{
|
|
||||||
iterator b = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (iterator iter = b; iter != e; iter++)
|
|
||||||
{
|
{
|
||||||
if ( (*iter).key == u )
|
iterator b = begin();
|
||||||
return iter;
|
iterator e = end();
|
||||||
|
for (iterator iter = b; iter != e; iter++)
|
||||||
|
{
|
||||||
|
if ( (*iter).key == u )
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
return end();
|
||||||
}
|
}
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator erase(iterator where)
|
iterator erase(iterator where)
|
||||||
{
|
{
|
||||||
where.erase();
|
where.erase();
|
||||||
return where;
|
return where;
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void erase(const U & u)
|
void erase(const U & u)
|
||||||
{
|
{
|
||||||
iterator iter = find(u);
|
iterator iter = find(u);
|
||||||
if (iter == end())
|
if (iter == end())
|
||||||
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_items;
|
||||||
};
|
};
|
||||||
//};
|
//};
|
||||||
|
|
||||||
#endif //_INCLUDE_SH_TINYHASH_H_
|
#endif //_INCLUDE_SH_TINYHASH_H_
|
||||||
|
|
Loading…
Reference in New Issue
Block a user