From 96626a07ae084d613fd85fa9eb87fd8b3495af59 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 23 Feb 2024 15:25:19 +0100 Subject: [PATCH] added functions to iterate through hash table and remove hash entries --- src/libgame/hash.c | 103 +++++++++++++++++++++++++++++++++++++++++++++ src/libgame/hash.h | 60 ++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) diff --git a/src/libgame/hash.c b/src/libgame/hash.c index 89c7134f..2b856f68 100644 --- a/src/libgame/hash.c +++ b/src/libgame/hash.c @@ -483,3 +483,106 @@ hashtable_iterator_advance(struct hashtable_itr *itr) return -1; } + +/*****************************************************************************/ +/* call function for all hashtable entries */ +void +hashtable_foreach(struct hashtable *h, hashtable_fn fn, void *userdata) +{ + if (h == NULL) + return; + + if (hashtable_count(h) == 0) + return; + + struct hashtable_itr *itr = hashtable_iterator(h); + + do + { + fn(hashtable_iterator_key(itr), hashtable_iterator_value(itr), userdata); + } + while (hashtable_iterator_advance(itr)); + + free(itr); +} + +/*****************************************************************************/ +/* call function for all hashtable entries and remove them, if function returned 1 */ +unsigned int +hashtable_foreach_remove(struct hashtable *h, hashtable_remove_fn fn, void *userdata) +{ + if (h == NULL) + return 0; + + if (hashtable_count(h) == 0) + return 0; + + struct hashtable *remove = create_hashtable(h->hashfn, h->eqfn, NULL, NULL); + struct hashtable_itr *itr = hashtable_iterator(h); + + do + { + if (fn(hashtable_iterator_key(itr), hashtable_iterator_value(itr), userdata)) + hashtable_insert(remove, hashtable_iterator_key(itr), "1"); + } + while (hashtable_iterator_advance(itr)); + + free(itr); + + struct hashtable_itr *itr_remove = hashtable_iterator(remove); + unsigned int num_removed = 0; + + do + { + hashtable_remove(h, hashtable_iterator_key(itr_remove)); + num_removed++; + } + while (hashtable_iterator_advance(itr_remove)); + + free(itr_remove); + + hashtable_destroy(remove); + + return num_removed; +} + +/*****************************************************************************/ +/* remove_all hashtable entries */ +unsigned int +hashtable_remove_all(struct hashtable *h) +{ + /* TODO: this function should directly remove all hashtable entries */ + + if (h == NULL) + return 0; + + if (hashtable_count(h) == 0) + return 0; + + struct hashtable *remove = create_hashtable(h->hashfn, h->eqfn, NULL, NULL); + struct hashtable_itr *itr = hashtable_iterator(h); + + do + { + hashtable_insert(remove, hashtable_iterator_key(itr), "1"); + } + while (hashtable_iterator_advance(itr)); + + free(itr); + + struct hashtable_itr *itr_remove = hashtable_iterator(remove); + unsigned int num_removed = 0; + + do + { + hashtable_remove(h, hashtable_iterator_key(itr_remove)); + num_removed++; + } + while (hashtable_iterator_advance(itr_remove)); + + free(itr_remove); + + hashtable_destroy(remove); + + return num_removed; +} diff --git a/src/libgame/hash.h b/src/libgame/hash.h index 8fe6f7fa..50806d44 100644 --- a/src/libgame/hash.h +++ b/src/libgame/hash.h @@ -297,4 +297,64 @@ hashtable_iterator_value(struct hashtable_itr *i); int hashtable_iterator_advance(struct hashtable_itr *itr); + +/*****************************************************************************/ +/* hashtable_fn - prototype of function to call for hashtable entry + + * @name hashtable_fn + * @param k the key of the current hash entry + * @param v the value of the current hash entry + * @param u additional user data + */ + +typedef void (*hashtable_fn) (void *k, void *v, void *u); + +/*****************************************************************************/ +/* hashtable_foreach - call function for all hashtable entries + + * @name hashtable_foreach + * @param h the hashtable to iterate through + * @param fn the function to call for each entry + */ + +void +hashtable_foreach(struct hashtable *h, hashtable_fn fn, void *userdata); + +/*****************************************************************************/ +/* hashtable_remove_fn - prototype of function to call for hashtable entry + + * @name hashtable_remove_fn + * @param k the key of the current hash entry + * @param v the value of the current hash entry + * @param u additional user data + * @return non-zero if entry should be removed, else zero + */ + +typedef int (*hashtable_remove_fn) (void *k, void *v, void *u); + +/*****************************************************************************/ +/* hashtable_foreach_remove - call function for all hashtable entries and remove them, + * if function returned 1 + * returns the number of removed entries + + * @name hashtable_foreach_remove + * @param h the hashtable to iterate through + * @param fn the function to call for each entry + * @return the number of removed entries + */ + +unsigned int +hashtable_foreach_remove(struct hashtable *h, hashtable_remove_fn fn, void *userdata); + +/*****************************************************************************/ +/* hashtable_remove_all - remove_all hashtable entries + + * @name hashtable_remove + * @param h the hashtable to remove all entries from + * @return the number of removed entries + */ + +unsigned int +hashtable_remove_all(struct hashtable *h); + #endif -- 2.34.1