aboutsummaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2019-07-14 18:41:07 +0100
committerKatharina Fey <kookie@spacekookie.de>2019-07-14 18:47:18 +0100
commitf6e83e64abbf76bbfddc90f885f7c3be379ecf2c (patch)
tree726ff7b647e7cd1704b30638d8adf73c50a15dfe /hash.c
parent98852464c7d4cd3a6a08d0208378506fdce822d6 (diff)
Various improvements around HASH nodes
The example previously would lead to corrupt memory when running for items that needed to re-hash the hash array. This has been fixed. Secondly, all HASH node memory leaks are now fixed, that resulted from badly tracking objects through the resize process. A new function `hash_free_shallow` was added to help with this. The function `array_free_shallow` is unused but might become useful in the future and so was not removed. The hash strategy is still garbage but this can be fixed later :)
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/hash.c b/hash.c
index 5ee4f90..f1abfb3 100644
--- a/hash.c
+++ b/hash.c
@@ -26,9 +26,9 @@ err_t hash_insert_key(struct bowl *self, char *key, struct bowl *child)
// If the index is used, rescale and try again
if(arr->ptr[idx] != NULL) {
- struct bowl *prev = self;
+ struct bowl_arr *prev = arr;
- // Allocate new array
+ // Allocate new hash array
e = array_malloc(self, arr->size * 2);
if(e) return e;
@@ -41,12 +41,11 @@ err_t hash_insert_key(struct bowl *self, char *key, struct bowl *child)
}
}
- e = array_free(prev);
- if(e) return e;
-
e = hash_insert_key(self, key, child);
if(e) return e;
+ hash_free_shallow(prev);
+
} else {
hash_item *item = malloc(sizeof(hash_item));
CHECK(item, MALLOC_FAILED)
@@ -58,6 +57,7 @@ err_t hash_insert_key(struct bowl *self, char *key, struct bowl *child)
item->data = child;
arr->ptr[idx] = (struct bowl*) item;
+ arr->used += 1;
}
return OK;
@@ -65,7 +65,6 @@ err_t hash_insert_key(struct bowl *self, char *key, struct bowl *child)
err_t hash_remove_key(struct bowl *self, char *key, struct bowl **child)
{
-
CHECK(self, INVALID_STATE)
CHECK(child, INVALID_STATE)
CHECK(key, INVALID_STATE)
@@ -79,7 +78,49 @@ err_t hash_remove_key(struct bowl *self, char *key, struct bowl **child)
if(e) return e;
(*child) = arr->ptr[idx];
+ arr->used -= 1;
arr->ptr[idx] = NULL;
return OK;
}
-
+
+err_t hash_free(struct bowl *self)
+{
+ CHECK(self, INVALID_PARAMS)
+ struct bowl_arr *arr = self->_pl.array;
+ CHECK(arr, INVALID_PARAMS)
+
+ err_t e = OK;
+ for(int i = 0; i < arr->size; i++) {
+ hash_item *item = (hash_item *) arr->ptr[i];
+ if(item != NULL) {
+ CHECK(item->data, INVALID_STATE)
+ CHECK(item->key, INVALID_STATE)
+
+ e = bowl_free(item->data);
+ if(e) break;
+
+ free(item->key);
+ free(item);
+ }
+ }
+
+ free(arr->ptr);
+ free(arr);
+ return e;
+}
+
+err_t hash_free_shallow(struct bowl_arr *arr)
+{
+ CHECK(arr, INVALID_PARAMS);
+ for(int i = 0; i < arr->size; i++) {
+ hash_item *item = (hash_item *) arr->ptr[i];
+ if(item != NULL) {
+ free(item->key);
+ free(item);
+ }
+ }
+
+ free(arr->ptr);
+ free(arr);
+ return OK;
+}