X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=libiberty%2Fhashtab.c;h=9f917c3571d96a6ebd1e472f85bb85787f715a6c;hb=75c6c844d9df37761e0e834df057b89e41816e55;hp=6e7a44b9c91d2865be3a6b4ba0e3eb43b81314b8;hpb=bb6a587dd383a443ab1b78669870f33cfbc117a2;p=deliverable%2Fbinutils-gdb.git diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c index 6e7a44b9c9..9f917c3571 100644 --- a/libiberty/hashtab.c +++ b/libiberty/hashtab.c @@ -1,6 +1,5 @@ /* An expandable hash tables datatype. - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. + Copyright (C) 1999-2019 Free Software Foundation, Inc. Contributed by Vladimir Makarov (vmakarov@cygnus.com). This file is part of the libiberty library. @@ -16,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* This package implements basic hash table functionality. It is possible to search for an entry, create an entry and destroy an entry. @@ -50,6 +49,9 @@ Boston, MA 02111-1307, USA. */ #ifdef HAVE_LIMITS_H #include #endif +#ifdef HAVE_INTTYPES_H +#include +#endif #ifdef HAVE_STDINT_H #include #endif @@ -64,23 +66,14 @@ Boston, MA 02111-1307, USA. */ #define CHAR_BIT 8 #endif -/* This macro defines reserved value for empty table entry. */ - -#define EMPTY_ENTRY ((PTR) 0) - -/* This macro defines reserved value for table entry which contained - a deleted element. */ - -#define DELETED_ENTRY ((PTR) 1) - -static unsigned int higher_prime_index PARAMS ((unsigned long)); -static hashval_t htab_mod_1 PARAMS ((hashval_t, hashval_t, hashval_t, int)); -static hashval_t htab_mod PARAMS ((hashval_t, htab_t)); -static hashval_t htab_mod_m2 PARAMS ((hashval_t, htab_t)); -static hashval_t hash_pointer PARAMS ((const void *)); -static int eq_pointer PARAMS ((const void *, const void *)); -static int htab_expand PARAMS ((htab_t)); -static PTR *find_empty_slot_for_expand PARAMS ((htab_t, hashval_t)); +static unsigned int higher_prime_index (unsigned long); +static hashval_t htab_mod_1 (hashval_t, hashval_t, hashval_t, int); +static hashval_t htab_mod (hashval_t, htab_t); +static hashval_t htab_mod_m2 (hashval_t, htab_t); +static hashval_t hash_pointer (const void *); +static int eq_pointer (const void *, const void *); +static int htab_expand (htab_t); +static PTR *find_empty_slot_for_expand (htab_t, hashval_t); /* At some point, we could make these be NULL, and modify the hash-table routines to handle NULL specially; that would avoid @@ -176,8 +169,7 @@ static struct prime_ent const prime_tab[] = { nearest prime number which is greater than N, and near a power of two. */ static unsigned int -higher_prime_index (n) - unsigned long n; +higher_prime_index (unsigned long n) { unsigned int low = 0; unsigned int high = sizeof(prime_tab) / sizeof(prime_tab[0]); @@ -201,49 +193,44 @@ higher_prime_index (n) return low; } -/* Returns a hash code for P. */ - -static hashval_t -hash_pointer (p) - const PTR p; -{ - return (hashval_t) ((long)p >> 3); -} - /* Returns non-zero if P1 and P2 are equal. */ static int -eq_pointer (p1, p2) - const PTR p1; - const PTR p2; +eq_pointer (const PTR p1, const PTR p2) { return p1 == p2; } -/* Return the current size of given hash table. */ -inline size_t -htab_size (htab) - htab_t htab; +/* The parens around the function names in the next two definitions + are essential in order to prevent macro expansions of the name. + The bodies, however, are expanded as expected, so they are not + recursive definitions. */ + +/* Return the current size of given hash table. */ + +#define htab_size(htab) ((htab)->size) + +size_t +(htab_size) (htab_t htab) { - return htab->size; + return htab_size (htab); } /* Return the current number of elements in given hash table. */ -inline size_t -htab_elements (htab) - htab_t htab; +#define htab_elements(htab) ((htab)->n_elements - (htab)->n_deleted) + +size_t +(htab_elements) (htab_t htab) { - return htab->n_elements - htab->n_deleted; + return htab_elements (htab); } /* Return X % Y. */ static inline hashval_t -htab_mod_1 (x, y, inv, shift) - hashval_t x, y, inv; - int shift; +htab_mod_1 (hashval_t x, hashval_t y, hashval_t inv, int shift) { /* The multiplicative inverses computed above are for 32-bit types, and requires that we be able to compute a highpart multiply. */ @@ -271,9 +258,7 @@ htab_mod_1 (x, y, inv, shift) /* Compute the primary hash for HASH given HTAB's current size. */ static inline hashval_t -htab_mod (hash, htab) - hashval_t hash; - htab_t htab; +htab_mod (hashval_t hash, htab_t htab) { const struct prime_ent *p = &prime_tab[htab->size_prime_index]; return htab_mod_1 (hash, p->prime, p->inv, p->shift); @@ -282,9 +267,7 @@ htab_mod (hash, htab) /* Compute the secondary hash for HASH given HTAB's current size. */ static inline hashval_t -htab_mod_m2 (hash, htab) - hashval_t hash; - htab_t htab; +htab_mod_m2 (hashval_t hash, htab_t htab) { const struct prime_ent *p = &prime_tab[htab->size_prime_index]; return 1 + htab_mod_1 (hash, p->prime - 2, p->inv_m2, p->shift); @@ -292,17 +275,25 @@ htab_mod_m2 (hash, htab) /* This function creates table with length slightly longer than given source length. Created hash table is initiated as empty (all the - hash table entries are EMPTY_ENTRY). The function returns the + hash table entries are HTAB_EMPTY_ENTRY). The function returns the created hash table, or NULL if memory allocation fails. */ htab_t -htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; - htab_alloc alloc_f; - htab_free free_f; +htab_create_alloc (size_t size, htab_hash hash_f, htab_eq eq_f, + htab_del del_f, htab_alloc alloc_f, htab_free free_f) +{ + return htab_create_typed_alloc (size, hash_f, eq_f, del_f, alloc_f, alloc_f, + free_f); +} + +/* As above, but uses the variants of ALLOC_F and FREE_F which accept + an extra argument. */ + +htab_t +htab_create_alloc_ex (size_t size, htab_hash hash_f, htab_eq eq_f, + htab_del del_f, void *alloc_arg, + htab_alloc_with_arg alloc_f, + htab_free_with_arg free_f) { htab_t result; unsigned int size_prime_index; @@ -310,14 +301,14 @@ htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f) size_prime_index = higher_prime_index (size); size = prime_tab[size_prime_index].prime; - result = (htab_t) (*alloc_f) (1, sizeof (struct htab)); + result = (htab_t) (*alloc_f) (alloc_arg, 1, sizeof (struct htab)); if (result == NULL) return NULL; - result->entries = (PTR *) (*alloc_f) (size, sizeof (PTR)); + result->entries = (PTR *) (*alloc_f) (alloc_arg, size, sizeof (PTR)); if (result->entries == NULL) { if (free_f != NULL) - (*free_f) (result); + (*free_f) (alloc_arg, result); return NULL; } result->size = size; @@ -325,24 +316,37 @@ htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f) result->hash_f = hash_f; result->eq_f = eq_f; result->del_f = del_f; - result->alloc_f = alloc_f; - result->free_f = free_f; + result->alloc_arg = alloc_arg; + result->alloc_with_arg_f = alloc_f; + result->free_with_arg_f = free_f; return result; } -/* As above, but use the variants of alloc_f and free_f which accept - an extra argument. */ +/* + +@deftypefn Supplemental htab_t htab_create_typed_alloc (size_t @var{size}, @ +htab_hash @var{hash_f}, htab_eq @var{eq_f}, htab_del @var{del_f}, @ +htab_alloc @var{alloc_tab_f}, htab_alloc @var{alloc_f}, @ +htab_free @var{free_f}) + +This function creates a hash table that uses two different allocators +@var{alloc_tab_f} and @var{alloc_f} to use for allocating the table itself +and its entries respectively. This is useful when variables of different +types need to be allocated with different allocators. + +The created hash table is slightly larger than @var{size} and it is +initially empty (all the hash table entries are @code{HTAB_EMPTY_ENTRY}). +The function returns the created hash table, or @code{NULL} if memory +allocation fails. + +@end deftypefn + +*/ htab_t -htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f, - free_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; - PTR alloc_arg; - htab_alloc_with_arg alloc_f; - htab_free_with_arg free_f; +htab_create_typed_alloc (size_t size, htab_hash hash_f, htab_eq eq_f, + htab_del del_f, htab_alloc alloc_tab_f, + htab_alloc alloc_f, htab_free free_f) { htab_t result; unsigned int size_prime_index; @@ -350,14 +354,14 @@ htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f, size_prime_index = higher_prime_index (size); size = prime_tab[size_prime_index].prime; - result = (htab_t) (*alloc_f) (alloc_arg, 1, sizeof (struct htab)); + result = (htab_t) (*alloc_tab_f) (1, sizeof (struct htab)); if (result == NULL) return NULL; - result->entries = (PTR *) (*alloc_f) (alloc_arg, size, sizeof (PTR)); + result->entries = (PTR *) (*alloc_f) (size, sizeof (PTR)); if (result->entries == NULL) { if (free_f != NULL) - (*free_f) (alloc_arg, result); + (*free_f) (result); return NULL; } result->size = size; @@ -365,23 +369,18 @@ htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f, result->hash_f = hash_f; result->eq_f = eq_f; result->del_f = del_f; - result->alloc_arg = alloc_arg; - result->alloc_with_arg_f = alloc_f; - result->free_with_arg_f = free_f; + result->alloc_f = alloc_f; + result->free_f = free_f; return result; } + /* Update the function pointers and allocation parameter in the htab_t. */ void -htab_set_functions_ex (htab, hash_f, eq_f, del_f, alloc_arg, alloc_f, free_f) - htab_t htab; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; - PTR alloc_arg; - htab_alloc_with_arg alloc_f; - htab_free_with_arg free_f; +htab_set_functions_ex (htab_t htab, htab_hash hash_f, htab_eq eq_f, + htab_del del_f, PTR alloc_arg, + htab_alloc_with_arg alloc_f, htab_free_with_arg free_f) { htab->hash_f = hash_f; htab->eq_f = eq_f; @@ -395,21 +394,13 @@ htab_set_functions_ex (htab, hash_f, eq_f, del_f, alloc_arg, alloc_f, free_f) #undef htab_create htab_t -htab_create (size, hash_f, eq_f, del_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; +htab_create (size_t size, htab_hash hash_f, htab_eq eq_f, htab_del del_f) { return htab_create_alloc (size, hash_f, eq_f, del_f, xcalloc, free); } htab_t -htab_try_create (size, hash_f, eq_f, del_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; +htab_try_create (size_t size, htab_hash hash_f, htab_eq eq_f, htab_del del_f) { return htab_create_alloc (size, hash_f, eq_f, del_f, calloc, free); } @@ -418,8 +409,7 @@ htab_try_create (size, hash_f, eq_f, del_f) Naturally the hash table must already exist. */ void -htab_delete (htab) - htab_t htab; +htab_delete (htab_t htab) { size_t size = htab_size (htab); PTR *entries = htab->entries; @@ -427,7 +417,7 @@ htab_delete (htab) if (htab->del_f) for (i = size - 1; i >= 0; i--) - if (entries[i] != EMPTY_ENTRY && entries[i] != DELETED_ENTRY) + if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY) (*htab->del_f) (entries[i]); if (htab->free_f != NULL) @@ -445,8 +435,7 @@ htab_delete (htab) /* This function clears all entries in the given hash table. */ void -htab_empty (htab) - htab_t htab; +htab_empty (htab_t htab) { size_t size = htab_size (htab); PTR *entries = htab->entries; @@ -454,10 +443,31 @@ htab_empty (htab) if (htab->del_f) for (i = size - 1; i >= 0; i--) - if (entries[i] != EMPTY_ENTRY && entries[i] != DELETED_ENTRY) + if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY) (*htab->del_f) (entries[i]); - memset (entries, 0, size * sizeof (PTR)); + /* Instead of clearing megabyte, downsize the table. */ + if (size > 1024*1024 / sizeof (PTR)) + { + int nindex = higher_prime_index (1024 / sizeof (PTR)); + int nsize = prime_tab[nindex].prime; + + if (htab->free_f != NULL) + (*htab->free_f) (htab->entries); + else if (htab->free_with_arg_f != NULL) + (*htab->free_with_arg_f) (htab->alloc_arg, htab->entries); + if (htab->alloc_with_arg_f != NULL) + htab->entries = (PTR *) (*htab->alloc_with_arg_f) (htab->alloc_arg, nsize, + sizeof (PTR *)); + else + htab->entries = (PTR *) (*htab->alloc_f) (nsize, sizeof (PTR *)); + htab->size = nsize; + htab->size_prime_index = nindex; + } + else + memset (entries, 0, size * sizeof (PTR)); + htab->n_deleted = 0; + htab->n_elements = 0; } /* Similar to htab_find_slot, but without several unwanted side effects: @@ -468,18 +478,16 @@ htab_empty (htab) HASH is the hash value for the element to be inserted. */ static PTR * -find_empty_slot_for_expand (htab, hash) - htab_t htab; - hashval_t hash; +find_empty_slot_for_expand (htab_t htab, hashval_t hash) { hashval_t index = htab_mod (hash, htab); size_t size = htab_size (htab); PTR *slot = htab->entries + index; hashval_t hash2; - if (*slot == EMPTY_ENTRY) + if (*slot == HTAB_EMPTY_ENTRY) return slot; - else if (*slot == DELETED_ENTRY) + else if (*slot == HTAB_DELETED_ENTRY) abort (); hash2 = htab_mod_m2 (hash, htab); @@ -490,9 +498,9 @@ find_empty_slot_for_expand (htab, hash) index -= size; slot = htab->entries + index; - if (*slot == EMPTY_ENTRY) + if (*slot == HTAB_EMPTY_ENTRY) return slot; - else if (*slot == DELETED_ENTRY) + else if (*slot == HTAB_DELETED_ENTRY) abort (); } } @@ -506,8 +514,7 @@ find_empty_slot_for_expand (htab, hash) expanded. If all goes well, it will return a non-zero value. */ static int -htab_expand (htab) - htab_t htab; +htab_expand (htab_t htab) { PTR *oentries; PTR *olimit; @@ -553,7 +560,7 @@ htab_expand (htab) { PTR x = *p; - if (x != EMPTY_ENTRY && x != DELETED_ENTRY) + if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) { PTR *q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x)); @@ -575,10 +582,7 @@ htab_expand (htab) element. It cannot be used to insert or delete an element. */ PTR -htab_find_with_hash (htab, element, hash) - htab_t htab; - const PTR element; - hashval_t hash; +htab_find_with_hash (htab_t htab, const PTR element, hashval_t hash) { hashval_t index, hash2; size_t size; @@ -589,8 +593,8 @@ htab_find_with_hash (htab, element, hash) index = htab_mod (hash, htab); entry = htab->entries[index]; - if (entry == EMPTY_ENTRY - || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))) + if (entry == HTAB_EMPTY_ENTRY + || (entry != HTAB_DELETED_ENTRY && (*htab->eq_f) (entry, element))) return entry; hash2 = htab_mod_m2 (hash, htab); @@ -602,8 +606,8 @@ htab_find_with_hash (htab, element, hash) index -= size; entry = htab->entries[index]; - if (entry == EMPTY_ENTRY - || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))) + if (entry == HTAB_EMPTY_ENTRY + || (entry != HTAB_DELETED_ENTRY && (*htab->eq_f) (entry, element))) return entry; } } @@ -612,27 +616,22 @@ htab_find_with_hash (htab, element, hash) element. */ PTR -htab_find (htab, element) - htab_t htab; - const PTR element; +htab_find (htab_t htab, const PTR element) { return htab_find_with_hash (htab, element, (*htab->hash_f) (element)); } /* This function searches for a hash table slot containing an entry equal to the given element. To delete an entry, call this with - INSERT = 0, then call htab_clear_slot on the slot returned (possibly - after doing some checks). To insert an entry, call this with - INSERT = 1, then write the value you want into the returned slot. - When inserting an entry, NULL may be returned if memory allocation - fails. */ + insert=NO_INSERT, then call htab_clear_slot on the slot returned + (possibly after doing some checks). To insert an entry, call this + with insert=INSERT, then write the value you want into the returned + slot. When inserting an entry, NULL may be returned if memory + allocation fails. */ PTR * -htab_find_slot_with_hash (htab, element, hash, insert) - htab_t htab; - const PTR element; - hashval_t hash; - enum insert_option insert; +htab_find_slot_with_hash (htab_t htab, const PTR element, + hashval_t hash, enum insert_option insert) { PTR *first_deleted_slot; hashval_t index, hash2; @@ -653,9 +652,9 @@ htab_find_slot_with_hash (htab, element, hash, insert) first_deleted_slot = NULL; entry = htab->entries[index]; - if (entry == EMPTY_ENTRY) + if (entry == HTAB_EMPTY_ENTRY) goto empty_entry; - else if (entry == DELETED_ENTRY) + else if (entry == HTAB_DELETED_ENTRY) first_deleted_slot = &htab->entries[index]; else if ((*htab->eq_f) (entry, element)) return &htab->entries[index]; @@ -669,9 +668,9 @@ htab_find_slot_with_hash (htab, element, hash, insert) index -= size; entry = htab->entries[index]; - if (entry == EMPTY_ENTRY) + if (entry == HTAB_EMPTY_ENTRY) goto empty_entry; - else if (entry == DELETED_ENTRY) + else if (entry == HTAB_DELETED_ENTRY) { if (!first_deleted_slot) first_deleted_slot = &htab->entries[index]; @@ -687,7 +686,7 @@ htab_find_slot_with_hash (htab, element, hash, insert) if (first_deleted_slot) { htab->n_deleted--; - *first_deleted_slot = EMPTY_ENTRY; + *first_deleted_slot = HTAB_EMPTY_ENTRY; return first_deleted_slot; } @@ -699,10 +698,7 @@ htab_find_slot_with_hash (htab, element, hash, insert) element. */ PTR * -htab_find_slot (htab, element, insert) - htab_t htab; - const PTR element; - enum insert_option insert; +htab_find_slot (htab_t htab, const PTR element, enum insert_option insert) { return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element), insert); @@ -713,9 +709,7 @@ htab_find_slot (htab, element, insert) element in the hash table, this function does nothing. */ void -htab_remove_elt (htab, element) - htab_t htab; - PTR element; +htab_remove_elt (htab_t htab, PTR element) { htab_remove_elt_with_hash (htab, element, (*htab->hash_f) (element)); } @@ -726,21 +720,18 @@ htab_remove_elt (htab, element) function does nothing. */ void -htab_remove_elt_with_hash (htab, element, hash) - htab_t htab; - PTR element; - hashval_t hash; +htab_remove_elt_with_hash (htab_t htab, PTR element, hashval_t hash) { PTR *slot; slot = htab_find_slot_with_hash (htab, element, hash, NO_INSERT); - if (*slot == EMPTY_ENTRY) + if (slot == NULL) return; if (htab->del_f) (*htab->del_f) (*slot); - *slot = DELETED_ENTRY; + *slot = HTAB_DELETED_ENTRY; htab->n_deleted++; } @@ -749,18 +740,16 @@ htab_remove_elt_with_hash (htab, element, hash) again. */ void -htab_clear_slot (htab, slot) - htab_t htab; - PTR *slot; +htab_clear_slot (htab_t htab, PTR *slot) { if (slot < htab->entries || slot >= htab->entries + htab_size (htab) - || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY) + || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY) abort (); if (htab->del_f) (*htab->del_f) (*slot); - *slot = DELETED_ENTRY; + *slot = HTAB_DELETED_ENTRY; htab->n_deleted++; } @@ -770,14 +759,11 @@ htab_clear_slot (htab, slot) argument. */ void -htab_traverse_noresize (htab, callback, info) - htab_t htab; - htab_trav callback; - PTR info; +htab_traverse_noresize (htab_t htab, htab_trav callback, PTR info) { PTR *slot; PTR *limit; - + slot = htab->entries; limit = slot + htab_size (htab); @@ -785,7 +771,7 @@ htab_traverse_noresize (htab, callback, info) { PTR x = *slot; - if (x != EMPTY_ENTRY && x != DELETED_ENTRY) + if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) if (!(*callback) (slot, info)) break; } @@ -796,12 +782,10 @@ htab_traverse_noresize (htab, callback, info) too empty to improve effectivity of subsequent calls. */ void -htab_traverse (htab, callback, info) - htab_t htab; - htab_trav callback; - PTR info; +htab_traverse (htab_t htab, htab_trav callback, PTR info) { - if (htab_elements (htab) * 8 < htab_size (htab)) + size_t size = htab_size (htab); + if (htab_elements (htab) * 8 < size && size > 32) htab_expand (htab); htab_traverse_noresize (htab, callback, info); @@ -811,8 +795,7 @@ htab_traverse (htab, callback, info) hash table. */ double -htab_collisions (htab) - htab_t htab; +htab_collisions (htab_t htab) { if (htab->searches == 0) return 0.0; @@ -846,8 +829,7 @@ htab_collisions (htab) function they just started using for Perl's hashes. */ hashval_t -htab_hash_string (p) - const PTR p; +htab_hash_string (const PTR p) { const unsigned char *str = (const unsigned char *) p; hashval_t r = 0; @@ -936,10 +918,11 @@ acceptable. Do NOT use for cryptographic purposes. -------------------------------------------------------------------- */ -hashval_t iterative_hash (k_in, length, initval) - const PTR k_in; /* the key */ - register size_t length; /* the length of the key */ - register hashval_t initval; /* the previous hash, or an arbitrary value */ +hashval_t +iterative_hash (const PTR k_in /* the key */, + register size_t length /* the length of the key */, + register hashval_t initval /* the previous hash, or + an arbitrary value */) { register const unsigned char *k = (const unsigned char *)k_in; register hashval_t a,b,c,len; @@ -978,17 +961,17 @@ hashval_t iterative_hash (k_in, length, initval) c += length; switch(len) /* all the case statements fall through */ { - case 11: c+=((hashval_t)k[10]<<24); - case 10: c+=((hashval_t)k[9]<<16); - case 9 : c+=((hashval_t)k[8]<<8); + case 11: c+=((hashval_t)k[10]<<24); /* fall through */ + case 10: c+=((hashval_t)k[9]<<16); /* fall through */ + case 9 : c+=((hashval_t)k[8]<<8); /* fall through */ /* the first byte of c is reserved for the length */ - case 8 : b+=((hashval_t)k[7]<<24); - case 7 : b+=((hashval_t)k[6]<<16); - case 6 : b+=((hashval_t)k[5]<<8); - case 5 : b+=k[4]; - case 4 : a+=((hashval_t)k[3]<<24); - case 3 : a+=((hashval_t)k[2]<<16); - case 2 : a+=((hashval_t)k[1]<<8); + case 8 : b+=((hashval_t)k[7]<<24); /* fall through */ + case 7 : b+=((hashval_t)k[6]<<16); /* fall through */ + case 6 : b+=((hashval_t)k[5]<<8); /* fall through */ + case 5 : b+=k[4]; /* fall through */ + case 4 : a+=((hashval_t)k[3]<<24); /* fall through */ + case 3 : a+=((hashval_t)k[2]<<16); /* fall through */ + case 2 : a+=((hashval_t)k[1]<<8); /* fall through */ case 1 : a+=k[0]; /* case 0: nothing left to add */ } @@ -996,3 +979,19 @@ hashval_t iterative_hash (k_in, length, initval) /*-------------------------------------------- report the result */ return c; } + +/* Returns a hash code for pointer P. Simplified version of evahash */ + +static hashval_t +hash_pointer (const PTR p) +{ + intptr_t v = (intptr_t) p; + unsigned a, b, c; + + a = b = 0x9e3779b9; + a += v >> (sizeof (intptr_t) * CHAR_BIT / 2); + b += v & (((intptr_t) 1 << (sizeof (intptr_t) * CHAR_BIT / 2)) - 1); + c = 0x42135234; + mix (a, b, c); + return c; +}