# include <config.h>
#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* HAVE_STRING_H */
#include <stdlib.h>
#include <assert.h>
#include "hash.h"
#ifdef STANDALONE
+# undef xmalloc
+# undef xrealloc
+# undef xfree
+
# define xmalloc malloc
# define xrealloc realloc
+# define xfree free
#endif
/* INTERFACE:
void
hash_table_destroy (struct hash_table *ht)
{
- free (ht->mappings);
- free (ht);
+ xfree (ht->mappings);
+ xfree (ht);
}
/* The heart of almost all functions in this file -- find the mapping
int needed_size = prime_size (ht->count * 3);
ht->size = MAX (old_size, needed_size);
+#if 0
printf ("growing from %d to %d\n", old_size, ht->size);
+#endif
ht->mappings = xmalloc (ht->size * sizeof (struct mapping));
memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
hash_table_put (ht, mp_key, mp->value);
}
assert (ht->count == old_count);
- free (old_mappings);
+ xfree (old_mappings);
}
/* Put VALUE in the hash table HT under the key KEY. This regrows the
void
hash_table_put (struct hash_table *ht, const void *key, void *value)
{
- /* Cannot use find_mapping here because we treat deleted entries
- specially. */
+ /* Cannot use find_mapping here because we're actually looking for
+ an *empty* entry. */
struct mapping *mappings = ht->mappings;
int size = ht->size;
mp->value = value;
break;
}
- else if (DELETED_ENTRY_P (mp_key))
+ else if (DELETED_ENTRY_P (mp_key)
+ || !ht->test_function (key, mp_key))
{
- /* We're replacing a deleteed entry, so ht->count gets
- increased, but ht->fullness remains unchanged. */
- ++ht->count;
- goto just_insert;
+ if (++location == size)
+ location = 0;
}
- else if (ht->test_function (key, mp_key))
+ else /* equal to key and not deleted */
{
/* We're replacing an existing entry, so ht->count and
ht->fullness remain unchanged. */
goto just_insert;
}
- else
- {
- if (++location == size)
- location = 0;
- }
}
if (ht->fullness * 4 > ht->size * 3)
/* When fullness exceeds 75% of size, regrow the table. */
if (hash_table_get_pair (ht, line, &line_copy, NULL))
{
hash_table_remove (ht, line);
- free (line_copy);
+ xfree (line_copy);
}
}
#endif