/* hash - hashing table processing.
- Copyright (C) 1998-2004, 2006-2007, 2009-2010 Free Software Foundation, Inc.
+ Copyright (C) 1998-2004, 2006-2007, 2009-2011 Free Software Foundation, Inc.
Written by Jim Meyering, 1992.
(unsigned long int) max_bucket_length);
}
+/* Hash KEY and return a pointer to the selected bucket.
+ If TABLE->hasher misbehaves, abort. */
+static struct hash_entry *
+safe_hasher (const Hash_table *table, const void *key)
+{
+ size_t n = table->hasher (key, table->n_buckets);
+ if (! (n < table->n_buckets))
+ abort ();
+ return table->bucket + n;
+}
+
/* If ENTRY matches an entry already in the hash table, return the
entry from the table. Otherwise, return NULL. */
void *
hash_lookup (const Hash_table *table, const void *entry)
{
- struct hash_entry const *bucket
- = table->bucket + table->hasher (entry, table->n_buckets);
+ struct hash_entry const *bucket = safe_hasher (table, entry);
struct hash_entry const *cursor;
- if (! (bucket < table->bucket_limit))
- abort ();
-
if (bucket->data == NULL)
return NULL;
void *
hash_get_next (const Hash_table *table, const void *entry)
{
- struct hash_entry const *bucket
- = table->bucket + table->hasher (entry, table->n_buckets);
+ struct hash_entry const *bucket = safe_hasher (table, entry);
struct hash_entry const *cursor;
- if (! (bucket < table->bucket_limit))
- abort ();
-
/* Find next entry in the same bucket. */
- for (cursor = bucket; cursor; cursor = cursor->next)
- if (cursor->data == entry && cursor->next)
- return cursor->next->data;
+ cursor = bucket;
+ do
+ {
+ if (cursor->data == entry && cursor->next)
+ return cursor->next->data;
+ cursor = cursor->next;
+ }
+ while (cursor != NULL);
/* Find first entry in any subsequent bucket. */
while (++bucket < table->bucket_limit)
hash_find_entry (Hash_table *table, const void *entry,
struct hash_entry **bucket_head, bool delete)
{
- struct hash_entry *bucket
- = table->bucket + table->hasher (entry, table->n_buckets);
+ struct hash_entry *bucket = safe_hasher (table, entry);
struct hash_entry *cursor;
- if (! (bucket < table->bucket_limit))
- abort ();
-
*bucket_head = bucket;
/* Test for empty bucket. */
for (cursor = bucket->next; cursor; cursor = next)
{
data = cursor->data;
- new_bucket = (dst->bucket + dst->hasher (data, dst->n_buckets));
-
- if (! (new_bucket < dst->bucket_limit))
- abort ();
+ new_bucket = safe_hasher (dst, data);
next = cursor->next;
bucket->next = NULL;
if (safe)
continue;
- new_bucket = (dst->bucket + dst->hasher (data, dst->n_buckets));
-
- if (! (new_bucket < dst->bucket_limit))
- abort ();
+ new_bucket = safe_hasher (dst, data);
if (new_bucket->data)
{