198b9484cSchristos /* An expandable hash tables datatype. 2*e663ba6eSchristos Copyright (C) 1999-2024 Free Software Foundation, Inc. 398b9484cSchristos Contributed by Vladimir Makarov (vmakarov@cygnus.com). 498b9484cSchristos 598b9484cSchristos This program is free software; you can redistribute it and/or modify 698b9484cSchristos it under the terms of the GNU General Public License as published by 798b9484cSchristos the Free Software Foundation; either version 2 of the License, or 898b9484cSchristos (at your option) any later version. 998b9484cSchristos 1098b9484cSchristos This program is distributed in the hope that it will be useful, 1198b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1298b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1398b9484cSchristos GNU General Public License for more details. 1498b9484cSchristos 1598b9484cSchristos You should have received a copy of the GNU General Public License 1698b9484cSchristos along with this program; if not, write to the Free Software 1798b9484cSchristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 1898b9484cSchristos 1998b9484cSchristos /* This package implements basic hash table functionality. It is possible 2098b9484cSchristos to search for an entry, create an entry and destroy an entry. 2198b9484cSchristos 2298b9484cSchristos Elements in the table are generic pointers. 2398b9484cSchristos 2498b9484cSchristos The size of the table is not fixed; if the occupancy of the table 2598b9484cSchristos grows too high the hash table will be expanded. 2698b9484cSchristos 2798b9484cSchristos The abstract data implementation is based on generalized Algorithm D 2898b9484cSchristos from Knuth's book "The art of computer programming". Hash table is 2998b9484cSchristos expanded by creation of new hash table and transferring elements from 3098b9484cSchristos the old table to the new table. */ 3198b9484cSchristos 3298b9484cSchristos #ifndef __HASHTAB_H__ 3398b9484cSchristos #define __HASHTAB_H__ 3498b9484cSchristos 3598b9484cSchristos #ifdef __cplusplus 3698b9484cSchristos extern "C" { 3798b9484cSchristos #endif /* __cplusplus */ 3898b9484cSchristos 3998b9484cSchristos #include "ansidecl.h" 4098b9484cSchristos 4198b9484cSchristos /* The type for a hash code. */ 4298b9484cSchristos typedef unsigned int hashval_t; 4398b9484cSchristos 4498b9484cSchristos /* Callback function pointer types. */ 4598b9484cSchristos 4698b9484cSchristos /* Calculate hash of a table entry. */ 4798b9484cSchristos typedef hashval_t (*htab_hash) (const void *); 4898b9484cSchristos 4998b9484cSchristos /* Compare a table entry with a possible entry. The entry already in 5098b9484cSchristos the table always comes first, so the second element can be of a 5198b9484cSchristos different type (but in this case htab_find and htab_find_slot 5298b9484cSchristos cannot be used; instead the variants that accept a hash value 5398b9484cSchristos must be used). */ 5498b9484cSchristos typedef int (*htab_eq) (const void *, const void *); 5598b9484cSchristos 5698b9484cSchristos /* Cleanup function called whenever a live element is removed from 5798b9484cSchristos the hash table. */ 5898b9484cSchristos typedef void (*htab_del) (void *); 5998b9484cSchristos 6098b9484cSchristos /* Function called by htab_traverse for each live element. The first 6198b9484cSchristos arg is the slot of the element (which can be passed to htab_clear_slot 6298b9484cSchristos if desired), the second arg is the auxiliary pointer handed to 6398b9484cSchristos htab_traverse. Return 1 to continue scan, 0 to stop. */ 6498b9484cSchristos typedef int (*htab_trav) (void **, void *); 6598b9484cSchristos 6698b9484cSchristos /* Memory-allocation function, with the same functionality as calloc(). 6798b9484cSchristos Iff it returns NULL, the hash table implementation will pass an error 6898b9484cSchristos code back to the user, so if your code doesn't handle errors, 6998b9484cSchristos best if you use xcalloc instead. */ 7098b9484cSchristos typedef void *(*htab_alloc) (size_t, size_t); 7198b9484cSchristos 7298b9484cSchristos /* We also need a free() routine. */ 7398b9484cSchristos typedef void (*htab_free) (void *); 7498b9484cSchristos 7598b9484cSchristos /* Memory allocation and deallocation; variants which take an extra 7698b9484cSchristos argument. */ 7798b9484cSchristos typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t); 7898b9484cSchristos typedef void (*htab_free_with_arg) (void *, void *); 7998b9484cSchristos 8098b9484cSchristos /* This macro defines reserved value for empty table entry. */ 8198b9484cSchristos 824b169a6bSchristos #define HTAB_EMPTY_ENTRY ((void *) 0) 8398b9484cSchristos 8498b9484cSchristos /* This macro defines reserved value for table entry which contained 8598b9484cSchristos a deleted element. */ 8698b9484cSchristos 874b169a6bSchristos #define HTAB_DELETED_ENTRY ((void *) 1) 8898b9484cSchristos 8998b9484cSchristos /* Hash tables are of the following type. The structure 9098b9484cSchristos (implementation) of this type is not needed for using the hash 9198b9484cSchristos tables. All work with hash table should be executed only through 9298b9484cSchristos functions mentioned below. The size of this structure is subject to 9398b9484cSchristos change. */ 9498b9484cSchristos 95ba340e45Schristos struct htab { 9698b9484cSchristos /* Pointer to hash function. */ 9798b9484cSchristos htab_hash hash_f; 9898b9484cSchristos 9998b9484cSchristos /* Pointer to comparison function. */ 10098b9484cSchristos htab_eq eq_f; 10198b9484cSchristos 10298b9484cSchristos /* Pointer to cleanup function. */ 10398b9484cSchristos htab_del del_f; 10498b9484cSchristos 10598b9484cSchristos /* Table itself. */ 106ba340e45Schristos void **entries; 10798b9484cSchristos 10898b9484cSchristos /* Current size (in entries) of the hash table. */ 10998b9484cSchristos size_t size; 11098b9484cSchristos 11198b9484cSchristos /* Current number of elements including also deleted elements. */ 11298b9484cSchristos size_t n_elements; 11398b9484cSchristos 11498b9484cSchristos /* Current number of deleted elements in the table. */ 11598b9484cSchristos size_t n_deleted; 11698b9484cSchristos 11798b9484cSchristos /* The following member is used for debugging. Its value is number 11898b9484cSchristos of all calls of `htab_find_slot' for the hash table. */ 11998b9484cSchristos unsigned int searches; 12098b9484cSchristos 12198b9484cSchristos /* The following member is used for debugging. Its value is number 12298b9484cSchristos of collisions fixed for time of work with the hash table. */ 12398b9484cSchristos unsigned int collisions; 12498b9484cSchristos 12598b9484cSchristos /* Pointers to allocate/free functions. */ 12698b9484cSchristos htab_alloc alloc_f; 12798b9484cSchristos htab_free free_f; 12898b9484cSchristos 12998b9484cSchristos /* Alternate allocate/free functions, which take an extra argument. */ 130ba340e45Schristos void *alloc_arg; 13198b9484cSchristos htab_alloc_with_arg alloc_with_arg_f; 13298b9484cSchristos htab_free_with_arg free_with_arg_f; 13398b9484cSchristos 13498b9484cSchristos /* Current size (in entries) of the hash table, as an index into the 13598b9484cSchristos table of primes. */ 13698b9484cSchristos unsigned int size_prime_index; 13798b9484cSchristos }; 13898b9484cSchristos 13998b9484cSchristos typedef struct htab *htab_t; 14098b9484cSchristos 14198b9484cSchristos /* An enum saying whether we insert into the hash table or not. */ 14298b9484cSchristos enum insert_option {NO_INSERT, INSERT}; 14398b9484cSchristos 14498b9484cSchristos /* The prototypes of the package functions. */ 14598b9484cSchristos 14698b9484cSchristos extern htab_t htab_create_alloc (size_t, htab_hash, 14798b9484cSchristos htab_eq, htab_del, 14898b9484cSchristos htab_alloc, htab_free); 14998b9484cSchristos 15098b9484cSchristos extern htab_t htab_create_alloc_ex (size_t, htab_hash, 15198b9484cSchristos htab_eq, htab_del, 15298b9484cSchristos void *, htab_alloc_with_arg, 15398b9484cSchristos htab_free_with_arg); 15498b9484cSchristos 15598b9484cSchristos extern htab_t htab_create_typed_alloc (size_t, htab_hash, htab_eq, htab_del, 15698b9484cSchristos htab_alloc, htab_alloc, htab_free); 15798b9484cSchristos 15898b9484cSchristos /* Backward-compatibility functions. */ 15998b9484cSchristos extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del); 16098b9484cSchristos extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del); 16198b9484cSchristos 16298b9484cSchristos extern void htab_set_functions_ex (htab_t, htab_hash, 16398b9484cSchristos htab_eq, htab_del, 16498b9484cSchristos void *, htab_alloc_with_arg, 16598b9484cSchristos htab_free_with_arg); 16698b9484cSchristos 16798b9484cSchristos extern void htab_delete (htab_t); 16898b9484cSchristos extern void htab_empty (htab_t); 16998b9484cSchristos 17098b9484cSchristos extern void * htab_find (htab_t, const void *); 17198b9484cSchristos extern void ** htab_find_slot (htab_t, const void *, enum insert_option); 17298b9484cSchristos extern void * htab_find_with_hash (htab_t, const void *, hashval_t); 17398b9484cSchristos extern void ** htab_find_slot_with_hash (htab_t, const void *, 17498b9484cSchristos hashval_t, enum insert_option); 17598b9484cSchristos extern void htab_clear_slot (htab_t, void **); 1768dffb485Schristos extern void htab_remove_elt (htab_t, const void *); 1778dffb485Schristos extern void htab_remove_elt_with_hash (htab_t, const void *, hashval_t); 17898b9484cSchristos 17998b9484cSchristos extern void htab_traverse (htab_t, htab_trav, void *); 18098b9484cSchristos extern void htab_traverse_noresize (htab_t, htab_trav, void *); 18198b9484cSchristos 18298b9484cSchristos extern size_t htab_size (htab_t); 18398b9484cSchristos extern size_t htab_elements (htab_t); 18498b9484cSchristos extern double htab_collisions (htab_t); 18598b9484cSchristos 18698b9484cSchristos /* A hash function for pointers. */ 18798b9484cSchristos extern htab_hash htab_hash_pointer; 18898b9484cSchristos 18998b9484cSchristos /* An equality function for pointers. */ 19098b9484cSchristos extern htab_eq htab_eq_pointer; 19198b9484cSchristos 19298b9484cSchristos /* A hash function for null-terminated strings. */ 19398b9484cSchristos extern hashval_t htab_hash_string (const void *); 19498b9484cSchristos 1954b169a6bSchristos /* An equality function for null-terminated strings. */ 1964b169a6bSchristos extern int htab_eq_string (const void *, const void *); 1974b169a6bSchristos 19898b9484cSchristos /* An iterative hash function for arbitrary data. */ 19998b9484cSchristos extern hashval_t iterative_hash (const void *, size_t, hashval_t); 20098b9484cSchristos /* Shorthand for hashing something with an intrinsic size. */ 20198b9484cSchristos #define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT) 20298b9484cSchristos 20398b9484cSchristos #ifdef __cplusplus 20498b9484cSchristos } 20598b9484cSchristos #endif /* __cplusplus */ 20698b9484cSchristos 20798b9484cSchristos #endif /* __HASHTAB_H */ 208