X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fhash.c;h=0e4f2d61c744020fe88e9c1b409614d6320957da;hb=6b8b6deecb00631ea5f4bba04c739b9a19d29a4e;hp=54ba0ff6f958b0aeb2214d62fbcc09e2c678cc2b;hpb=de081c6520170bc7459b05c635a50e9c7c2ffedf;p=gnulib.git diff --git a/lib/hash.c b/lib/hash.c index 54ba0ff6f..0e4f2d61c 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -1,12 +1,4 @@ -/* Global assumptions: - - ANSI C - - a certain amount of library support, at least - - C ints are at least 32-bits long - */ - -/* Things to do: - - add a sample do_all function for listing the hash table. - */ +/* A generic hash table package. */ #include #include @@ -15,17 +7,13 @@ #include "hash.h" #ifdef USE_OBSTACK -/* This macro assumes that there is an HT with an initialized - HT_OBSTACK in scope. */ -# define ZALLOC(n) obstack_alloc (&(ht->ht_obstack), (n)) +# define ZALLOC(Ht, N) obstack_alloc (&(ht->ht_obstack), (N)) #else -# define ZALLOC(n) malloc ((n)) +# define ZALLOC(Ht, N) malloc ((N)) #endif #define BUCKET_HEAD(ht, idx) ((ht)->hash_table[(idx)]) -static void hash_free_0 (HT *, int); - static int is_prime (candidate) unsigned long candidate; @@ -78,7 +66,7 @@ hash_allocate_entry (HT *ht) } else { - new = (HASH_ENT *) ZALLOC (sizeof (HASH_ENT)); + new = (HASH_ENT *) ZALLOC (ht, sizeof (HASH_ENT)); } return new; } @@ -89,6 +77,53 @@ hash_get_n_slots_used (const HT *ht) return ht->hash_n_slots_used; } +/* Free all storage associated with HT that functions in this package + have allocated. If a key_freer function has been supplied (when HT + was created), this function applies it to the key of each entry before + freeing that entry. */ + +static void +hash_free_0 (HT *ht, int free_user_data) +{ + if (free_user_data && ht->hash_key_freer != NULL) + { + unsigned int i; + + for (i = 0; i < ht->hash_table_size; i++) + { + HASH_ENT *p; + HASH_ENT *next; + + for (p = BUCKET_HEAD (ht, i); p; p = next) + { + next = p->next; + ht->hash_key_freer (p->key); + } + } + } + +#ifdef USE_OBSTACK + obstack_free (&(ht->ht_obstack), NULL); +#else + { + unsigned int i; + for (i = 0; i < ht->hash_table_size; i++) + { + HASH_ENT *p; + HASH_ENT *next; + + for (p = BUCKET_HEAD (ht, i); p; p = next) + { + next = p->next; + free (p); + } + } + } +#endif + ht->hash_free_entry_list = NULL; + free (ht->hash_table); +} + /* FIXME-comment */ int @@ -182,10 +217,7 @@ hash_get_table_size (const HT *ht) - if KEY_COMPARATOR or HASH is null - if it was unable to allocate sufficient storage for the hash table - if WHEN_TO_REHASH is zero or negative - Otherwise it returns zero. - - FIXME: tell what happens to any existing hash table when this - function is called (e.g. a second time). */ + Otherwise it returns zero. */ HT * hash_initialize (unsigned int candidate_table_size, @@ -625,53 +657,6 @@ hash_clear (HT *ht) ht->hash_dirty_max_chain_length = 0; } -/* Free all storage associated with HT that functions in this package - have allocated. If a key_freer function has been supplied (when HT - was created), this function applies it to the key of each entry before - freeing that entry. */ - -static void -hash_free_0 (HT *ht, int free_user_data) -{ - if (free_user_data && ht->hash_key_freer != NULL) - { - unsigned int i; - - for (i = 0; i < ht->hash_table_size; i++) - { - HASH_ENT *p; - HASH_ENT *next; - - for (p = BUCKET_HEAD (ht, i); p; p = next) - { - next = p->next; - ht->hash_key_freer (p->key); - } - } - } - -#ifdef USE_OBSTACK - obstack_free (&(ht->ht_obstack), NULL); -#else - { - unsigned int i; - for (i = 0; i < ht->hash_table_size; i++) - { - HASH_ENT *p; - HASH_ENT *next; - - for (p = BUCKET_HEAD (ht, i); p; p = next) - { - next = p->next; - free (p); - } - } - } -#endif - ht->hash_free_entry_list = NULL; - free (ht->hash_table); -} - void hash_free (HT *ht) {