diff options
Diffstat (limited to 'src/hashmap.c')
| -rw-r--r-- | src/hashmap.c | 199 |
1 files changed, 191 insertions, 8 deletions
diff --git a/src/hashmap.c b/src/hashmap.c index c9fb315..256644a 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -2,6 +2,22 @@ #include <stdlib.h> #include <string.h> +/** + * \defgroup hashmap Hashmap + * + * Data stucture for storing pointers in the hashmap. + * \{ + */ + +/** + * Creates the new hashmap object. + * + * \param equal Comparision function + * \param hash Key hash function + * + * \return On success, returns the pointer to the new hashmap object. + * \return On failure, returns a null pointer. + */ bh_hashmap_t *bh_hashmap_new(bh_equal_cb_t equal, bh_hash_cb_t hash) { @@ -14,12 +30,26 @@ bh_hashmap_t *bh_hashmap_new(bh_equal_cb_t equal, return result; } +/** + * Frees the \a hashmap object. + * + * \param hashmap Pointer to the hashmap object to be freed + */ void bh_hashmap_free(bh_hashmap_t *hashmap) { bh_hashmap_destroy(hashmap); free(hashmap); } +/** + * Initializes the \a hashmap object. + * + * \warning This is an internal function. + * + * \param hashmap Pointer to the hashmap object to be initialized + * \param equal Comparision function + * \param hash Key hash function + */ void bh_hashmap_init(bh_hashmap_t *hashmap, bh_equal_cb_t equal, bh_hash_cb_t hash) @@ -30,6 +60,13 @@ void bh_hashmap_init(bh_hashmap_t *hashmap, hashmap->hash = hash; } +/** + * Destroys the \a hashmap object. + * + * \warning This is an internal function. + * + * \param hashmap Pointer to the hashmap object to be destroied + */ void bh_hashmap_destroy(bh_hashmap_t *hashmap) { if (hashmap->capacity) @@ -39,6 +76,11 @@ void bh_hashmap_destroy(bh_hashmap_t *hashmap) } } +/** + * Clears the \a hashmap object. + * + * \param hashmap Pointer to the hashmap object to be cleared + */ void bh_hashmap_clear(bh_hashmap_t *hashmap) { if (hashmap->capacity) @@ -46,8 +88,24 @@ void bh_hashmap_clear(bh_hashmap_t *hashmap) hashmap->size = 0; } +/** + * Reserves the space for \a size elements in the \a hashmap. + * + * This function can both expand and shrink the available space in \a hashmap. + * This function takes into account current hashmap load factor. + * + * \param hashmap Pointer to the hashmap object to be resized in terms of + * capacity + * \param size New capacity of the hashmap + * + * \note Calling this function will invalidate iterators. + * \note Actual hashmap capacity can be bigger then requested. + * + * \return On success, returns zero value. + * \return On failure, returns error code. + */ int bh_hashmap_reserve(bh_hashmap_t *hashmap, - size_t size) + size_t size) { bh_hashmap_t other; size_t capacity, max_capacity, threshold; @@ -78,7 +136,7 @@ int bh_hashmap_reserve(bh_hashmap_t *hashmap, /* Capacity can't be bigger than max capacity and overflow */ if (capacity > max_capacity || capacity < 16) - return -1; + return BH_OOM; } } else @@ -93,7 +151,7 @@ int bh_hashmap_reserve(bh_hashmap_t *hashmap, /* Prevent same size reallocation */ if (capacity == hashmap->capacity) - return 0; + return BH_OK; /* Initialize new hashmap */ bh_hashmap_init(&other, hashmap->equal, hashmap->hash); @@ -105,7 +163,6 @@ int bh_hashmap_reserve(bh_hashmap_t *hashmap, /* Allocate new memory for the hashmap */ other.data = malloc(sizeof(*other.data) * capacity); - other.psls = malloc(sizeof(size_t) * capacity); other.threshold = threshold; other.capacity = capacity; @@ -117,7 +174,7 @@ int bh_hashmap_reserve(bh_hashmap_t *hashmap, free(other.data); if (other.psls) free(other.psls); - return -1; + return BH_OOM; } /* Reset probe sequence lengths */ @@ -140,9 +197,22 @@ int bh_hashmap_reserve(bh_hashmap_t *hashmap, /* Swap hashmaps */ bh_hashmap_destroy(hashmap); *hashmap = other; - return 0; + return BH_OK; } +/** + * Inserts the pair of \a key and \a value into the \a hashmap. This function + * allows duplicates to be inserted. + * + * \param hashmap Pointer to the hashmap object + * \param key Key to be inserted + * \param value Value to be inserted + * + * \note Calling this function will invalidate iterators. + * + * \return On success, returns zero value. + * \return On failure, returns error code. + */ int bh_hashmap_insert(bh_hashmap_t *hashmap, void *key, void *value) @@ -154,7 +224,7 @@ int bh_hashmap_insert(bh_hashmap_t *hashmap, if (hashmap->size + 1 > hashmap->threshold) if (bh_hashmap_reserve(hashmap, hashmap->size + 1)) if (hashmap->size >= hashmap->capacity) - return -1; + return BH_OOM; /* Prepare inserted data and set PSL to 1 */ item.key = key; @@ -187,9 +257,19 @@ int bh_hashmap_insert(bh_hashmap_t *hashmap, hashmap->psls[bucket] = psl; hashmap->size++; - return 0; + return BH_OK; } +/** + * Removes value from the \a hashmap by \a key. + * + * \param hashmap Pointer to the hashmap object + * \param key Key value + * + * \note Calling this function will invalidate iterators. + * \note If hashmap contains several key-value pairs with the same key, only + * one pair will be removed. + */ void bh_hashmap_remove(bh_hashmap_t *hashmap, void *key) { @@ -200,6 +280,19 @@ void bh_hashmap_remove(bh_hashmap_t *hashmap, bh_hashmap_iter_remove(hashmap, iter); } +/** + * Returns the value from the \a hashmap by the specified \a key. + * + * If the \a exists is not null pointer, the value will be stored to indicated, + * whether the \a key exists in the hashmap or not. + * + * \param hashmap Pointer to the hashmap object + * \param key Key value + * \param exists Pointer to the exists flag variable (optional) + * + * \return On success, returns value. + * \return On failure, return null pointer. + */ void *bh_hashmap_at(bh_hashmap_t *hashmap, void *key, int *exists) @@ -221,36 +314,87 @@ void *bh_hashmap_at(bh_hashmap_t *hashmap, return NULL; } +/** + * Checks if the \a hashmap is empty. + * + * \param hashmap Pointer to the hashmap object + * + * \return If hashmap is empty, returns non-zero value + * \return If hashmap is not empty, returns zero value + */ int bh_hashmap_empty(bh_hashmap_t *hashmap) { return !hashmap->size; } +/** + * Returns the size of the \a hashmap. + * + * \param hashmap Pointer to the hashmap object + * + * \return Returns the size of the hashmap. + */ size_t bh_hashmap_size(bh_hashmap_t *hashmap) { return hashmap->size; } +/** + * Returns the capacity of the \a hashmap. + * + * \param hashmap Pointer to the hashmap object + * + * \return Returns the capacity of the hashmap. + */ size_t bh_hashmap_capacity(bh_hashmap_t *hashmap) { return hashmap->capacity; } +/** + * Returns the load factor of the \a hashmap. + * + * \param hashmap Pointer to the hashmap object + * + * \return Returns the load factor of the hashmap. + */ float bh_hashmap_factor(bh_hashmap_t *hashmap) { return hashmap->factor; } +/** + * Sets the load \a factor of the \a hashmap. + * + * \param hashmap Pointer to the hashmap object + * \param factor Load factor value + * + * \note New load factor will be applied on the next reserve/insert operation. + */ void bh_hashmap_set_factor(bh_hashmap_t *hashmap, float factor) { + /* Limit the factor value to [0.15, 1.0] */ factor = (factor > 1.0f) ? (1.0f) : (factor); factor = (factor < 0.15f) ? (0.15f) : (factor); + /* Calculate new threshold value */ hashmap->factor = factor; hashmap->threshold = hashmap->capacity * factor; } +/** + * Returns the iterator to the element in the \a hashmap with specified \a key. + * + * \param hashmap Pointer to the hashmap object + * \param iter Opaque iterator value + * + * \return On success, returns iterator value. + * \return On failure, returns null pointer. + * + * \note If hashmap contains several key-value pairs with the same key, only + * iterator to the one of the pairs will returned. + */ void *bh_hashmap_iter_at(bh_hashmap_t *hashmap, void *key) { @@ -278,6 +422,19 @@ void *bh_hashmap_iter_at(bh_hashmap_t *hashmap, return NULL; } +/** + * Returns the iterator to the next element in the \a hashmap. + * + * \param hashmap Pointer to the hashmap object + * \param iter Opaque iterator value + * + * \return If the \a iter doesn't point to the last element of the hashmap, + * returns next iterator value. + * \return If the \a iter point to the last element of the hashmap, returns + * null pointer. + * \return If the \a iter is the null pointer, returns iterator to the + * first element of the hashmap. + */ void *bh_hashmap_iter_next(bh_hashmap_t *hashmap, void *iter) { @@ -302,6 +459,14 @@ void *bh_hashmap_iter_next(bh_hashmap_t *hashmap, } } +/** + * Removes value from the \a hashmap by iterator \a iter. + * + * \param hashmap Pointer to the hashmap object + * \param iter Iterator value + * + * \note Calling this function will invalidate iterators. + */ void bh_hashmap_iter_remove(bh_hashmap_t *hashmap, void *iter) { @@ -332,12 +497,30 @@ void bh_hashmap_iter_remove(bh_hashmap_t *hashmap, hashmap->psls[bucket] = 0; } +/** + * Returns the key, pointed by the hashmap iterator \a iter. + * + * \param iter Opaque iterator value + * + * \return Returns key, pointed by iterator. + */ void *bh_hashmap_iter_key(void *iter) { return ((bh_hashmap_node_t *)iter)->key; } +/** + * Returns the value, pointed by the hashmap iterator \a iter. + * + * \param iter Opaque iterator value + * + * \return Returns value, pointed by iterator. + */ void *bh_hashmap_iter_value(void *iter) { return ((bh_hashmap_node_t *)iter)->value; } + +/** + * \} + */ |
