Program Listing for File Hashmap.h
↰ Return to documentation for file (Utils/Hashmap.h)
#ifndef __HASHMAP_H__
#define __HASHMAP_H__
#include "Common/Common.h"
#include <map>
#include <stdlib.h>
namespace Utilities
{
template<class KeyType>
inline unsigned int hashFunction(const KeyType &key)
{
return 0u;
}
template <class KeyType, class ValueType>
class Hashmap
{
public:
typedef typename std::map<unsigned int, ValueType> KeyValueMap;
private:
KeyValueMap **m_hashMap;
unsigned int m_bucketCount;
unsigned int m_moduloValue;
protected:
FORCE_INLINE void init()
{
m_hashMap = new KeyValueMap*[m_bucketCount];
for (unsigned int i=0; i < m_bucketCount; i++)
{
m_hashMap[i] = NULL;
}
}
FORCE_INLINE void cleanup()
{
if (m_hashMap)
{
for (unsigned int i=0; i < m_bucketCount; i++)
{
if (m_hashMap[i] != NULL)
{
m_hashMap[i]->clear();
delete m_hashMap[i];
}
}
delete [] m_hashMap;
m_hashMap = NULL;
}
}
public:
FORCE_INLINE Hashmap(const unsigned int bucketCount)
{
// Use a bucket count of 2^n => faster modulo
unsigned int val = bucketCount;
unsigned int powerOfTwo = 1u;
while(powerOfTwo < val)
powerOfTwo <<= 1;
m_bucketCount = powerOfTwo;
m_moduloValue = m_bucketCount-1u;
init();
}
~Hashmap()
{
cleanup();
}
FORCE_INLINE void clear()
{
cleanup();
init();
}
FORCE_INLINE KeyValueMap* getKeyValueMap(const unsigned int index)
{
return m_hashMap[index];
}
FORCE_INLINE void reset()
{
for (unsigned int i=0; i < m_bucketCount; i++)
{
if (m_hashMap[i] != NULL)
{
m_hashMap[i]->clear();
}
}
}
FORCE_INLINE unsigned int bucket_count() const
{
return m_bucketCount;
}
FORCE_INLINE ValueType* find(const KeyType &key)
{
const unsigned int hashValue = hashFunction<KeyType>(key);
const unsigned int mapIndex = hashValue & m_moduloValue;
if (m_hashMap[mapIndex] != NULL)
{
typename KeyValueMap::iterator &iter = (*m_hashMap[mapIndex]).find(hashValue);
if (iter != (*m_hashMap[mapIndex]).end())
return &iter->second;
}
return NULL;
}
FORCE_INLINE void insert(const KeyType &key, const ValueType& value)
{
const unsigned int hashValue = hashFunction<KeyType>(key);
const unsigned int mapIndex = hashValue & m_moduloValue;
if (m_hashMap[mapIndex] == NULL)
{
m_hashMap[mapIndex] = new KeyValueMap();
}
(*m_hashMap[mapIndex])[hashValue] = value;
}
FORCE_INLINE void remove(const KeyType &key)
{
const unsigned int hashValue = hashFunction<KeyType>(key);
const unsigned int mapIndex = hashValue & m_moduloValue;
if (m_hashMap[mapIndex] != NULL)
{
m_hashMap[mapIndex]->erase(hashValue);
if (m_hashMap[mapIndex]->size() == 0)
{
delete m_hashMap[mapIndex];
m_hashMap[mapIndex] = NULL;
}
}
}
FORCE_INLINE ValueType& operator[](const KeyType &key)
{
const int hashValue = hashFunction<KeyType>(key);
const unsigned int mapIndex = hashValue & m_moduloValue;
if (m_hashMap[mapIndex] == NULL)
{
m_hashMap[mapIndex] = new KeyValueMap();
}
return (*m_hashMap[mapIndex])[hashValue];
}
FORCE_INLINE const ValueType& operator[](const KeyType &key) const
{
const unsigned int hashValue = hashFunction<KeyType>(key, m_bucketCount);
const unsigned int mapIndex = hashValue & m_moduloValue;
if (m_hashMap[mapIndex] == NULL)
{
m_hashMap[mapIndex] = new KeyValueMap();
}
return (*m_hashMap[mapIndex])[hashValue];
}
FORCE_INLINE const ValueType* query(const KeyType &key) const
{
const unsigned int hashValue = hashFunction<KeyType>(key);
const unsigned int mapIndex = hashValue & m_moduloValue;
if (m_hashMap[mapIndex] == NULL)
{
return NULL;
}
typename KeyValueMap::iterator &it = m_hashMap[mapIndex]->find(hashValue);
if (it != m_hashMap[mapIndex]->end())
return &it->second;
return NULL;
}
FORCE_INLINE ValueType* query(const KeyType &key)
{
const unsigned int hashValue = hashFunction<KeyType>(key);
const unsigned int mapIndex = hashValue & m_moduloValue;
if (m_hashMap[mapIndex] == NULL)
{
return NULL;
}
const typename KeyValueMap::iterator &it = m_hashMap[mapIndex]->find(hashValue);
if (it != m_hashMap[mapIndex]->end())
return &it->second;
return NULL;
}
};
}
#endif