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