From 36350a57f4fe6a70f139c0cbb01984cc1692e353 Mon Sep 17 00:00:00 2001 From: Bruce Cowan <bruce.cowan@strath.ac.uk> Date: Sun, 22 Dec 2019 14:56:05 +0000 Subject: [PATCH] Change hashtable to use arrays rather than linked lists --- lib/types/hashtable.c | 69 +++++++++++++++++++++++++++---------------- lib/types/hashtable.h | 2 -- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/lib/types/hashtable.c b/lib/types/hashtable.c index a55e447..00803b3 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 03d02f4..d2b9e92 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); -- GitLab