aboutsummaryrefslogtreecommitdiff
path: root/src/hashmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hashmap.c')
-rw-r--r--src/hashmap.c199
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;
}
+
+/**
+ * \}
+ */