1 /* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
   2 
   3 #ifndef __HASHTABLE_CWC22_H__
   4 #define __HASHTABLE_CWC22_H__
   5 
   6 struct hashtable;
   7 
   8 /* Example of use:
   9  *
  10  *      struct hashtable  *h;
  11  *      struct some_key   *k;
  12  *      struct some_value *v;
  13  *
  14  *      static unsigned int         hash_from_key_fn( void *k );
  15  *      static int                  keys_equal_fn ( void *key1, void *key2 );
  16  *
  17  *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
  18  *      k = (struct some_key *)     malloc(sizeof(struct some_key));
  19  *      v = (struct some_value *)   malloc(sizeof(struct some_value));
  20  *
  21  *      (initialise k and v to suitable values)
  22  * 
  23  *      if (! hashtable_insert(h,k,v) )
  24  *      {     exit(-1);               }
  25  *
  26  *      if (NULL == (found = hashtable_search(h,k) ))
  27  *      {    printf("not found!");                  }
  28  *
  29  *      if (NULL == (found = hashtable_remove(h,k) ))
  30  *      {    printf("Not found\n");                 }
  31  *
  32  */
  33 
  34 /* Macros may be used to define type-safe(r) hashtable access functions, with
  35  * methods specialized to take known key and value types as parameters.
  36  * 
  37  * Example:
  38  *
  39  * Insert this at the start of your file:
  40  *
  41  * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
  42  * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
  43  * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
  44  *
  45  * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
  46  * These operate just like hashtable_insert etc., with the same parameters,
  47  * but their function signatures have 'struct some_key *' rather than
  48  * 'void *', and hence can generate compile time errors if your program is
  49  * supplying incorrect data as a key (and similarly for value).
  50  *
  51  * Note that the hash and key equality functions passed to create_hashtable
  52  * still take 'void *' parameters instead of 'some key *'. This shouldn't be
  53  * a difficult issue as they're only defined and passed once, and the other
  54  * functions will ensure that only valid keys are supplied to them.
  55  *
  56  * The cost for this checking is increased code size and runtime overhead
  57  * - if performance is important, it may be worth switching back to the
  58  * unsafe methods once your program has been debugged with the safe methods.
  59  * This just requires switching to some simple alternative defines - eg:
  60  * #define insert_some hashtable_insert
  61  *
  62  */
  63 
  64 /*****************************************************************************
  65  * create_hashtable
  66    
  67  * @name                    create_hashtable
  68  * @param   minsize         minimum initial size of hashtable
  69  * @param   hashfunction    function for hashing keys
  70  * @param   key_eq_fn       function for determining key equality
  71  * @return                  newly created hashtable or NULL on failure
  72  */
  73 
  74 struct hashtable *
  75 create_hashtable(unsigned int minsize,
  76                  unsigned int (*hashfunction) (void*),
  77                  int (*key_eq_fn) (void*,void*));
  78 
  79 /*****************************************************************************
  80  * hashtable_insert
  81    
  82  * @name        hashtable_insert
  83  * @param   h   the hashtable to insert into
  84  * @param   k   the key - hashtable claims ownership and will free on removal
  85  * @param   v   the value - does not claim ownership
  86  * @return      non-zero for successful insertion
  87  *
  88  * This function will cause the table to expand if the insertion would take
  89  * the ratio of entries to table size over the maximum load factor.
  90  *
  91  * This function does not check for repeated insertions with a duplicate key.
  92  * The value returned when using a duplicate key is undefined -- when
  93  * the hashtable changes size, the order of retrieval of duplicate key
  94  * entries is reversed.
  95  * If in doubt, remove before insert.
  96  */
  97 
  98 int 
  99 hashtable_insert(struct hashtable *h, void *k, void *v);
 100 
 101 #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
 102 int fnname (struct hashtable *h, keytype *k, valuetype *v) \
 103 { \
 104     return hashtable_insert(h,k,v); \
 105 }
 106 
 107 /*****************************************************************************
 108  * hashtable_search
 109    
 110  * @name        hashtable_search
 111  * @param   h   the hashtable to search
 112  * @param   k   the key to search for  - does not claim ownership
 113  * @return      the value associated with the key, or NULL if none found
 114  */
 115 
 116 void *
 117 hashtable_search(struct hashtable *h, void *k);
 118 
 119 #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
 120 valuetype * fnname (struct hashtable *h, keytype *k) \
 121 { \
 122     return (valuetype *) (hashtable_search(h,k)); \
 123 }
 124 
 125 /*****************************************************************************
 126  * hashtable_remove
 127    
 128  * @name        hashtable_remove
 129  * @param   h   the hashtable to remove the item from
 130  * @param   k   the key to search for  - does not claim ownership
 131  * @return      the value associated with the key, or NULL if none found
 132  */
 133 
 134 void * /* returns value */
 135 hashtable_remove(struct hashtable *h, void *k);
 136 
 137 #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
 138 valuetype * fnname (struct hashtable *h, keytype *k) \
 139 { \
 140     return (valuetype *) (hashtable_remove(h,k)); \
 141 }
 142 
 143 
 144 /*****************************************************************************
 145  * hashtable_count
 146    
 147  * @name        hashtable_count
 148  * @param   h   the hashtable
 149  * @return      the number of items stored in the hashtable
 150  */
 151 unsigned int
 152 hashtable_count(struct hashtable *h);
 153 
 154 
 155 /*****************************************************************************
 156  * hashtable_destroy
 157    
 158  * @name        hashtable_destroy
 159  * @param   h   the hashtable
 160  * @param       free_values     whether to call 'free' on the remaining values
 161  */
 162 
 163 void
 164 hashtable_destroy(struct hashtable *h, int free_values);
 165 
 166 #endif /* __HASHTABLE_CWC22_H__ */
 167 
 168 /*
 169  * Copyright (c) 2002, Christopher Clark
 170  * All rights reserved.
 171  * 
 172  * Redistribution and use in source and binary forms, with or without
 173  * modification, are permitted provided that the following conditions
 174  * are met:
 175  * 
 176  * * Redistributions of source code must retain the above copyright
 177  * notice, this list of conditions and the following disclaimer.
 178  * 
 179  * * Redistributions in binary form must reproduce the above copyright
 180  * notice, this list of conditions and the following disclaimer in the
 181  * documentation and/or other materials provided with the distribution.
 182  * 
 183  * * Neither the name of the original author; nor the names of any contributors
 184  * may be used to endorse or promote products derived from this software
 185  * without specific prior written permission.
 186  * 
 187  * 
 188  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 189  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 190  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 191  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
 192  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 193  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 194  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 195  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 196  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 197  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 198  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 199 */