From: Mathieu Desnoyers Date: Wed, 9 Nov 2011 21:18:42 +0000 (-0500) Subject: Add hash table iterator macros X-Git-Tag: v0.7.0~43^2~52 X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=commitdiff_plain;h=6d3201268d1d5f42ae79ddbca1d5a5b983cc49ba Add hash table iterator macros Signed-off-by: Mathieu Desnoyers --- diff --git a/tests/test_urcu_hash.c b/tests/test_urcu_hash.c index 87c4ad1..554f1e9 100644 --- a/tests/test_urcu_hash.c +++ b/tests/test_urcu_hash.c @@ -711,14 +711,12 @@ void test_delete_all_nodes(struct cds_lfht *ht) struct lfht_test_node *node; unsigned long count = 0; - cds_lfht_first(ht, &iter); - while ((node = cds_lfht_iter_get_test_node(&iter)) != NULL) { + cds_lfht_for_each_entry(ht, &iter, node, node) { int ret; ret = cds_lfht_del(test_ht, &iter); assert(!ret); call_rcu(&node->head, free_node_cb); - cds_lfht_next(ht, &iter); count++; } printf("deleted %lu nodes.\n", count); diff --git a/urcu/rculfhash.h b/urcu/rculfhash.h index 6e4f604..37eaccf 100644 --- a/urcu/rculfhash.h +++ b/urcu/rculfhash.h @@ -26,6 +26,7 @@ */ #include +#include #include #ifdef __cplusplus @@ -361,6 +362,43 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_iter *iter); */ void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); +/* + * Note: cds_lfht_for_each are safe for element removal during + * iteration. + */ +#define cds_lfht_for_each(ht, iter, node) \ + for (cds_lfht_first(ht, iter), \ + node = cds_lfht_iter_get_node(iter); \ + node != NULL; \ + cds_lfht_next(ht, iter), \ + node = cds_lfht_iter_get_node(iter)) + +#define cds_lfht_for_each_duplicate(ht, match, hash, key, iter, node) \ + for (cds_lfht_lookup(ht, match, hash, key, iter), \ + node = cds_lfht_iter_get_node(iter); \ + node != NULL; \ + cds_lfht_next_duplicate(ht, match, key, iter), \ + node = cds_lfht_iter_get_node(iter)) + +#define cds_lfht_for_each_entry(ht, iter, pos, member) \ + for (cds_lfht_first(ht, iter), \ + pos = caa_container_of(cds_lfht_iter_get_node(iter), \ + typeof(*(pos)), member); \ + &pos->member != NULL; \ + cds_lfht_next(ht, iter), \ + pos = caa_container_of(cds_lfht_iter_get_node(iter), \ + typeof(*(pos)), member)) + +#define cds_lfht_for_each_entry_duplicate(ht, match, hash, key, \ + iter, pos, member) \ + for (cds_lfht_lookup(ht, match, hash, key, iter), \ + pos = caa_container_of(cds_lfht_iter_get_node(iter), \ + typeof(*(pos)), member); \ + &pos->member != NULL; \ + cds_lfht_next_duplicate(ht, match, key, iter), \ + pos = caa_container_of(cds_lfht_iter_get_node(iter), \ + typeof(*(pos)), member)) + #ifdef __cplusplus } #endif