diff options
-rw-r--r-- | include/ChangeLog | 6 | ||||
-rw-r--r-- | include/hashtab.h | 14 | ||||
-rw-r--r-- | libiberty/ChangeLog | 6 | ||||
-rw-r--r-- | libiberty/hashtab.c | 27 |
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++; } |