From 548c540989527b45b9152f9f21ab8cf5e53893a6 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 1 Jul 2020 23:14:01 +0200 Subject: Slight optimisation of ht_grow() The hashtable has been slightly integration-tested, but not rigorously -- even though the implementation is non-trivial enough that it could warrant testing. And it's a completely separate module, so eminently testable. Please test. --- TODO.txt | 1 + hashtable.c | 23 ++++++++--------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/TODO.txt b/TODO.txt index 1f09bca..be26784 100644 --- a/TODO.txt +++ b/TODO.txt @@ -5,3 +5,4 @@ - A session is marked inactive 2 minutes after the latest activity on that session. Make the number "2" configurable and not a hard-coded constant. - Use poll(2), not select(2) - Fix OOM dos vector +- Unit tests for hashtable diff --git a/hashtable.c b/hashtable.c index ea0f0fc..bfda316 100644 --- a/hashtable.c +++ b/hashtable.c @@ -32,13 +32,6 @@ struct hashtable { struct bucket *table; }; -static void ht_nullify(struct hashtable *ht) { - for (size_t i = 0; i < ht->modulus; i++) { - free(ht->table[i].pairs); // noop if values == NULL - } - free(ht->table); -} - static void ht_grow(struct hashtable *ht) { static bool nested_grow = false; @@ -58,8 +51,6 @@ static void ht_grow(struct hashtable *ht) { newht.num_values = 0; newht.table = calloc(newht.modulus, struct bucket); - debug("ht: growing from %zu to %zu", ht->modulus, newht.modulus); - for (size_t i = 0; i < ht->modulus; i++) { const struct bucket *bucket = &ht->table[i]; for (int j = 0; j < bucket->len; j++) { @@ -73,9 +64,12 @@ static void ht_grow(struct hashtable *ht) { // boolean. ht_insert(&newht, pair->key, pair->value); } + + free(bucket->pairs); // noop if pairs == NULL } - ht_nullify(ht); + free(ht->table); + *ht = newht; } @@ -89,15 +83,16 @@ struct hashtable* ht_alloc() { } void ht_free(struct hashtable *ht) { - ht_nullify(ht); + for (size_t i = 0; i < ht->modulus; i++) { + free(ht->table[i].pairs); // noop if pairs == NULL + } + free(ht->table); free(ht); } void ht_insert(struct hashtable *ht, unsigned int key, void *value) { struct bucket *bucket = &ht->table[key % ht->modulus]; - debug("ht: insert num_values=%zu key=%u bucket: cap=%d len=%d", ht->num_values, key, bucket->cap, bucket->len); - if (bucket->cap == 0) { bucket->cap = 1; bucket->pairs = malloc(bucket->cap, struct keyvalue); @@ -136,7 +131,6 @@ void ht_delete(struct hashtable *ht, unsigned int key) { struct bucket *bucket = &ht->table[key % ht->modulus]; for (int i = 0; i < bucket->len; i++) { if (bucket->pairs[i].key == key) { - debug("ht: delete key=%u bucket: cap=%d len=%d i=%d", key, bucket->cap, bucket->len, i); if (i < bucket->len - 1) { bucket->pairs[i] = bucket->pairs[bucket->len - 1]; } @@ -145,5 +139,4 @@ void ht_delete(struct hashtable *ht, unsigned int key) { return; } } - debug("ht: delete key=%u not found", key); } -- cgit v1.2.3-54-g00ecf