summaryrefslogtreecommitdiffstats
path: root/utils/hashtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hashtable.h')
-rwxr-xr-xutils/hashtable.h451
1 files changed, 451 insertions, 0 deletions
diff --git a/utils/hashtable.h b/utils/hashtable.h
new file mode 100755
index 0000000..66f9fbf
--- /dev/null
+++ b/utils/hashtable.h
@@ -0,0 +1,451 @@
+/******************************************************************
+* $Id: hashtable.h,v 1.1 2004/10/29 09:28:25 snowdrop Exp $
+*
+* CSOAP Project: A http client/server library in C
+* Copyright (C) 2003-2004 Ferhat Ayaz
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Email: ferhatayaz@yahoo.com
+******************************************************************/
+#ifndef UTILS_HASHTABLE_H
+#define UTILS_HASHTABLE_H
+
+/* These structs should not be accessed directly from user code.
+ * All access should be via the public functions declared below. */
+
+typedef struct _hashpair {
+ const void *key;
+ void *value;
+ struct _hashpair *next;
+} hashpair_t;
+
+typedef struct {
+ long numOfBuckets;
+ long numOfElements;
+ hashpair_t **bucketArray;
+ float idealRatio, lowerRehashThreshold, upperRehashThreshold;
+ int (*keycmp)(const void *key1, const void *key2);
+ int (*valuecmp)(const void *value1, const void *value2);
+ unsigned long (*hashFunction)(const void *key);
+ void (*keyDeallocator)(void *key);
+ void (*valueDeallocator)(void *value);
+} hashtable_t;
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_create() - creates a new HashTable
+ * DESCRIPTION:
+ * Creates a new HashTable. When finished with this HashTable, it
+ * should be explicitly destroyed by calling the hashtable_destroy()
+ * function.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * numOfBuckets - the number of buckets to start the HashTable out with.
+ * Must be greater than zero, and should be prime.
+ * Ideally, the number of buckets should between 1/5
+ * and 1 times the expected number of elements in the
+ * HashTable. Values much more or less than this will
+ * result in wasted memory or decreased performance
+ * respectively. The number of buckets in a HashTable
+ * can be re-calculated to an appropriate number by
+ * calling the hashtable_rehash() function once the
+ * HashTable has been populated. The number of buckets
+ * in a HashTable may also be re-calculated
+ * automatically if the ratio of elements to buckets
+ * passes the thresholds set by hashtable_set_ideal_ration().
+ * RETURNS:
+ * HashTable - a new Hashtable, or NULL on error
+\*--------------------------------------------------------------------------*/
+
+hashtable_t *hashtable_create(long numOfBuckets);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_destroy() - destroys an existing HashTable
+ * DESCRIPTION:
+ * Destroys an existing HashTable.
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to destroy
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_destroy(hashtable_t *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_contains_key() - checks the existence of a key in a HashTable
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains the
+ * specified key. Uses the comparison function specified by
+ * hashtable_set_key_comparision_function().
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * key - the key to search for
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains the
+ * specified key.
+\*--------------------------------------------------------------------------*/
+
+int hashtable_contains_key(const hashtable_t *hashTable, const void *key);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_contains_value()
+ * - checks the existence of a value in a HashTable
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains the
+ * specified value. Unlike hashtable_contains_key(), this function is
+ * not very efficient, since it has to scan linearly looking for a
+ * match. Uses the comparison function specified by
+ * hashtable_set_value_comparision_function().
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * value - the value to search for
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains the
+ * specified value.
+\*--------------------------------------------------------------------------*/
+
+int hashtable_contains_value(const hashtable_t *hashTable, const void *value);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_put() - adds a key/value pair to a HashTable
+ * DESCRIPTION:
+ * Adds the specified key/value pair to the specified HashTable. If
+ * the key already exists in the HashTable (determined by the comparison
+ * function specified by hashtable_set_key_comparision_function()), its value
+ * is replaced by the new value. May trigger an auto-rehash (see
+ * hashtable_set_ideal_ration()). It is illegal to specify NULL as the
+ * key or value.
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to add to
+ * key - the key to add or whose value to replace
+ * value - the value associated with the key
+ * RETURNS:
+ * err - 0 if successful, -1 if an error was encountered
+\*--------------------------------------------------------------------------*/
+
+int hashtable_put(hashtable_t *hashTable, const void *key, void *value);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_get() - retrieves the value of a key in a HashTable
+ * DESCRIPTION:
+ * Retrieves the value of the specified key in the specified HashTable.
+ * Uses the comparison function specified by
+ * hashtable_set_key_comparision_function().
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * key - the key whose value is desired
+ * RETURNS:
+ * void * - the value of the specified key, or NULL if the key
+ * doesn't exist in the HashTable
+\*--------------------------------------------------------------------------*/
+
+void *hashtable_get(const hashtable_t *hashTable, const void *key);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_remove() - removes a key/value pair from a HashTable
+ * DESCRIPTION:
+ * Removes the key/value pair identified by the specified key from the
+ * specified HashTable if the key exists in the HashTable. May trigger
+ * an auto-rehash (see hashtable_set_ideal_ration()).
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to remove the key/value pair from
+ * key - the key specifying the key/value pair to be removed
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_remove(hashtable_t *hashTable, const void *key);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_remove_all() - removes all key/value pairs from a HashTable
+ * DESCRIPTION:
+ * Removes all key/value pairs from the specified HashTable. May trigger
+ * an auto-rehash (see hashtable_set_ideal_ration()).
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to remove all key/value pairs from
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_remove_all(hashtable_t *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_is_empty() - determines if a HashTable is empty
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains any
+ * key/value pairs.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable to check
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains any
+ * key/value pairs
+\*--------------------------------------------------------------------------*/
+
+int hashtable_is_empty(const hashtable_t *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_size() - returns the number of elements in a HashTable
+ * DESCRIPTION:
+ * Returns the number of key/value pairs that are present in the
+ * specified HashTable.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable whose size is requested
+ * RETURNS:
+ * long - the number of key/value pairs that are present in
+ * the specified HashTable
+\*--------------------------------------------------------------------------*/
+
+long hashtable_size(const hashtable_t *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_getNumBuckets() - returns the number of buckets in a HashTable
+ * DESCRIPTION:
+ * Returns the number of buckets that are in the specified HashTable.
+ * This may change dynamically throughout the life of a HashTable if
+ * automatic or manual rehashing is performed.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable whose number of buckets is requested
+ * RETURNS:
+ * long - the number of buckets that are in the specified
+ * HashTable
+\*--------------------------------------------------------------------------*/
+
+long hashtable_get_num_buckets(const hashtable_t *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_set_key_comparision_function()
+ * - specifies the function used to compare keys in a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to compare keys in the specified
+ * HashTable. The specified function should return zero if the two
+ * keys are considered equal, and non-zero otherwise. The default
+ * function is one that simply compares pointers.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose key comparison function is being
+ * specified
+ * keycmp - a function which returns zero if the two arguments
+ * passed to it are considered "equal" keys and non-zero
+ * otherwise
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_set_key_comparision_function(hashtable_t *hashTable,
+ int (*keycmp)(const void *key1, const void *key2));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_set_value_comparision_function()
+ * - specifies the function used to compare values in a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to compare values in the specified
+ * HashTable. The specified function should return zero if the two
+ * values are considered equal, and non-zero otherwise. The default
+ * function is one that simply compares pointers.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose value comparison function is being
+ * specified
+ * valuecmp - a function which returns zero if the two arguments
+ * passed to it are considered "equal" values and non-zero
+ * otherwise
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_set_value_comparision_function(hashtable_t *hashTable,
+ int (*valuecmp)(const void *value1, const void *value2));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_set_hashfunction()
+ * - specifies the hash function used by a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to determine the hash value for a key
+ * in the specified HashTable (before modulation). An ideal hash
+ * function is one which is easy to compute and approximates a
+ * "random" function. The default function is one that works
+ * relatively well for pointers. If the HashTable keys are to be
+ * strings (which is probably the case), then this default function
+ * will not suffice, in which case consider using the provided
+ * hashtable_string_hash_function() function.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose hash function is being specified
+ * hashFunction - a function which returns an appropriate hash code
+ * for a given key
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_set_hashfunction(hashtable_t *hashTable,
+ unsigned long (*hashFunction)(const void *key));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_rehash() - reorganizes a HashTable to be more efficient
+ * DESCRIPTION:
+ * Reorganizes a HashTable to be more efficient. If a number of
+ * buckets is specified, the HashTable is rehashed to that number of
+ * buckets. If 0 is specified, the HashTable is rehashed to a number
+ * of buckets which is automatically calculated to be a prime number
+ * that achieves (as closely as possible) the ideal element-to-bucket
+ * ratio specified by the hashtable_set_ideal_ration() function.
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to be reorganized
+ * numOfBuckets - the number of buckets to rehash the HashTable to.
+ * Should be prime. Ideally, the number of buckets
+ * should be between 1/5 and 1 times the expected
+ * number of elements in the HashTable. Values much
+ * more or less than this will result in wasted memory
+ * or decreased performance respectively. If 0 is
+ * specified, an appropriate number of buckets is
+ * automatically calculated.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_rehash(hashtable_t *hashTable, long numOfBuckets);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_set_ideal_ration()
+ * - sets the ideal element-to-bucket ratio of a HashTable
+ * DESCRIPTION:
+ * Sets the ideal element-to-bucket ratio, as well as the lower and
+ * upper auto-rehash thresholds, of the specified HashTable. Note
+ * that this function doesn't actually perform a rehash.
+ *
+ * The default values for these properties are 3.0, 0.0 and 15.0
+ * respectively. This is likely fine for most situations, so there
+ * is probably no need to call this function.
+ * ARGUMENTS:
+ * hashTable - a HashTable
+ * idealRatio - the ideal element-to-bucket ratio. When a rehash
+ * occurs (either manually via a call to the
+ * hashtable_rehash() function or automatically due the
+ * the triggering of one of the thresholds below), the
+ * number of buckets in the HashTable will be
+ * recalculated to be a prime number that achieves (as
+ * closely as possible) this ideal ratio. Must be a
+ * positive number.
+ * lowerRehashThreshold
+ * - the element-to-bucket ratio that is considered
+ * unacceptably low (i.e., too few elements per bucket).
+ * If the actual ratio falls below this number, a
+ * rehash will automatically be performed. Must be
+ * lower than the value of idealRatio. If no ratio
+ * is considered unacceptably low, a value of 0.0 can
+ * be specified.
+ * upperRehashThreshold
+ * - the element-to-bucket ratio that is considered
+ * unacceptably high (i.e., too many elements per bucket).
+ * If the actual ratio rises above this number, a
+ * rehash will automatically be performed. Must be
+ * higher than idealRatio. However, if no ratio
+ * is considered unacceptably high, a value of 0.0 can
+ * be specified.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_set_ideal_ration(hashtable_t *hashTable, float idealRatio,
+ float lowerRehashThreshold,
+ float upperRehashThreshold);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_set_deallocation_function()
+ * - sets the key and value deallocation functions of a HashTable
+ * DESCRIPTION:
+ * Sets the key and value deallocation functions of the specified
+ * HashTable. This determines what happens to a key or a value when it
+ * is removed from the HashTable. If the deallocation function is NULL
+ * (the default if this function is never called), its reference is
+ * simply dropped and it is up to the calling program to perform the
+ * proper memory management. If the deallocation function is non-NULL,
+ * it is called to free the memory used by the object. E.g., for simple
+ * objects, an appropriate deallocation function may be free().
+ *
+ * This affects the behaviour of the hashtable_destroy(), hashtable_put(),
+ * hashtable_remove() and hashtable_remove_all() functions.
+ * ARGUMENTS:
+ * hashTable - a HashTable
+ * keyDeallocator
+ * - if non-NULL, the function to be called when a key is
+ * removed from the HashTable.
+ * valueDeallocator
+ * - if non-NULL, the function to be called when a value is
+ * removed from the HashTable.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void hashtable_set_deallocation_function(hashtable_t *hashTable,
+ void (*keyDeallocator)(void *key),
+ void (*valueDeallocator)(void *value));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * hashtable_string_hash_function() - a good hash function for strings
+ * DESCRIPTION:
+ * A hash function that is appropriate for hashing strings. Note that
+ * this is not the default hash function. To make it the default hash
+ * function, call hashtable_set_hashfunction(hashtable_string_hash_function).
+ * ARGUMENTS:
+ * key - the key to be hashed
+ * RETURNS:
+ * long - the unmodulated hash value of the key
+\*--------------------------------------------------------------------------*/
+
+unsigned long hashtable_string_hash_function(const void *key);
+
+#endif /* UTILS_HASHTABLE_H */
+
+