1*3d8817e4Smiod /* An expandable hash tables datatype. 2*3d8817e4Smiod Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. 3*3d8817e4Smiod Contributed by Vladimir Makarov (vmakarov@cygnus.com). 4*3d8817e4Smiod 5*3d8817e4Smiod This program is free software; you can redistribute it and/or modify 6*3d8817e4Smiod it under the terms of the GNU General Public License as published by 7*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or 8*3d8817e4Smiod (at your option) any later version. 9*3d8817e4Smiod 10*3d8817e4Smiod This program is distributed in the hope that it will be useful, 11*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of 12*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*3d8817e4Smiod GNU General Public License for more details. 14*3d8817e4Smiod 15*3d8817e4Smiod You should have received a copy of the GNU General Public License 16*3d8817e4Smiod along with this program; if not, write to the Free Software 17*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 18*3d8817e4Smiod 19*3d8817e4Smiod /* This package implements basic hash table functionality. It is possible 20*3d8817e4Smiod to search for an entry, create an entry and destroy an entry. 21*3d8817e4Smiod 22*3d8817e4Smiod Elements in the table are generic pointers. 23*3d8817e4Smiod 24*3d8817e4Smiod The size of the table is not fixed; if the occupancy of the table 25*3d8817e4Smiod grows too high the hash table will be expanded. 26*3d8817e4Smiod 27*3d8817e4Smiod The abstract data implementation is based on generalized Algorithm D 28*3d8817e4Smiod from Knuth's book "The art of computer programming". Hash table is 29*3d8817e4Smiod expanded by creation of new hash table and transferring elements from 30*3d8817e4Smiod the old table to the new table. */ 31*3d8817e4Smiod 32*3d8817e4Smiod #ifndef __HASHTAB_H__ 33*3d8817e4Smiod #define __HASHTAB_H__ 34*3d8817e4Smiod 35*3d8817e4Smiod #ifdef __cplusplus 36*3d8817e4Smiod extern "C" { 37*3d8817e4Smiod #endif /* __cplusplus */ 38*3d8817e4Smiod 39*3d8817e4Smiod #include "ansidecl.h" 40*3d8817e4Smiod 41*3d8817e4Smiod #ifndef GTY 42*3d8817e4Smiod #define GTY(X) 43*3d8817e4Smiod #endif 44*3d8817e4Smiod 45*3d8817e4Smiod /* The type for a hash code. */ 46*3d8817e4Smiod typedef unsigned int hashval_t; 47*3d8817e4Smiod 48*3d8817e4Smiod /* Callback function pointer types. */ 49*3d8817e4Smiod 50*3d8817e4Smiod /* Calculate hash of a table entry. */ 51*3d8817e4Smiod typedef hashval_t (*htab_hash) (const void *); 52*3d8817e4Smiod 53*3d8817e4Smiod /* Compare a table entry with a possible entry. The entry already in 54*3d8817e4Smiod the table always comes first, so the second element can be of a 55*3d8817e4Smiod different type (but in this case htab_find and htab_find_slot 56*3d8817e4Smiod cannot be used; instead the variants that accept a hash value 57*3d8817e4Smiod must be used). */ 58*3d8817e4Smiod typedef int (*htab_eq) (const void *, const void *); 59*3d8817e4Smiod 60*3d8817e4Smiod /* Cleanup function called whenever a live element is removed from 61*3d8817e4Smiod the hash table. */ 62*3d8817e4Smiod typedef void (*htab_del) (void *); 63*3d8817e4Smiod 64*3d8817e4Smiod /* Function called by htab_traverse for each live element. The first 65*3d8817e4Smiod arg is the slot of the element (which can be passed to htab_clear_slot 66*3d8817e4Smiod if desired), the second arg is the auxiliary pointer handed to 67*3d8817e4Smiod htab_traverse. Return 1 to continue scan, 0 to stop. */ 68*3d8817e4Smiod typedef int (*htab_trav) (void **, void *); 69*3d8817e4Smiod 70*3d8817e4Smiod /* Memory-allocation function, with the same functionality as calloc(). 71*3d8817e4Smiod Iff it returns NULL, the hash table implementation will pass an error 72*3d8817e4Smiod code back to the user, so if your code doesn't handle errors, 73*3d8817e4Smiod best if you use xcalloc instead. */ 74*3d8817e4Smiod typedef void *(*htab_alloc) (size_t, size_t); 75*3d8817e4Smiod 76*3d8817e4Smiod /* We also need a free() routine. */ 77*3d8817e4Smiod typedef void (*htab_free) (void *); 78*3d8817e4Smiod 79*3d8817e4Smiod /* Memory allocation and deallocation; variants which take an extra 80*3d8817e4Smiod argument. */ 81*3d8817e4Smiod typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t); 82*3d8817e4Smiod typedef void (*htab_free_with_arg) (void *, void *); 83*3d8817e4Smiod 84*3d8817e4Smiod /* This macro defines reserved value for empty table entry. */ 85*3d8817e4Smiod 86*3d8817e4Smiod #define HTAB_EMPTY_ENTRY ((PTR) 0) 87*3d8817e4Smiod 88*3d8817e4Smiod /* This macro defines reserved value for table entry which contained 89*3d8817e4Smiod a deleted element. */ 90*3d8817e4Smiod 91*3d8817e4Smiod #define HTAB_DELETED_ENTRY ((PTR) 1) 92*3d8817e4Smiod 93*3d8817e4Smiod /* Hash tables are of the following type. The structure 94*3d8817e4Smiod (implementation) of this type is not needed for using the hash 95*3d8817e4Smiod tables. All work with hash table should be executed only through 96*3d8817e4Smiod functions mentioned below. The size of this structure is subject to 97*3d8817e4Smiod change. */ 98*3d8817e4Smiod 99*3d8817e4Smiod struct htab GTY(()) 100*3d8817e4Smiod { 101*3d8817e4Smiod /* Pointer to hash function. */ 102*3d8817e4Smiod htab_hash hash_f; 103*3d8817e4Smiod 104*3d8817e4Smiod /* Pointer to comparison function. */ 105*3d8817e4Smiod htab_eq eq_f; 106*3d8817e4Smiod 107*3d8817e4Smiod /* Pointer to cleanup function. */ 108*3d8817e4Smiod htab_del del_f; 109*3d8817e4Smiod 110*3d8817e4Smiod /* Table itself. */ 111*3d8817e4Smiod void ** GTY ((use_param, length ("%h.size"))) entries; 112*3d8817e4Smiod 113*3d8817e4Smiod /* Current size (in entries) of the hash table. */ 114*3d8817e4Smiod size_t size; 115*3d8817e4Smiod 116*3d8817e4Smiod /* Current number of elements including also deleted elements. */ 117*3d8817e4Smiod size_t n_elements; 118*3d8817e4Smiod 119*3d8817e4Smiod /* Current number of deleted elements in the table. */ 120*3d8817e4Smiod size_t n_deleted; 121*3d8817e4Smiod 122*3d8817e4Smiod /* The following member is used for debugging. Its value is number 123*3d8817e4Smiod of all calls of `htab_find_slot' for the hash table. */ 124*3d8817e4Smiod unsigned int searches; 125*3d8817e4Smiod 126*3d8817e4Smiod /* The following member is used for debugging. Its value is number 127*3d8817e4Smiod of collisions fixed for time of work with the hash table. */ 128*3d8817e4Smiod unsigned int collisions; 129*3d8817e4Smiod 130*3d8817e4Smiod /* Pointers to allocate/free functions. */ 131*3d8817e4Smiod htab_alloc alloc_f; 132*3d8817e4Smiod htab_free free_f; 133*3d8817e4Smiod 134*3d8817e4Smiod /* Alternate allocate/free functions, which take an extra argument. */ 135*3d8817e4Smiod void * GTY((skip)) alloc_arg; 136*3d8817e4Smiod htab_alloc_with_arg alloc_with_arg_f; 137*3d8817e4Smiod htab_free_with_arg free_with_arg_f; 138*3d8817e4Smiod 139*3d8817e4Smiod /* Current size (in entries) of the hash table, as an index into the 140*3d8817e4Smiod table of primes. */ 141*3d8817e4Smiod unsigned int size_prime_index; 142*3d8817e4Smiod }; 143*3d8817e4Smiod 144*3d8817e4Smiod typedef struct htab *htab_t; 145*3d8817e4Smiod 146*3d8817e4Smiod /* An enum saying whether we insert into the hash table or not. */ 147*3d8817e4Smiod enum insert_option {NO_INSERT, INSERT}; 148*3d8817e4Smiod 149*3d8817e4Smiod /* The prototypes of the package functions. */ 150*3d8817e4Smiod 151*3d8817e4Smiod extern htab_t htab_create_alloc (size_t, htab_hash, 152*3d8817e4Smiod htab_eq, htab_del, 153*3d8817e4Smiod htab_alloc, htab_free); 154*3d8817e4Smiod 155*3d8817e4Smiod extern htab_t htab_create_alloc_ex (size_t, htab_hash, 156*3d8817e4Smiod htab_eq, htab_del, 157*3d8817e4Smiod void *, htab_alloc_with_arg, 158*3d8817e4Smiod htab_free_with_arg); 159*3d8817e4Smiod 160*3d8817e4Smiod /* Backward-compatibility functions. */ 161*3d8817e4Smiod extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del); 162*3d8817e4Smiod extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del); 163*3d8817e4Smiod 164*3d8817e4Smiod extern void htab_set_functions_ex (htab_t, htab_hash, 165*3d8817e4Smiod htab_eq, htab_del, 166*3d8817e4Smiod void *, htab_alloc_with_arg, 167*3d8817e4Smiod htab_free_with_arg); 168*3d8817e4Smiod 169*3d8817e4Smiod extern void htab_delete (htab_t); 170*3d8817e4Smiod extern void htab_empty (htab_t); 171*3d8817e4Smiod 172*3d8817e4Smiod extern void * htab_find (htab_t, const void *); 173*3d8817e4Smiod extern void ** htab_find_slot (htab_t, const void *, enum insert_option); 174*3d8817e4Smiod extern void * htab_find_with_hash (htab_t, const void *, hashval_t); 175*3d8817e4Smiod extern void ** htab_find_slot_with_hash (htab_t, const void *, 176*3d8817e4Smiod hashval_t, enum insert_option); 177*3d8817e4Smiod extern void htab_clear_slot (htab_t, void **); 178*3d8817e4Smiod extern void htab_remove_elt (htab_t, void *); 179*3d8817e4Smiod extern void htab_remove_elt_with_hash (htab_t, void *, hashval_t); 180*3d8817e4Smiod 181*3d8817e4Smiod extern void htab_traverse (htab_t, htab_trav, void *); 182*3d8817e4Smiod extern void htab_traverse_noresize (htab_t, htab_trav, void *); 183*3d8817e4Smiod 184*3d8817e4Smiod extern size_t htab_size (htab_t); 185*3d8817e4Smiod extern size_t htab_elements (htab_t); 186*3d8817e4Smiod extern double htab_collisions (htab_t); 187*3d8817e4Smiod 188*3d8817e4Smiod /* A hash function for pointers. */ 189*3d8817e4Smiod extern htab_hash htab_hash_pointer; 190*3d8817e4Smiod 191*3d8817e4Smiod /* An equality function for pointers. */ 192*3d8817e4Smiod extern htab_eq htab_eq_pointer; 193*3d8817e4Smiod 194*3d8817e4Smiod /* A hash function for null-terminated strings. */ 195*3d8817e4Smiod extern hashval_t htab_hash_string (const void *); 196*3d8817e4Smiod 197*3d8817e4Smiod /* An iterative hash function for arbitrary data. */ 198*3d8817e4Smiod extern hashval_t iterative_hash (const void *, size_t, hashval_t); 199*3d8817e4Smiod /* Shorthand for hashing something with an intrinsic size. */ 200*3d8817e4Smiod #define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT) 201*3d8817e4Smiod 202*3d8817e4Smiod #ifdef __cplusplus 203*3d8817e4Smiod } 204*3d8817e4Smiod #endif /* __cplusplus */ 205*3d8817e4Smiod 206*3d8817e4Smiod #endif /* __HASHTAB_H */ 207