From d3652db599cb3bf4101cf2e6cf42c764d65b6fb8 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sun, 11 Aug 2024 22:12:30 -0700 Subject: idhash: add nng_id_visit API This allows an efficient way to iterate over the entries stored in an ID hash. The iteration is fast, and requires no additional storage. The order of iteration is not guaranteed. --- src/supplemental/util/idhash.c | 6 +++++ src/supplemental/util/idhash_test.c | 48 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) (limited to 'src/supplemental') diff --git a/src/supplemental/util/idhash.c b/src/supplemental/util/idhash.c index cf48df3e..4ededa31 100644 --- a/src/supplemental/util/idhash.c +++ b/src/supplemental/util/idhash.c @@ -60,3 +60,9 @@ nng_id_alloc(nng_id_map *map, uint64_t *id, void *val) { return (nni_id_alloc(&map->m, id, val)); } + +bool +nng_id_visit(nng_id_map *map, uint64_t *id, void **valp, uint32_t *cursor) +{ + return (nni_id_visit(&map->m, id, valp, cursor)); +} diff --git a/src/supplemental/util/idhash_test.c b/src/supplemental/util/idhash_test.c index 5bbdc4fb..e0d472a0 100644 --- a/src/supplemental/util/idhash_test.c +++ b/src/supplemental/util/idhash_test.c @@ -182,6 +182,52 @@ test_id_set_out_of_range(void) nng_id_map_free(m); } +void +test_id_visit(void) +{ + nng_id_map *m; + int x, y; + uint64_t id1; + uint64_t id2; + int *v1; + int *v2; + uint32_t cursor = 0; + + NUTS_PASS(nng_id_map_alloc(&m, 10, 13, 0)); + + // We can insert outside the range forcibly. + NUTS_PASS(nng_id_set(m, 1, &x)); + NUTS_PASS(nng_id_set(m, 100, &y)); + NUTS_TRUE(nng_id_visit(m, &id1, (void **) &v1, &cursor)); + NUTS_ASSERT(id1 == 1 || id1 == 100); + NUTS_ASSERT(v1 == &x || v1 == &y); + NUTS_TRUE(nng_id_visit(m, &id2, (void **) &v2, &cursor)); + NUTS_ASSERT(id2 == 1 || id2 == 100); + NUTS_ASSERT(v2 == &x || v2 == &y); + NUTS_ASSERT(id1 != id2); + NUTS_ASSERT(v1 != v2); + NUTS_TRUE(!nng_id_visit(m, &id2, (void **) &v2, &cursor)); + nng_id_map_free(m); +} + +void +test_id_visit_out_of_range(void) +{ + nng_id_map *m; + int x, y; + uint64_t id1; + int *v1; + uint32_t cursor = 1000; + + NUTS_PASS(nng_id_map_alloc(&m, 10, 13, 0)); + + // We can insert outside the range forcibly. + NUTS_PASS(nng_id_set(m, 1, &x)); + NUTS_PASS(nng_id_set(m, 100, &y)); + NUTS_TRUE(!nng_id_visit(m, &id1, (void **) &v1, &cursor)); + nng_id_map_free(m); +} + #define STRESS_LOAD 50000 #define NUM_VALUES 1000 @@ -303,6 +349,8 @@ NUTS_TESTS = { { "id resize", test_id_resize }, { "id dynamic", test_id_dynamic }, { "id set out of range", test_id_set_out_of_range }, + { "id visit", test_id_visit }, + { "id visit out of range", test_id_visit_out_of_range }, { "id stress", test_id_stress }, { "id alloc long long", test_id_alloc_long_long }, { NULL, NULL }, -- cgit v1.2.3-70-g09d2