X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fhash.c;h=b3595ad4ce4517f8f4b50ab5a7ee847ae1513422;hb=edaa850fd2d2cae7ec31961fae3d56487e710c71;hp=89c7134f5906aa06d8a6cb24813eebf84f2d42af;hpb=afba55b62615e9b162159c0f7b0df602f27f69a7;p=rocksndiamonds.git diff --git a/src/libgame/hash.c b/src/libgame/hash.c index 89c7134f..b3595ad4 100644 --- a/src/libgame/hash.c +++ b/src/libgame/hash.c @@ -423,18 +423,24 @@ hashtable_iterator(struct hashtable *h) /* key - return the key of the (key, value) pair at the current position */ void * -hashtable_iterator_key(struct hashtable_itr *i) +hashtable_iterator_key(struct hashtable_itr *itr) { - return i->e->k; + if (itr == NULL || itr->e == NULL) + return NULL; + + return itr->e->k; } /*****************************************************************************/ /* value - return the value of the (key, value) pair at the current position */ void * -hashtable_iterator_value(struct hashtable_itr *i) +hashtable_iterator_value(struct hashtable_itr *itr) { - return i->e->v; + if (itr == NULL || itr->e == NULL) + return NULL; + + return itr->e->v; } /*****************************************************************************/ @@ -483,3 +489,110 @@ 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); + + unsigned int num_removed = 0; + + if (hashtable_count(remove) > 0) + { + struct hashtable_itr *itr_remove = hashtable_iterator(remove); + + 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; +}