diff options
Diffstat (limited to 'utils/hashtable.h')
| -rwxr-xr-x | utils/hashtable.h | 451 | 
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 */ + + | 
