aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-07-01 23:14:01 +0200
committerTom Smeding <tom.smeding@gmail.com>2020-07-01 23:14:42 +0200
commit548c540989527b45b9152f9f21ab8cf5e53893a6 (patch)
treeb86be0d5efbc6f5de1ce72e7c606bdfc7ff85719
parentf695f9046b5793796ebd703ad816f19637403473 (diff)
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.
-rw-r--r--TODO.txt1
-rw-r--r--hashtable.c23
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);
}