aboutsummaryrefslogtreecommitdiff
path: root/src/supplemental/util
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2025-01-04 14:25:44 -0800
committerGarrett D'Amore <garrett@damore.org>2025-01-04 16:40:37 -0800
commita40b421d39a64c285a4ac23304538690aaa90739 (patch)
tree8b55dad260cafe6c02938fd1850f0a2e88e776ce /src/supplemental/util
parent7cdba9654117b4be1bf43925c10bae1a2a510cfa (diff)
downloadnng-a40b421d39a64c285a4ac23304538690aaa90739.tar.gz
nng-a40b421d39a64c285a4ac23304538690aaa90739.tar.bz2
nng-a40b421d39a64c285a4ac23304538690aaa90739.zip
api: Promote idhash supplemental API to core
Diffstat (limited to 'src/supplemental/util')
-rw-r--r--src/supplemental/util/CMakeLists.txt4
-rw-r--r--src/supplemental/util/idhash.c68
-rw-r--r--src/supplemental/util/idhash_test.c357
3 files changed, 1 insertions, 428 deletions
diff --git a/src/supplemental/util/CMakeLists.txt b/src/supplemental/util/CMakeLists.txt
index 69afd9e0..d7541363 100644
--- a/src/supplemental/util/CMakeLists.txt
+++ b/src/supplemental/util/CMakeLists.txt
@@ -7,9 +7,7 @@
# found online at https://opensource.org/licenses/MIT.
#
-nng_sources(idhash.c options.c)
+nng_sources(options.c)
nng_headers(
- nng/supplemental/util/idhash.h
nng/supplemental/util/options.h)
-nng_test(idhash_test)
nng_test(options_test)
diff --git a/src/supplemental/util/idhash.c b/src/supplemental/util/idhash.c
deleted file mode 100644
index 4ededa31..00000000
--- a/src/supplemental/util/idhash.c
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
-//
-// This software is supplied under the terms of the MIT License, a
-// copy of which should be located in the distribution where this
-// file was obtained (LICENSE.txt). A copy of the license may also be
-// found online at https://opensource.org/licenses/MIT.
-//
-
-#include <nng/nng.h>
-#include <nng/supplemental/util/idhash.h>
-
-#include "core/nng_impl.h"
-
-struct nng_id_map_s {
- nni_id_map m;
-};
-
-int
-nng_id_map_alloc(nng_id_map **map, uint64_t lo, uint64_t hi, int flags)
-{
- nng_id_map *m;
-
- if ((m = NNI_ALLOC_STRUCT(m)) == NULL) {
- return (NNG_ENOMEM);
- }
- nni_id_map_init(
- &m->m, lo, hi, (flags & NNG_MAP_RANDOM) ? true : false);
- *map = m;
- return (0);
-}
-
-void
-nng_id_map_free(nng_id_map *map)
-{
- nni_id_map_fini(&map->m);
- NNI_FREE_STRUCT(map);
-}
-
-void *
-nng_id_get(nng_id_map *map, uint64_t id)
-{
- return (nni_id_get(&map->m, id));
-}
-
-int
-nng_id_set(nng_id_map *map, uint64_t id, void *val)
-{
- return (nni_id_set(&map->m, id, val));
-}
-
-int
-nng_id_remove(nng_id_map *map, uint64_t id)
-{
- return (nni_id_remove(&map->m, id));
-}
-
-int
-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
deleted file mode 100644
index e0d472a0..00000000
--- a/src/supplemental/util/idhash_test.c
+++ /dev/null
@@ -1,357 +0,0 @@
-//
-// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
-//
-// This software is supplied under the terms of the MIT License, a
-// copy of which should be located in the distribution where this
-// file was obtained (LICENSE.txt). A copy of the license may also be
-// found online at https://opensource.org/licenses/MIT.
-//
-
-#include <nuts.h>
-
-#include <nng/supplemental/util/idhash.h>
-
-void
-test_id_basic(void)
-{
- nng_id_map *m;
- char *five = "five";
- char *four = "four";
-
- NUTS_PASS(nng_id_map_alloc(&m, 0, 0, 0));
-
- // insert it
- NUTS_PASS(nng_id_set(m, 5, five));
- // retrieve it
- NUTS_TRUE(nng_id_get(m, 5) == five);
-
- // change it
- NUTS_PASS(nng_id_set(m, 5, four));
- NUTS_TRUE(nng_id_get(m, 5) == four);
-
- // delete
- NUTS_PASS(nng_id_remove(m, 5));
-
- nng_id_map_free(m);
-}
-
-void
-test_id_random(void)
-{
- int i;
- uint64_t id;
- for (i = 0; i < 2; i++) {
- nng_id_map *m;
- NUTS_PASS(nng_id_map_alloc(&m, 0, 0, NNG_MAP_RANDOM));
- NUTS_PASS(nng_id_alloc(m, &id, &id));
- nng_id_map_free(m);
- NUTS_TRUE(id != 0);
- if (id != 1) {
- break;
- }
- // one chance in 4 billion, but try again
- }
-
- NUTS_TRUE(id != 1);
- NUTS_TRUE(i < 2);
-}
-
-void
-test_id_collision(void)
-{
- nng_id_map *m;
- char *five = "five";
- char *four = "four";
-
- NUTS_PASS(nng_id_map_alloc(&m, 0, 0, 0));
-
- // Carefully crafted -- 13 % 8 == 5.
- NUTS_PASS(nng_id_set(m, 5, five));
- NUTS_PASS(nng_id_set(m, 13, four));
- NUTS_TRUE(nng_id_get(m, 5) == five);
- NUTS_TRUE(nng_id_get(m, 13) == four);
-
- // Delete the intermediate
- NUTS_PASS(nng_id_remove(m, 5));
- NUTS_TRUE(nng_id_get(m, 13) == four);
-
- nng_id_map_free(m);
-}
-
-void
-test_id_empty(void)
-{
- nng_id_map *m;
-
- NUTS_PASS(nng_id_map_alloc(&m, 0, 0, 0));
-
- NUTS_TRUE(nng_id_get(m, 42) == NULL);
- NUTS_FAIL(nng_id_remove(m, 42), NNG_ENOENT);
- NUTS_FAIL(nng_id_remove(m, 1), NNG_ENOENT);
- nng_id_map_free(m);
-}
-
-void
-test_id_not_found(void)
-{
- nng_id_map *m;
- uint64_t id;
-
- NUTS_PASS(nng_id_map_alloc(&m, 0, 0, 0));
-
- NUTS_PASS(nng_id_alloc(m, &id, &id));
- NUTS_FAIL(nng_id_remove(m, 42), NNG_ENOENT);
- NUTS_FAIL(nng_id_remove(m, 2), NNG_ENOENT);
- NUTS_PASS(nng_id_remove(m, id));
- nng_id_map_free(m);
-}
-
-void
-test_id_resize(void)
-{
- nng_id_map *m;
- int rv;
- int i;
- int expect[1024];
-
- for (i = 0; i < 1024; i++) {
- expect[i] = i;
- }
-
- NUTS_PASS(nng_id_map_alloc(&m, 0, 0, 0));
-
- for (i = 0; i < 1024; i++) {
- if ((rv = nng_id_set(m, i, &expect[i])) != 0) {
- NUTS_PASS(rv);
- }
- }
-
- for (i = 0; i < 1024; i++) {
- if ((rv = nng_id_remove(m, i)) != 0) {
- NUTS_PASS(rv);
- }
- }
- nng_id_map_free(m);
-}
-
-void
-test_id_dynamic(void)
-{
- nng_id_map *m;
- int expect[5];
- uint64_t id;
-
- NUTS_PASS(nng_id_map_alloc(&m, 10, 13, 0));
-
- // We can fill the table.
- NUTS_PASS(nng_id_alloc(m, &id, &expect[0]));
- NUTS_TRUE(id == 10);
- NUTS_PASS(nng_id_alloc(m, &id, &expect[1]));
- NUTS_TRUE(id == 11);
- NUTS_PASS(nng_id_alloc(m, &id, &expect[2]));
- NUTS_TRUE(id == 12);
- NUTS_PASS(nng_id_alloc(m, &id, &expect[3]));
- NUTS_TRUE(id == 13);
-
- // Adding another fails.
- NUTS_FAIL(nng_id_alloc(m, &id, &expect[4]), NNG_ENOMEM);
-
- // Delete one.
- NUTS_PASS(nng_id_remove(m, 11));
-
- // And now we can allocate one.
- NUTS_PASS(nng_id_alloc(m, &id, &expect[4]));
- NUTS_TRUE(id == 11);
- nng_id_map_free(m);
-}
-
-void
-test_id_set_out_of_range(void)
-{
- nng_id_map *m;
- int x;
- uint64_t id;
-
- 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, &x));
- NUTS_PASS(nng_id_alloc(m, &id, &x));
- NUTS_TRUE(id == 10);
- 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
-
-void
-test_id_stress(void)
-{
- void *values[NUM_VALUES];
- nng_id_map *m;
- size_t i;
- int rv;
- void *x;
- int v;
-
- NUTS_PASS(nng_id_map_alloc(&m, 0, 0, 0));
- for (i = 0; i < NUM_VALUES; i++) {
- values[i] = NULL;
- }
-
- for (i = 0; i < STRESS_LOAD; i++) {
- v = rand() % NUM_VALUES; // Keep it constrained
-
- switch (rand() & 3) {
- case 0:
- x = &values[rand() % NUM_VALUES];
- values[v] = x;
- if ((rv = nng_id_set(m, v, x)) != 0) {
- NUTS_PASS(rv);
- goto out;
- }
- break;
-
- case 1:
- rv = nng_id_remove(m, v);
- if (values[v] == NULL) {
- if (rv != NNG_ENOENT) {
- NUTS_FAIL(rv, NNG_ENOENT);
- goto out;
- }
- } else {
- values[v] = NULL;
- if (rv != 0) {
- NUTS_PASS(rv);
- goto out;
- }
- }
- break;
- case 2:
- x = nng_id_get(m, v);
- if (x != values[v]) {
- NUTS_TRUE(x == values[v]);
- goto out;
- }
- break;
- }
- }
-out:
- NUTS_TRUE(i == STRESS_LOAD);
-
- // Post stress check.
- for (i = 0; i < NUM_VALUES; i++) {
- x = nng_id_get(m, (uint32_t) i);
- if (x != values[i]) {
- NUTS_TRUE(x == values[i]);
- break;
- }
-
- // We only use the test macros if we know they are going
- // to fail. Otherwise, there will be too many errors reported.
- rv = nng_id_remove(m, (uint32_t) i);
- if ((x == NULL) && (rv != NNG_ENOENT)) {
- NUTS_FAIL(rv, NNG_ENOENT);
- } else if ((x != NULL) && (rv != 0)) {
- NUTS_PASS(rv);
- }
- }
- NUTS_TRUE(i == NUM_VALUES);
-
- nng_id_map_free(m);
-}
-
-void
-test_id_alloc_long_long(void)
-{
-#define TEST_IDS 100
- nng_id_map *m;
- int x;
- uint64_t ids[TEST_IDS];
-
- NUTS_PASS(nng_id_map_alloc(&m, 1ULL << 32, (int64_t) -1, 0));
-
- // We can insert outside the range forcibly - making sure we are
- // choosing numbers above 64 bits.
- for (int i = 0; i < TEST_IDS; i++) {
- NUTS_PASS(nng_id_alloc(m, &ids[i], &x));
- NUTS_ASSERT(ids[i] > 0xFFFFFFFFULL);
- }
- for (int i = 0; i < TEST_IDS; i++) {
- bool matched = false;
- for (int j = 0; j < i; j++) {
- // only dump the assertion on failure
- // otherwise it is too noisy
- if (ids[i] == ids[j]) {
- matched = true;
- break;
- }
- }
- NUTS_ASSERT(!matched);
- }
- nng_id_map_free(m);
-#undef TEST_IDS
-}
-
-NUTS_TESTS = {
- { "id basic", test_id_basic },
- { "id random", test_id_random },
- { "id collision", test_id_collision },
- { "id empty", test_id_empty },
- { "not found", test_id_not_found },
- { "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 },
-};