diff options
author | Adrian Moreno <amorenoz@redhat.com> | 2022-03-23 12:56:19 +0100 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2022-03-30 20:14:21 +0200 |
commit | 019895b83230a3e7df78372d1ae96aec7b31504a (patch) | |
tree | 1590402c5f5e942c9b1b3aa824462791e0d1ecea | |
parent | 9f176f7025cd3dab688592c5722d1d236127a19d (diff) | |
download | openvswitch-019895b83230a3e7df78372d1ae96aec7b31504a.tar.gz |
hindex: use multi-variable iterators.
Re-write hindex's loops using multi-variable helpers.
For safe loops, use the LONG version to maintain backwards
compatibility.
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
-rw-r--r-- | lib/hindex.h | 45 | ||||
-rw-r--r-- | tests/test-hindex.c | 6 |
2 files changed, 32 insertions, 19 deletions
diff --git a/lib/hindex.h b/lib/hindex.h index 876c5a9e3..f7a30d511 100644 --- a/lib/hindex.h +++ b/lib/hindex.h @@ -128,18 +128,22 @@ void hindex_remove(struct hindex *, struct hindex_node *); * Evaluates HASH only once. */ #define HINDEX_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HINDEX) \ - for (INIT_CONTAINER(NODE, hindex_node_with_hash(HINDEX, HASH), MEMBER); \ - NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ - ASSIGN_CONTAINER(NODE, (NODE)->MEMBER.s, MEMBER)) + for (INIT_MULTIVAR(NODE, MEMBER, hindex_node_with_hash(HINDEX, HASH), \ + struct hindex_node); \ + CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ + UPDATE_MULTIVAR(NODE, ITER_VAR(NODE)->s)) /* Safe when NODE may be freed (not needed when NODE may be removed from the * hash map but its members remain accessible and intact). */ -#define HINDEX_FOR_EACH_WITH_HASH_SAFE(NODE, NEXT, MEMBER, HASH, HINDEX) \ - for (INIT_CONTAINER(NODE, hindex_node_with_hash(HINDEX, HASH), MEMBER); \ - (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \ - ? INIT_CONTAINER(NEXT, (NODE)->MEMBER.s, MEMBER), 1 \ - : 0); \ - (NODE) = (NEXT)) +#define HINDEX_FOR_EACH_WITH_HASH_SAFE(NODE, NEXT, MEMBER, HASH, HINDEX) \ + for (INIT_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ + hindex_node_with_hash(HINDEX, HASH), \ + struct hindex_node); \ + CONDITION_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ + ITER_VAR(NODE) != NULL, \ + ITER_VAR(NEXT) = ITER_VAR(NODE)->s, \ + ITER_VAR(NEXT) != NULL); \ + UPDATE_MULTIVAR_SAFE_LONG(NODE, NEXT)) /* Returns the head node in 'hindex' with the given 'hash', or a null pointer * if no nodes have that hash value. */ @@ -157,19 +161,22 @@ hindex_node_with_hash(const struct hindex *hindex, size_t hash) /* Iteration. */ /* Iterates through every node in HINDEX. */ -#define HINDEX_FOR_EACH(NODE, MEMBER, HINDEX) \ - for (INIT_CONTAINER(NODE, hindex_first(HINDEX), MEMBER); \ - NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ - ASSIGN_CONTAINER(NODE, hindex_next(HINDEX, &(NODE)->MEMBER), MEMBER)) +#define HINDEX_FOR_EACH(NODE, MEMBER, HINDEX) \ + for (INIT_MULTIVAR(NODE, MEMBER, hindex_first(HINDEX), \ + struct hindex_node); \ + CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ + UPDATE_MULTIVAR(NODE, hindex_next(HINDEX, ITER_VAR(NODE)))) /* Safe when NODE may be freed (not needed when NODE may be removed from the * hash index but its members remain accessible and intact). */ -#define HINDEX_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HINDEX) \ - for (INIT_CONTAINER(NODE, hindex_first(HINDEX), MEMBER); \ - (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \ - ? INIT_CONTAINER(NEXT, hindex_next(HINDEX, &(NODE)->MEMBER), MEMBER), 1 \ - : 0); \ - (NODE) = (NEXT)) +#define HINDEX_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HINDEX) \ + for (INIT_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, hindex_first(HINDEX), \ + struct hindex_node); \ + CONDITION_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ + ITER_VAR(NODE) != NULL, \ + ITER_VAR(NEXT) = hindex_next(HINDEX, ITER_VAR(NODE)), \ + ITER_VAR(NEXT) != NULL); \ + UPDATE_MULTIVAR_SAFE_LONG(NODE, NEXT)) struct hindex_node *hindex_first(const struct hindex *); struct hindex_node *hindex_next(const struct hindex *, diff --git a/tests/test-hindex.c b/tests/test-hindex.c index af06be5fc..95e49284e 100644 --- a/tests/test-hindex.c +++ b/tests/test-hindex.c @@ -265,6 +265,11 @@ test_hindex_for_each_safe(hash_func *hash) i = 0; n_remaining = n; HINDEX_FOR_EACH_SAFE (e, next, node, &hindex) { + if (hindex_next(&hindex, &e->node) == NULL) { + assert(next == NULL); + } else { + assert(&next->node == hindex_next(&hindex, &e->node)); + } assert(i < n); if (pattern & (1ul << e->value)) { size_t j; @@ -281,6 +286,7 @@ test_hindex_for_each_safe(hash_func *hash) i++; } assert(i == n); + assert(next == NULL); for (i = 0; i < n; i++) { if (pattern & (1ul << i)) { |