186d7f5d3SJohn Marino /* An expandable hash tables datatype. 286d7f5d3SJohn Marino Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2009, 2010 386d7f5d3SJohn Marino Free Software Foundation, Inc. 486d7f5d3SJohn Marino Contributed by Vladimir Makarov (vmakarov@cygnus.com). 586d7f5d3SJohn Marino 686d7f5d3SJohn Marino This program is free software; you can redistribute it and/or modify 786d7f5d3SJohn Marino it under the terms of the GNU General Public License as published by 886d7f5d3SJohn Marino the Free Software Foundation; either version 2 of the License, or 986d7f5d3SJohn Marino (at your option) any later version. 1086d7f5d3SJohn Marino 1186d7f5d3SJohn Marino This program is distributed in the hope that it will be useful, 1286d7f5d3SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of 1386d7f5d3SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1486d7f5d3SJohn Marino GNU General Public License for more details. 1586d7f5d3SJohn Marino 1686d7f5d3SJohn Marino You should have received a copy of the GNU General Public License 1786d7f5d3SJohn Marino along with this program; if not, write to the Free Software 1886d7f5d3SJohn Marino Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 1986d7f5d3SJohn Marino 2086d7f5d3SJohn Marino /* This package implements basic hash table functionality. It is possible 2186d7f5d3SJohn Marino to search for an entry, create an entry and destroy an entry. 2286d7f5d3SJohn Marino 2386d7f5d3SJohn Marino Elements in the table are generic pointers. 2486d7f5d3SJohn Marino 2586d7f5d3SJohn Marino The size of the table is not fixed; if the occupancy of the table 2686d7f5d3SJohn Marino grows too high the hash table will be expanded. 2786d7f5d3SJohn Marino 2886d7f5d3SJohn Marino The abstract data implementation is based on generalized Algorithm D 2986d7f5d3SJohn Marino from Knuth's book "The art of computer programming". Hash table is 3086d7f5d3SJohn Marino expanded by creation of new hash table and transferring elements from 3186d7f5d3SJohn Marino the old table to the new table. */ 3286d7f5d3SJohn Marino 3386d7f5d3SJohn Marino #ifndef __HASHTAB_H__ 3486d7f5d3SJohn Marino #define __HASHTAB_H__ 3586d7f5d3SJohn Marino 3686d7f5d3SJohn Marino #ifdef __cplusplus 3786d7f5d3SJohn Marino extern "C" { 3886d7f5d3SJohn Marino #endif /* __cplusplus */ 3986d7f5d3SJohn Marino 4086d7f5d3SJohn Marino #include "ansidecl.h" 4186d7f5d3SJohn Marino 4286d7f5d3SJohn Marino #ifndef GTY 4386d7f5d3SJohn Marino #define GTY(X) 4486d7f5d3SJohn Marino #endif 4586d7f5d3SJohn Marino 4686d7f5d3SJohn Marino /* The type for a hash code. */ 4786d7f5d3SJohn Marino typedef unsigned int hashval_t; 4886d7f5d3SJohn Marino 4986d7f5d3SJohn Marino /* Callback function pointer types. */ 5086d7f5d3SJohn Marino 5186d7f5d3SJohn Marino /* Calculate hash of a table entry. */ 5286d7f5d3SJohn Marino typedef hashval_t (*htab_hash) (const void *); 5386d7f5d3SJohn Marino 5486d7f5d3SJohn Marino /* Compare a table entry with a possible entry. The entry already in 5586d7f5d3SJohn Marino the table always comes first, so the second element can be of a 5686d7f5d3SJohn Marino different type (but in this case htab_find and htab_find_slot 5786d7f5d3SJohn Marino cannot be used; instead the variants that accept a hash value 5886d7f5d3SJohn Marino must be used). */ 5986d7f5d3SJohn Marino typedef int (*htab_eq) (const void *, const void *); 6086d7f5d3SJohn Marino 6186d7f5d3SJohn Marino /* Cleanup function called whenever a live element is removed from 6286d7f5d3SJohn Marino the hash table. */ 6386d7f5d3SJohn Marino typedef void (*htab_del) (void *); 6486d7f5d3SJohn Marino 6586d7f5d3SJohn Marino /* Function called by htab_traverse for each live element. The first 6686d7f5d3SJohn Marino arg is the slot of the element (which can be passed to htab_clear_slot 6786d7f5d3SJohn Marino if desired), the second arg is the auxiliary pointer handed to 6886d7f5d3SJohn Marino htab_traverse. Return 1 to continue scan, 0 to stop. */ 6986d7f5d3SJohn Marino typedef int (*htab_trav) (void **, void *); 7086d7f5d3SJohn Marino 7186d7f5d3SJohn Marino /* Memory-allocation function, with the same functionality as calloc(). 7286d7f5d3SJohn Marino Iff it returns NULL, the hash table implementation will pass an error 7386d7f5d3SJohn Marino code back to the user, so if your code doesn't handle errors, 7486d7f5d3SJohn Marino best if you use xcalloc instead. */ 7586d7f5d3SJohn Marino typedef void *(*htab_alloc) (size_t, size_t); 7686d7f5d3SJohn Marino 7786d7f5d3SJohn Marino /* We also need a free() routine. */ 7886d7f5d3SJohn Marino typedef void (*htab_free) (void *); 7986d7f5d3SJohn Marino 8086d7f5d3SJohn Marino /* Memory allocation and deallocation; variants which take an extra 8186d7f5d3SJohn Marino argument. */ 8286d7f5d3SJohn Marino typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t); 8386d7f5d3SJohn Marino typedef void (*htab_free_with_arg) (void *, void *); 8486d7f5d3SJohn Marino 8586d7f5d3SJohn Marino /* This macro defines reserved value for empty table entry. */ 8686d7f5d3SJohn Marino 8786d7f5d3SJohn Marino #define HTAB_EMPTY_ENTRY ((PTR) 0) 8886d7f5d3SJohn Marino 8986d7f5d3SJohn Marino /* This macro defines reserved value for table entry which contained 9086d7f5d3SJohn Marino a deleted element. */ 9186d7f5d3SJohn Marino 9286d7f5d3SJohn Marino #define HTAB_DELETED_ENTRY ((PTR) 1) 9386d7f5d3SJohn Marino 9486d7f5d3SJohn Marino /* Hash tables are of the following type. The structure 9586d7f5d3SJohn Marino (implementation) of this type is not needed for using the hash 9686d7f5d3SJohn Marino tables. All work with hash table should be executed only through 9786d7f5d3SJohn Marino functions mentioned below. The size of this structure is subject to 9886d7f5d3SJohn Marino change. */ 9986d7f5d3SJohn Marino 10086d7f5d3SJohn Marino struct GTY(()) htab { 10186d7f5d3SJohn Marino /* Pointer to hash function. */ 10286d7f5d3SJohn Marino htab_hash hash_f; 10386d7f5d3SJohn Marino 10486d7f5d3SJohn Marino /* Pointer to comparison function. */ 10586d7f5d3SJohn Marino htab_eq eq_f; 10686d7f5d3SJohn Marino 10786d7f5d3SJohn Marino /* Pointer to cleanup function. */ 10886d7f5d3SJohn Marino htab_del del_f; 10986d7f5d3SJohn Marino 11086d7f5d3SJohn Marino /* Table itself. */ 11186d7f5d3SJohn Marino void ** GTY ((use_param, length ("%h.size"))) entries; 11286d7f5d3SJohn Marino 11386d7f5d3SJohn Marino /* Current size (in entries) of the hash table. */ 11486d7f5d3SJohn Marino size_t size; 11586d7f5d3SJohn Marino 11686d7f5d3SJohn Marino /* Current number of elements including also deleted elements. */ 11786d7f5d3SJohn Marino size_t n_elements; 11886d7f5d3SJohn Marino 11986d7f5d3SJohn Marino /* Current number of deleted elements in the table. */ 12086d7f5d3SJohn Marino size_t n_deleted; 12186d7f5d3SJohn Marino 12286d7f5d3SJohn Marino /* The following member is used for debugging. Its value is number 12386d7f5d3SJohn Marino of all calls of `htab_find_slot' for the hash table. */ 12486d7f5d3SJohn Marino unsigned int searches; 12586d7f5d3SJohn Marino 12686d7f5d3SJohn Marino /* The following member is used for debugging. Its value is number 12786d7f5d3SJohn Marino of collisions fixed for time of work with the hash table. */ 12886d7f5d3SJohn Marino unsigned int collisions; 12986d7f5d3SJohn Marino 13086d7f5d3SJohn Marino /* Pointers to allocate/free functions. */ 13186d7f5d3SJohn Marino htab_alloc alloc_f; 13286d7f5d3SJohn Marino htab_free free_f; 13386d7f5d3SJohn Marino 13486d7f5d3SJohn Marino /* Alternate allocate/free functions, which take an extra argument. */ 13586d7f5d3SJohn Marino void * GTY((skip)) alloc_arg; 13686d7f5d3SJohn Marino htab_alloc_with_arg alloc_with_arg_f; 13786d7f5d3SJohn Marino htab_free_with_arg free_with_arg_f; 13886d7f5d3SJohn Marino 13986d7f5d3SJohn Marino /* Current size (in entries) of the hash table, as an index into the 14086d7f5d3SJohn Marino table of primes. */ 14186d7f5d3SJohn Marino unsigned int size_prime_index; 14286d7f5d3SJohn Marino }; 14386d7f5d3SJohn Marino 14486d7f5d3SJohn Marino typedef struct htab *htab_t; 14586d7f5d3SJohn Marino 14686d7f5d3SJohn Marino /* An enum saying whether we insert into the hash table or not. */ 14786d7f5d3SJohn Marino enum insert_option {NO_INSERT, INSERT}; 14886d7f5d3SJohn Marino 14986d7f5d3SJohn Marino /* The prototypes of the package functions. */ 15086d7f5d3SJohn Marino 15186d7f5d3SJohn Marino extern htab_t htab_create_alloc (size_t, htab_hash, 15286d7f5d3SJohn Marino htab_eq, htab_del, 15386d7f5d3SJohn Marino htab_alloc, htab_free); 15486d7f5d3SJohn Marino 15586d7f5d3SJohn Marino extern htab_t htab_create_alloc_ex (size_t, htab_hash, 15686d7f5d3SJohn Marino htab_eq, htab_del, 15786d7f5d3SJohn Marino void *, htab_alloc_with_arg, 15886d7f5d3SJohn Marino htab_free_with_arg); 15986d7f5d3SJohn Marino 16086d7f5d3SJohn Marino extern htab_t htab_create_typed_alloc (size_t, htab_hash, htab_eq, htab_del, 16186d7f5d3SJohn Marino htab_alloc, htab_alloc, htab_free); 16286d7f5d3SJohn Marino 16386d7f5d3SJohn Marino /* Backward-compatibility functions. */ 16486d7f5d3SJohn Marino extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del); 16586d7f5d3SJohn Marino extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del); 16686d7f5d3SJohn Marino 16786d7f5d3SJohn Marino extern void htab_set_functions_ex (htab_t, htab_hash, 16886d7f5d3SJohn Marino htab_eq, htab_del, 16986d7f5d3SJohn Marino void *, htab_alloc_with_arg, 17086d7f5d3SJohn Marino htab_free_with_arg); 17186d7f5d3SJohn Marino 17286d7f5d3SJohn Marino extern void htab_delete (htab_t); 17386d7f5d3SJohn Marino extern void htab_empty (htab_t); 17486d7f5d3SJohn Marino 17586d7f5d3SJohn Marino extern void * htab_find (htab_t, const void *); 17686d7f5d3SJohn Marino extern void ** htab_find_slot (htab_t, const void *, enum insert_option); 17786d7f5d3SJohn Marino extern void * htab_find_with_hash (htab_t, const void *, hashval_t); 17886d7f5d3SJohn Marino extern void ** htab_find_slot_with_hash (htab_t, const void *, 17986d7f5d3SJohn Marino hashval_t, enum insert_option); 18086d7f5d3SJohn Marino extern void htab_clear_slot (htab_t, void **); 18186d7f5d3SJohn Marino extern void htab_remove_elt (htab_t, void *); 18286d7f5d3SJohn Marino extern void htab_remove_elt_with_hash (htab_t, void *, hashval_t); 18386d7f5d3SJohn Marino 18486d7f5d3SJohn Marino extern void htab_traverse (htab_t, htab_trav, void *); 18586d7f5d3SJohn Marino extern void htab_traverse_noresize (htab_t, htab_trav, void *); 18686d7f5d3SJohn Marino 18786d7f5d3SJohn Marino extern size_t htab_size (htab_t); 18886d7f5d3SJohn Marino extern size_t htab_elements (htab_t); 18986d7f5d3SJohn Marino extern double htab_collisions (htab_t); 19086d7f5d3SJohn Marino 19186d7f5d3SJohn Marino /* A hash function for pointers. */ 19286d7f5d3SJohn Marino extern htab_hash htab_hash_pointer; 19386d7f5d3SJohn Marino 19486d7f5d3SJohn Marino /* An equality function for pointers. */ 19586d7f5d3SJohn Marino extern htab_eq htab_eq_pointer; 19686d7f5d3SJohn Marino 19786d7f5d3SJohn Marino /* A hash function for null-terminated strings. */ 19886d7f5d3SJohn Marino extern hashval_t htab_hash_string (const void *); 19986d7f5d3SJohn Marino 20086d7f5d3SJohn Marino /* An iterative hash function for arbitrary data. */ 20186d7f5d3SJohn Marino extern hashval_t iterative_hash (const void *, size_t, hashval_t); 20286d7f5d3SJohn Marino /* Shorthand for hashing something with an intrinsic size. */ 20386d7f5d3SJohn Marino #define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT) 20486d7f5d3SJohn Marino 20586d7f5d3SJohn Marino #ifdef __cplusplus 20686d7f5d3SJohn Marino } 20786d7f5d3SJohn Marino #endif /* __cplusplus */ 20886d7f5d3SJohn Marino 20986d7f5d3SJohn Marino #endif /* __HASHTAB_H */ 210