#ifndef LIBDS_HT_HEADER #define LIBDS_HT_HEADER #define LIBDS_HT_SIZE 32 #include "libds.h" /** * A linked list node used for hash table buckets. * Contains a copy of the key that was used to store the * data as to avoid conflicting hash functions. */ struct ht_node_s { /** * A copy of the key used to store this node's data. */ void* key; /** * The data stored in this node. */ void* data; /** * The next linked list node with the same hash. */ struct ht_node_s* next; }; /** * A hash table struct. * The struct contains function pointers to all necessary * internal functions so that it can be customized to work with * any kind of data. By default, it works with strings. * * The copy function, which is intended to use malloc(), should return * NULL if the allocation failed - otherwise, there is no way for the * hash table to know something went wrong. */ struct ht_s { /** * The buckets in this hash table. */ struct ht_node_s* data[LIBDS_HT_SIZE]; /** * Hash function used to store data. * @param input the data being hashed. * @return the data's hash. */ unsigned long (*hash_func)(const void* input); /** * Function to compare two keys. * @param given_key the key being used to retrieve data * @param current_key the key of a hash table node * @return nonzero value if the keys match. */ int (*cmp_func)(const void* given_key, const void* current_key); /** * Function used to duplicate the given key and * store it in a node. * @param key the key to copy * @return pointer to a new key. */ void* (*copy_func)(const void* key); /** * Function used to free a previously copied key. * @param key the key to free. */ void (*free_func)(void* key); }; typedef struct ht_node_s ht_node; typedef struct ht_s ht; /** * The default hash function. * Uses FNV-1 hash, and assumes data is a string. * @param key the data to hash. * @return the produced hashed integer. */ unsigned long ht_default_hash_func(const void* key); /** * The default key comparison function. * Assumes both keys are strings and uses strcmp. * @param a the key to compare * @param b the key compared against * @return true if the keys represent the same string. */ int ht_default_cmp_func(const void* a, const void* b); /** * The default key copy function. * @param key the key being copied * @return a pointer to the copy of the key. */ void* ht_default_copy_func(const void* key); /** * The default key free function. Simply calls free() * @param key the key to free. */ void ht_default_free_func(void* key); /** * Initializes the hash table with default values. * @param ht the hash table to initialize. */ void ht_init(ht* ht); /** * Frees the hash table and its internally allocated nodes. * The data itself is left intact - use ht_foreach to free it * if it is no longer used. * @param ht the hash table to free. */ void ht_free(ht* ht); /** * Stores data into the hash table. Uses malloc for node allocation. * @param ht the hash table to store data into. * @param key the key to use to store the data. * @param value the value to store. * @return LIBDS_SUCCESS if all goes well, LIBDS_MALLOC if an allocation fails. */ libds_result ht_put(ht* ht, const void* key, void* value); /** * Retrieves a value from the hash table. * @param ht the hash table to retrieve a value from. * @param key the key to use to find the data. * @return the data, or NULL if it is not found. */ void* ht_get(const ht* ht, const void* key); /** * Retreives the first value from the hash table * that's stored with the given key and passes the compare function. * @param ht the hash table to retreive the value from. * @param key the key to use to find the data. * @param data the data to compare the candidate value to. * @param compare the comparison function used to compare adta. * @return the data, or NULL if it is not found. */ void* ht_find(const ht* ht, const void* key, void* data, compare_func compare); /** * Removes a value from the hash table. * @param ht the hash table to remove a value from. * @param key the key to use to find the data. */ void ht_remove(ht* ht, const void* key); /** * Runs through every element in the hash table, and compares it against the * given data using the given comparison function. If the comparison function returns * true, calls the foreach function, passing it the element and the variable argument list. * Stops if any foreach function returns a nonzero code. * @param ht the hash table to perform the operation on. * @param data the data passed to the comparison function. * @param compare the comparison function operating on the data and each element in the list. * @param foreach the foreach function called on every element that is matched by the comparison function. * @param ... variable arguments to be passed to the foreach function. * @return the code returned by the foreach functions. */ int ht_foreach(const ht* ht, void* data, compare_func compare, foreach_func foreach, ...); #endif