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