diff options
-rw-r--r-- | array.c | 15 | ||||
-rw-r--r-- | array.h | 4 | ||||
-rw-r--r-- | bowl.c | 5 | ||||
-rw-r--r-- | hash.c | 55 | ||||
-rw-r--r-- | hash.h | 4 | ||||
-rw-r--r-- | utils.c | 2 |
6 files changed, 71 insertions, 14 deletions
@@ -12,7 +12,7 @@ err_t array_malloc(struct bowl *self, size_t size) struct bowl_arr *arr = malloc(sizeof(struct bowl_arr)); CHECK(arr, MALLOC_FAILED) - arr->size = 2; + arr->size = size; arr->used = 0; struct bowl **ptr = calloc(sizeof(struct bowl *), arr->size); @@ -109,12 +109,21 @@ err_t array_free(struct bowl *self) struct bowl_arr *arr = self->_pl.array; CHECK(arr, INVALID_STATE) + err_t e; for(int i = 0; i < arr->used; i++) { - err_t e = bowl_free(arr->ptr[i]); + e = bowl_free(arr->ptr[i]); if(e) break; } free(arr->ptr); free(arr); + return e; +} + +err_t array_free_shallow(struct bowl_arr *arr) +{ + CHECK(arr, INVALID_STATE) + free(arr->ptr); + free(arr); return OK; -}
\ No newline at end of file +} @@ -21,7 +21,9 @@ err_t array_remove_key(struct bowl *, size_t, struct bowl **); err_t array_free(struct bowl *); +err_t array_free_shallow(struct bowl_arr *); + #ifdef __cplusplus } #endif -#endif // _ARRAY_H_
\ No newline at end of file +#endif // _ARRAY_H_ @@ -31,7 +31,7 @@ err_t bowl_malloc(struct bowl **ptr, bowl_t type) switch((*ptr)->type) { case LEAF: return OK; // No further allocation needed - case ARRAY: return array_malloc(*ptr, ARRAY_START_SIZE); + case ARRAY | HASH: return array_malloc(*ptr, ARRAY_START_SIZE); default: return INVALID_STATE; } @@ -139,7 +139,8 @@ err_t bowl_free(struct bowl *self) err_t e; switch(self->type) { case LEAF: e = data_free(self->_pl.data); break; - case ARRAY | HASH: e = array_free(self); break; + case ARRAY: e = array_free(self); break; + case HASH: e = hash_free(self); break; default: e = INVALID_STATE; break; } if(e) return e; @@ -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; +} @@ -7,5 +7,9 @@ err_t hash_insert_key(struct bowl *, char *key, struct bowl *); err_t hash_remove_key(struct bowl *, char *key, struct bowl **); +err_t hash_free(struct bowl *); + +err_t hash_free_shallow(struct bowl_arr *); + #endif // HASH_H_ @@ -49,7 +49,7 @@ err_t _array_remove(void **ptr, size_t idx, size_t len, void **out) err_t _hash(char *str, size_t len, size_t *out) { CHECK(str, INVALID_PARAMS) - CHECK((len < 0), INVALID_PARAMS) + CHECK((len > 0), INVALID_PARAMS) // Implements the "murmur" non-cryptographic hash |