diff --git a/lib/types/hashtable.c b/lib/types/hashtable.c index a55e4478aa5f42bc688bc2ac615b4f10aa51e2cf..00803b3bd95a8729cc033fbab4315121a1348ae6 100644 --- a/lib/types/hashtable.c +++ b/lib/types/hashtable.c @@ -1,3 +1,4 @@ +#include "array.h" #include "hashtable.h" #include "mem.h" @@ -19,10 +20,20 @@ typedef struct */ struct _HashTable { - SList **array; - size_t size; + Array **buckets; + size_t size; }; +static void +key_value_free (void *element) +{ + KeyValue *kv = (KeyValue *) element; + + free (kv->key); + free (kv->value); + free (kv); +} + /** * hash_table_new: * @size: Number of buckets to use. @@ -32,23 +43,23 @@ struct _HashTable HashTable * hash_table_new (size_t size) { - HashTable *new = malloc (sizeof (HashTable)); - new->array = calloc (size, sizeof (SList *)); - new->size = size; + HashTable *new = malloc (sizeof (HashTable)); + new->buckets = calloc (size, sizeof (Array *)); + new->size = size; - return new; + return new; } static unsigned strhash (const char *string) { - unsigned h = 5381; - char c; + unsigned h = 5381; + char c; - while ((c = *string++)) - h = (h << 5) + h + c; + while ((c = *string++)) + h = (h << 5) + h + c; - return h; + return h; } /** @@ -66,14 +77,17 @@ hash_table_insert (HashTable *table, const char *key, const char *value) { - unsigned index = strhash (key) % table->size; + unsigned index = strhash (key) % table->size; KeyValue *kv = check_malloc (sizeof (KeyValue)); kv->key = strdup (key); kv->value = strdup (value); - SList *list = slist_prepend (table->array[index], kv); - table->array[index] = list; + // Only create array if needed + if (!table->buckets[index]) + table->buckets[index] = array_new (key_value_free); + + array_add (table->buckets[index], kv); } /** @@ -86,16 +100,19 @@ hash_table_insert (HashTable *table, void hash_table_print_all (HashTable *table) { - for (size_t i = 0; i < table->size; i++) - { - SList *bucket = table->array[i]; - if (bucket == NULL) - continue; - - for (SList *list = bucket; list; list = list->next) - { - KeyValue *kv = list->data; - printf ("%s:%s\n", kv->key, kv->value); - } - } + for (size_t i = 0; i < table->size; i++) + { + Array *bucket = table->buckets[i]; + + if (!bucket) + continue; + + size_t length = array_get_length (bucket); + + for (size_t j = 0; j < length; j++) + { + KeyValue *kv = (KeyValue *) array_get (bucket, j); + printf ("%s:%s\n", kv->key, kv->value); + } + } } diff --git a/lib/types/hashtable.h b/lib/types/hashtable.h index 03d02f480f65d28130979fa680faeb7eaee4e50c..d2b9e92d1ce5bdf8af8ae1b3b1a875704e9fd74a 100644 --- a/lib/types/hashtable.h +++ b/lib/types/hashtable.h @@ -2,8 +2,6 @@ #include <stddef.h> -#include "slist.h" - typedef struct _HashTable HashTable; HashTable * hash_table_new (size_t size);