From cd50723cf544f7091fb0acd86390e60fa25f661c Mon Sep 17 00:00:00 2001 From: Daniele Di Proietto Date: Wed, 16 Jul 2014 10:46:20 -0700 Subject: cmap: Fix cmap_next_position() cmap_next_position() didn't update the node pointer while iterating through a list of nodes with the same hash. This commit fixes the bug and improve test-cmap to detect it. Signed-off-by: Daniele Di Proietto Signed-off-by: Ben Pfaff --- lib/cmap.c | 2 +- tests/test-cmap.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/cmap.c b/lib/cmap.c index 0a791328c..5d6dbcfdc 100644 --- a/lib/cmap.c +++ b/lib/cmap.c @@ -854,7 +854,7 @@ cmap_next_position(const struct cmap *cmap, const struct cmap_node *node = cmap_node_next(&b->nodes[entry]); unsigned int i; - for (i = 0; node; i++) { + for (i = 0; node; i++, node = cmap_node_next(node)) { if (i == offset) { if (cmap_node_next(node)) { offset++; diff --git a/tests/test-cmap.c b/tests/test-cmap.c index 46c00e14e..a034ec9a9 100644 --- a/tests/test-cmap.c +++ b/tests/test-cmap.c @@ -55,14 +55,19 @@ static void check_cmap(struct cmap *cmap, const int values[], size_t n, hash_func *hash) { - int *sort_values, *cmap_values; + int *sort_values, *cmap_values, *cmap_values2; const struct element *e; size_t i; + struct cmap_position pos = { 0, 0, 0 }; + struct cmap_node *node; + /* Check that all the values are there in iteration. */ sort_values = xmalloc(sizeof *sort_values * n); cmap_values = xmalloc(sizeof *sort_values * n); + cmap_values2 = xmalloc(sizeof *sort_values * n); + /* Here we test cursor iteration */ i = 0; CMAP_FOR_EACH (e, node, cmap) { assert(i < n); @@ -70,14 +75,27 @@ check_cmap(struct cmap *cmap, const int values[], size_t n, } assert(i == n); + /* Here we test iteration with cmap_next_position() */ + i = 0; + while ((node = cmap_next_position(cmap, &pos))) { + struct element *e = OBJECT_CONTAINING(node, e, node); + + assert(i < n); + cmap_values2[i++] = e->value; + } + assert(i == n); + memcpy(sort_values, values, sizeof *sort_values * n); qsort(sort_values, n, sizeof *sort_values, compare_ints); qsort(cmap_values, n, sizeof *cmap_values, compare_ints); + qsort(cmap_values2, n, sizeof *cmap_values2, compare_ints); for (i = 0; i < n; i++) { assert(sort_values[i] == cmap_values[i]); + assert(sort_values[i] == cmap_values2[i]); } + free(cmap_values2); free(cmap_values); free(sort_values); -- cgit v1.2.1