74 Hashtable::Hashtable(
UINT32 (*hashFunc)(
void *),
SINT32 (*compareFunc)(
void *,
void *),
SINT32 capacity,
float loadFactor)
78 if (capacity < 0 || loadFactor <= 0)
88 m_table =
new Entry*[capacity];
89 for (
SINT32 i = 0; i < capacity; i++)
94 m_threshold = (
UINT32)(capacity * loadFactor);
97 m_loadFactor = loadFactor;
98 m_capacity = capacity;
101 m_hashFunc = hashFunc;
103 m_compareFunc = compareFunc;
107 Hashtable::~Hashtable()
111 for(
SINT32 index = 0; index < m_capacity; index++)
113 struct Entry *e,*next;
115 for(e = m_table[index]; e; e = next)
121 m_table[index] = NULL;
131 m_compareFunc = NULL;
147 bool Hashtable::isEmpty()
159 bool Hashtable::containsKey(
void *key)
161 return getHashEntry(key) ? true :
false;
171 void *Hashtable::getValue(
void *key)
173 struct Entry *e = getHashEntry(key);
192 void* Hashtable::put(
void *key,
void *value)
196 if (!key || !value || !m_table)
201 struct Entry *oldEntry = NULL;
202 struct Entry *newEntry = NULL;
203 UINT32 hash = m_hashFunc(key);
204 UINT32 index = hash % m_capacity;
207 if (m_count >= m_threshold)
212 index = hash % m_capacity;
214 newEntry =
new Entry;
215 newEntry->
e_Key = key;
219 oldEntry = m_table[index];
222 m_table[index] = newEntry;
226 struct Entry *prevEntry = NULL;
227 for(; oldEntry; oldEntry = oldEntry->
e_Next)
229 if (m_hashFunc(oldEntry->
e_Key) == hash && !m_compareFunc(oldEntry->
e_Key,key))
235 prevEntry = oldEntry;
239 prevEntry->
e_Next = newEntry;
243 m_table[index] = newEntry;
261 void *Hashtable::remove(
void *key)
265 if (!key || !m_table)
270 struct Entry *e,*prev;
271 UINT32 hash = m_hashFunc(key);
273 for(e = m_table[hash % m_capacity], prev = NULL; e; e = e->
e_Next)
275 if (m_hashFunc(e->
e_Key) == hash && !m_compareFunc(e->
e_Key,key))
286 m_table[hash % m_capacity] = e->
e_Next;
306 void Hashtable::clear(
SINT8 keyMode,
SINT8 valueMode)
315 for(
SINT32 index = 0; index < m_capacity; index++)
317 struct Entry *e,*next;
319 for(e = m_table[index]; e; e = next)
323 case HASH_EMPTY_DELETE:
337 case HASH_EMPTY_DELETE:
353 m_table[index] = NULL;
360 UINT32 Hashtable::getSize()
365 UINT32 Hashtable::getCapacity()
376 bool Hashtable::rehash()
385 UINT32 (*hashCode)(
void *) = m_hashFunc;
386 struct Entry **oldtable = m_table,**newtable;
387 SINT32 oldCapacity = m_capacity;
390 newCapacity = oldCapacity * 2 + 1;
391 newtable =
new Entry*[newCapacity];
392 for (
UINT32 i = 0; i < newCapacity; i++)
400 CAMsg::printMsg(LOG_INFO,
"Hashtable: Too many rehash operations! Please adapt hashtable capacity to at least %d.\n", newCapacity);
403 m_threshold = (
UINT32)(newCapacity * m_loadFactor);
405 m_capacity = newCapacity;
407 for(
SINT32 i = 0; i < oldCapacity; i++)
409 struct Entry *nextEntry, *e = NULL;
412 for (nextEntry = oldtable[i]; nextEntry;)
416 nextEntry = nextEntry->
e_Next;
418 index = hashCode(e->
e_Key) % newCapacity;
422 e->
e_Next = newtable[index];
442 struct Entry *Hashtable::getHashEntry(
void *key)
444 if (!key || !m_table)
450 UINT32 hash = m_hashFunc(key);
452 for(e = m_table[hash % m_capacity]; e; e = e->
e_Next)
454 if (m_hashFunc(e->
e_Key) == hash && !m_compareFunc(e->
e_Key,key))
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.