summaryrefslogtreecommitdiffstats
path: root/src/hashtable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hashtable.c')
-rw-r--r--src/hashtable.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/src/hashtable.c b/src/hashtable.c
index 08ff934..dd6dbfc 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -2,7 +2,7 @@
* hashtable.c
* really simple hash table implementation
*
- * Copyright (c) 2011 Nikias Bassen, All Rights Reserved.
+ * Copyright (c) 2011-2016 Nikias Bassen, All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,16 +20,17 @@
*/
#include "hashtable.h"
-hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func)
+hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func, free_func_t free_func)
{
hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t));
int i;
- for (i = 0; i < 256; i++) {
+ for (i = 0; i < 4096; i++) {
ht->entries[i] = NULL;
}
ht->count = 0;
ht->hash_func = hash_func;
ht->compare_func = compare_func;
+ ht->free_func = free_func;
return ht;
}
@@ -38,11 +39,13 @@ void hash_table_destroy(hashtable_t *ht)
if (!ht) return;
int i = 0;
- for (i = 0; i < 256; i++) {
+ for (i = 0; i < 4096; i++) {
if (ht->entries[i]) {
hashentry_t* e = ht->entries[i];
while (e) {
- free(e->value);
+ if (ht->free_func) {
+ ht->free_func(e->value);
+ }
hashentry_t* old = e;
e = e->next;
free(old);
@@ -58,7 +61,7 @@ void hash_table_insert(hashtable_t* ht, void *key, void *value)
unsigned int hash = ht->hash_func(key);
- int idx0 = hash & 0xFF;
+ int idx0 = hash & 0xFFF;
// get the idx0 list
hashentry_t* e = ht->entries[idx0];
@@ -93,7 +96,7 @@ void* hash_table_lookup(hashtable_t* ht, void *key)
if (!ht || !key) return NULL;
unsigned int hash = ht->hash_func(key);
- int idx0 = hash & 0xFF;
+ int idx0 = hash & 0xFFF;
hashentry_t* e = ht->entries[idx0];
while (e) {
@@ -104,3 +107,34 @@ void* hash_table_lookup(hashtable_t* ht, void *key)
}
return NULL;
}
+
+void hash_table_remove(hashtable_t* ht, void *key)
+{
+ if (!ht || !key) return;
+
+ unsigned int hash = ht->hash_func(key);
+
+ int idx0 = hash & 0xFFF;
+
+ // get the idx0 list
+ hashentry_t* e = ht->entries[idx0];
+ hashentry_t* last = e;
+ while (e) {
+ if (ht->compare_func(e->key, key)) {
+ // found element, remove it from the list
+ hashentry_t* old = e;
+ if (e == ht->entries[idx0]) {
+ ht->entries[idx0] = e->next;
+ } else {
+ last->next = e->next;
+ }
+ if (ht->free_func) {
+ ht->free_func(old->value);
+ }
+ free(old);
+ return;
+ }
+ last = e;
+ e = e->next;
+ }
+}