summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog6
-rw-r--r--include/hashtab.h14
-rw-r--r--libiberty/ChangeLog6
-rw-r--r--libiberty/hashtab.c27
4 files changed, 49 insertions, 4 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index 5ab66bcba7a..a73e5fefb06 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+2000-03-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * hashtab.h (struct htab): Add del_f.
+ (htab_del): New type.
+ (htab_create): Add fourth argument.
+
2000-03-08 Zack Weinberg <zack@wolery.cumb.org>
* hashtab.h (hash_table_t): Rename to htab_t.
diff --git a/include/hashtab.h b/include/hashtab.h
index f17572af863..e6e38e4d058 100644
--- a/include/hashtab.h
+++ b/include/hashtab.h
@@ -47,6 +47,10 @@ typedef unsigned int (*htab_hash) PARAMS ((const void *));
the table always comes first. */
typedef int (*htab_eq) PARAMS ((const void *, const void *));
+/* Cleanup function called whenever a live element is removed from
+ the hash table. */
+typedef void (*htab_del) PARAMS ((void *));
+
/* Function called by htab_traverse for each live element. The first
arg is the element, the second arg is the auxiliary pointer handed
to htab_traverse. Return 1 to continue scan, 0 to stop. */
@@ -62,10 +66,13 @@ struct htab
/* Pointer to hash function. */
htab_hash hash_f;
- /* Pointer to comparison function. */
+ /* Pointer to comparison function. */
htab_eq eq_f;
- /* Table itself */
+ /* Pointer to cleanup function. */
+ htab_del del_f;
+
+ /* Table itself. */
void **entries;
/* Current size (in entries) of the hash table */
@@ -90,7 +97,8 @@ typedef struct htab *htab_t;
/* The prototypes of the package functions. */
-extern htab_t htab_create PARAMS ((size_t, htab_hash, htab_eq));
+extern htab_t htab_create PARAMS ((size_t, htab_hash,
+ htab_eq, htab_del));
extern void htab_delete PARAMS ((htab_t));
extern void htab_empty PARAMS ((htab_t));
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index c0f59a89716..a9d849c3970 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,9 @@
+2000-03-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * hashtab.c (htab_create): Set del_f.
+ (htab_delete, htab_empty, htab_remove_elt, htab_clear_slot):
+ Use it.
+
2000-03-08 Zack Weinberg <zack@wolery.cumb.org>
* hashtab.c: Remove debugging variables (all_searches,
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index ea9f9d38ac7..0bc9e485ef0 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -88,10 +88,11 @@ higher_prime_number (n)
created hash table. */
htab_t
-htab_create (size, hash_f, eq_f)
+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_t result;
@@ -101,6 +102,7 @@ htab_create (size, hash_f, eq_f)
result->size = size;
result->hash_f = hash_f;
result->eq_f = eq_f;
+ result->del_f = del_f;
return result;
}
@@ -111,6 +113,15 @@ void
htab_delete (htab)
htab_t htab;
{
+ int i;
+ if (htab->del_f)
+ for (i = htab->size - 1; i >= 0; i--)
+ {
+ if (htab->entries[i] != EMPTY_ENTRY
+ && htab->entries[i] != DELETED_ENTRY)
+ (*htab->del_f) (htab->entries[i]);
+ }
+
free (htab->entries);
free (htab);
}
@@ -121,6 +132,15 @@ void
htab_empty (htab)
htab_t htab;
{
+ int i;
+ if (htab->del_f)
+ for (i = htab->size - 1; i >= 0; i--)
+ {
+ if (htab->entries[i] != EMPTY_ENTRY
+ && htab->entries[i] != DELETED_ENTRY)
+ (*htab->del_f) (htab->entries[i]);
+ }
+
memset (htab->entries, 0, htab->size * sizeof (void *));
}
@@ -273,6 +293,9 @@ htab_remove_elt (htab, element)
if (*slot == EMPTY_ENTRY)
return;
+ if (htab->del_f)
+ (*htab->del_f) (*slot);
+
*slot = DELETED_ENTRY;
htab->n_deleted++;
}
@@ -289,6 +312,8 @@ htab_clear_slot (htab, slot)
if (slot < htab->entries || slot >= htab->entries + htab->size
|| *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY)
abort ();
+ if (htab->del_f)
+ (*htab->del_f) (*slot);
*slot = DELETED_ENTRY;
htab->n_deleted++;
}