175fd0b74Schristos /* An expandable hash tables datatype. 2*e992f068Schristos Copyright (C) 1999-2022 Free Software Foundation, Inc. 375fd0b74Schristos Contributed by Vladimir Makarov (vmakarov@cygnus.com). 475fd0b74Schristos 575fd0b74Schristos This program is free software; you can redistribute it and/or modify 675fd0b74Schristos it under the terms of the GNU General Public License as published by 775fd0b74Schristos the Free Software Foundation; either version 2 of the License, or 875fd0b74Schristos (at your option) any later version. 975fd0b74Schristos 1075fd0b74Schristos This program is distributed in the hope that it will be useful, 1175fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1275fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1375fd0b74Schristos GNU General Public License for more details. 1475fd0b74Schristos 1575fd0b74Schristos You should have received a copy of the GNU General Public License 1675fd0b74Schristos along with this program; if not, write to the Free Software 1775fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 1875fd0b74Schristos 1975fd0b74Schristos /* This package implements basic hash table functionality. It is possible 2075fd0b74Schristos to search for an entry, create an entry and destroy an entry. 2175fd0b74Schristos 2275fd0b74Schristos Elements in the table are generic pointers. 2375fd0b74Schristos 2475fd0b74Schristos The size of the table is not fixed; if the occupancy of the table 2575fd0b74Schristos grows too high the hash table will be expanded. 2675fd0b74Schristos 2775fd0b74Schristos The abstract data implementation is based on generalized Algorithm D 2875fd0b74Schristos from Knuth's book "The art of computer programming". Hash table is 2975fd0b74Schristos expanded by creation of new hash table and transferring elements from 3075fd0b74Schristos the old table to the new table. */ 3175fd0b74Schristos 3275fd0b74Schristos #ifndef __HASHTAB_H__ 3375fd0b74Schristos #define __HASHTAB_H__ 3475fd0b74Schristos 3575fd0b74Schristos #ifdef __cplusplus 3675fd0b74Schristos extern "C" { 3775fd0b74Schristos #endif /* __cplusplus */ 3875fd0b74Schristos 3975fd0b74Schristos #include "ansidecl.h" 4075fd0b74Schristos 4175fd0b74Schristos /* The type for a hash code. */ 4275fd0b74Schristos typedef unsigned int hashval_t; 4375fd0b74Schristos 4475fd0b74Schristos /* Callback function pointer types. */ 4575fd0b74Schristos 4675fd0b74Schristos /* Calculate hash of a table entry. */ 4775fd0b74Schristos typedef hashval_t (*htab_hash) (const void *); 4875fd0b74Schristos 4975fd0b74Schristos /* Compare a table entry with a possible entry. The entry already in 5075fd0b74Schristos the table always comes first, so the second element can be of a 5175fd0b74Schristos different type (but in this case htab_find and htab_find_slot 5275fd0b74Schristos cannot be used; instead the variants that accept a hash value 5375fd0b74Schristos must be used). */ 5475fd0b74Schristos typedef int (*htab_eq) (const void *, const void *); 5575fd0b74Schristos 5675fd0b74Schristos /* Cleanup function called whenever a live element is removed from 5775fd0b74Schristos the hash table. */ 5875fd0b74Schristos typedef void (*htab_del) (void *); 5975fd0b74Schristos 6075fd0b74Schristos /* Function called by htab_traverse for each live element. The first 6175fd0b74Schristos arg is the slot of the element (which can be passed to htab_clear_slot 6275fd0b74Schristos if desired), the second arg is the auxiliary pointer handed to 6375fd0b74Schristos htab_traverse. Return 1 to continue scan, 0 to stop. */ 6475fd0b74Schristos typedef int (*htab_trav) (void **, void *); 6575fd0b74Schristos 6675fd0b74Schristos /* Memory-allocation function, with the same functionality as calloc(). 6775fd0b74Schristos Iff it returns NULL, the hash table implementation will pass an error 6875fd0b74Schristos code back to the user, so if your code doesn't handle errors, 6975fd0b74Schristos best if you use xcalloc instead. */ 7075fd0b74Schristos typedef void *(*htab_alloc) (size_t, size_t); 7175fd0b74Schristos 7275fd0b74Schristos /* We also need a free() routine. */ 7375fd0b74Schristos typedef void (*htab_free) (void *); 7475fd0b74Schristos 7575fd0b74Schristos /* Memory allocation and deallocation; variants which take an extra 7675fd0b74Schristos argument. */ 7775fd0b74Schristos typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t); 7875fd0b74Schristos typedef void (*htab_free_with_arg) (void *, void *); 7975fd0b74Schristos 8075fd0b74Schristos /* This macro defines reserved value for empty table entry. */ 8175fd0b74Schristos 82*e992f068Schristos #define HTAB_EMPTY_ENTRY ((void *) 0) 8375fd0b74Schristos 8475fd0b74Schristos /* This macro defines reserved value for table entry which contained 8575fd0b74Schristos a deleted element. */ 8675fd0b74Schristos 87*e992f068Schristos #define HTAB_DELETED_ENTRY ((void *) 1) 8875fd0b74Schristos 8975fd0b74Schristos /* Hash tables are of the following type. The structure 9075fd0b74Schristos (implementation) of this type is not needed for using the hash 9175fd0b74Schristos tables. All work with hash table should be executed only through 9275fd0b74Schristos functions mentioned below. The size of this structure is subject to 9375fd0b74Schristos change. */ 9475fd0b74Schristos 9575fd0b74Schristos struct htab { 9675fd0b74Schristos /* Pointer to hash function. */ 9775fd0b74Schristos htab_hash hash_f; 9875fd0b74Schristos 9975fd0b74Schristos /* Pointer to comparison function. */ 10075fd0b74Schristos htab_eq eq_f; 10175fd0b74Schristos 10275fd0b74Schristos /* Pointer to cleanup function. */ 10375fd0b74Schristos htab_del del_f; 10475fd0b74Schristos 10575fd0b74Schristos /* Table itself. */ 10675fd0b74Schristos void **entries; 10775fd0b74Schristos 10875fd0b74Schristos /* Current size (in entries) of the hash table. */ 10975fd0b74Schristos size_t size; 11075fd0b74Schristos 11175fd0b74Schristos /* Current number of elements including also deleted elements. */ 11275fd0b74Schristos size_t n_elements; 11375fd0b74Schristos 11475fd0b74Schristos /* Current number of deleted elements in the table. */ 11575fd0b74Schristos size_t n_deleted; 11675fd0b74Schristos 11775fd0b74Schristos /* The following member is used for debugging. Its value is number 11875fd0b74Schristos of all calls of `htab_find_slot' for the hash table. */ 11975fd0b74Schristos unsigned int searches; 12075fd0b74Schristos 12175fd0b74Schristos /* The following member is used for debugging. Its value is number 12275fd0b74Schristos of collisions fixed for time of work with the hash table. */ 12375fd0b74Schristos unsigned int collisions; 12475fd0b74Schristos 12575fd0b74Schristos /* Pointers to allocate/free functions. */ 12675fd0b74Schristos htab_alloc alloc_f; 12775fd0b74Schristos htab_free free_f; 12875fd0b74Schristos 12975fd0b74Schristos /* Alternate allocate/free functions, which take an extra argument. */ 13075fd0b74Schristos void *alloc_arg; 13175fd0b74Schristos htab_alloc_with_arg alloc_with_arg_f; 13275fd0b74Schristos htab_free_with_arg free_with_arg_f; 13375fd0b74Schristos 13475fd0b74Schristos /* Current size (in entries) of the hash table, as an index into the 13575fd0b74Schristos table of primes. */ 13675fd0b74Schristos unsigned int size_prime_index; 13775fd0b74Schristos }; 13875fd0b74Schristos 13975fd0b74Schristos typedef struct htab *htab_t; 14075fd0b74Schristos 14175fd0b74Schristos /* An enum saying whether we insert into the hash table or not. */ 14275fd0b74Schristos enum insert_option {NO_INSERT, INSERT}; 14375fd0b74Schristos 14475fd0b74Schristos /* The prototypes of the package functions. */ 14575fd0b74Schristos 14675fd0b74Schristos extern htab_t htab_create_alloc (size_t, htab_hash, 14775fd0b74Schristos htab_eq, htab_del, 14875fd0b74Schristos htab_alloc, htab_free); 14975fd0b74Schristos 15075fd0b74Schristos extern htab_t htab_create_alloc_ex (size_t, htab_hash, 15175fd0b74Schristos htab_eq, htab_del, 15275fd0b74Schristos void *, htab_alloc_with_arg, 15375fd0b74Schristos htab_free_with_arg); 15475fd0b74Schristos 15575fd0b74Schristos extern htab_t htab_create_typed_alloc (size_t, htab_hash, htab_eq, htab_del, 15675fd0b74Schristos htab_alloc, htab_alloc, htab_free); 15775fd0b74Schristos 15875fd0b74Schristos /* Backward-compatibility functions. */ 15975fd0b74Schristos extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del); 16075fd0b74Schristos extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del); 16175fd0b74Schristos 16275fd0b74Schristos extern void htab_set_functions_ex (htab_t, htab_hash, 16375fd0b74Schristos htab_eq, htab_del, 16475fd0b74Schristos void *, htab_alloc_with_arg, 16575fd0b74Schristos htab_free_with_arg); 16675fd0b74Schristos 16775fd0b74Schristos extern void htab_delete (htab_t); 16875fd0b74Schristos extern void htab_empty (htab_t); 16975fd0b74Schristos 17075fd0b74Schristos extern void * htab_find (htab_t, const void *); 17175fd0b74Schristos extern void ** htab_find_slot (htab_t, const void *, enum insert_option); 17275fd0b74Schristos extern void * htab_find_with_hash (htab_t, const void *, hashval_t); 17375fd0b74Schristos extern void ** htab_find_slot_with_hash (htab_t, const void *, 17475fd0b74Schristos hashval_t, enum insert_option); 17575fd0b74Schristos extern void htab_clear_slot (htab_t, void **); 176*e992f068Schristos extern void htab_remove_elt (htab_t, const void *); 177*e992f068Schristos extern void htab_remove_elt_with_hash (htab_t, const void *, hashval_t); 17875fd0b74Schristos 17975fd0b74Schristos extern void htab_traverse (htab_t, htab_trav, void *); 18075fd0b74Schristos extern void htab_traverse_noresize (htab_t, htab_trav, void *); 18175fd0b74Schristos 18275fd0b74Schristos extern size_t htab_size (htab_t); 18375fd0b74Schristos extern size_t htab_elements (htab_t); 18475fd0b74Schristos extern double htab_collisions (htab_t); 18575fd0b74Schristos 18675fd0b74Schristos /* A hash function for pointers. */ 18775fd0b74Schristos extern htab_hash htab_hash_pointer; 18875fd0b74Schristos 18975fd0b74Schristos /* An equality function for pointers. */ 19075fd0b74Schristos extern htab_eq htab_eq_pointer; 19175fd0b74Schristos 19275fd0b74Schristos /* A hash function for null-terminated strings. */ 19375fd0b74Schristos extern hashval_t htab_hash_string (const void *); 19475fd0b74Schristos 195*e992f068Schristos /* An equality function for null-terminated strings. */ 196*e992f068Schristos extern int htab_eq_string (const void *, const void *); 197*e992f068Schristos 19875fd0b74Schristos /* An iterative hash function for arbitrary data. */ 19975fd0b74Schristos extern hashval_t iterative_hash (const void *, size_t, hashval_t); 20075fd0b74Schristos /* Shorthand for hashing something with an intrinsic size. */ 20175fd0b74Schristos #define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT) 20275fd0b74Schristos 20375fd0b74Schristos #ifdef __cplusplus 20475fd0b74Schristos } 20575fd0b74Schristos #endif /* __cplusplus */ 20675fd0b74Schristos 20775fd0b74Schristos #endif /* __HASHTAB_H */ 208