summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2023-12-29 17:43:50 -0800
committerGarrett D'Amore <garrett@damore.org>2023-12-29 18:25:04 -0800
commit3298ac1e93742e7a1ef5c4dc2e9b603dfa89d3cb (patch)
treea1051ba1a3edcd5bc6c75c9a1f43ae1a14813b45 /src/core
parent5954332f1690e95c329b991a25b2d89b9a44ef02 (diff)
downloadnng-3298ac1e93742e7a1ef5c4dc2e9b603dfa89d3cb.tar.gz
nng-3298ac1e93742e7a1ef5c4dc2e9b603dfa89d3cb.tar.bz2
nng-3298ac1e93742e7a1ef5c4dc2e9b603dfa89d3cb.zip
fixes #1740 Public ID hash API
This includes a manual page documenting the entire set of functions in one step. The hash is 64-bit based for now, to be maximally flexible. An internal 32-bit convenience for the common internal use is also provided (not public). The public API includes a test suite.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/dialer.c2
-rw-r--r--src/core/id_test.c10
-rw-r--r--src/core/idhash.c34
-rw-r--r--src/core/idhash.h22
-rw-r--r--src/core/listener.c2
-rw-r--r--src/core/pipe.c2
-rw-r--r--src/core/socket.c4
7 files changed, 45 insertions, 31 deletions
diff --git a/src/core/dialer.c b/src/core/dialer.c
index 91d18dc8..b1ded52f 100644
--- a/src/core/dialer.c
+++ b/src/core/dialer.c
@@ -259,7 +259,7 @@ nni_dialer_create(nni_dialer **dp, nni_sock *s, const char *url_str)
nni_aio_init(&d->d_tmo_aio, dialer_timer_cb, d);
nni_mtx_lock(&dialers_lk);
- rv = nni_id_alloc(&dialers, &d->d_id, d);
+ rv = nni_id_alloc32(&dialers, &d->d_id, d);
nni_mtx_unlock(&dialers_lk);
#ifdef NNG_ENABLE_STATS
diff --git a/src/core/id_test.c b/src/core/id_test.c
index b948cc13..78be63b8 100644
--- a/src/core/id_test.c
+++ b/src/core/id_test.c
@@ -1,5 +1,5 @@
//
-// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2023 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
@@ -39,7 +39,7 @@ void
test_random(void)
{
int i;
- uint32_t id;
+ uint64_t id;
for (i = 0; i < 2; i++) {
nni_id_map m;
nni_id_map_init(&m, 0, 0, true);
@@ -94,7 +94,7 @@ void
test_not_found(void)
{
nni_id_map m;
- uint32_t id;
+ uint64_t id;
nni_id_map_init(&m, 0, 0, false);
NUTS_PASS(nni_id_alloc(&m, &id, &id));
@@ -137,7 +137,7 @@ test_dynamic(void)
{
nni_id_map m;
int expect[5];
- uint32_t id;
+ uint64_t id;
nni_id_map_init(&m, 10, 13, false);
@@ -175,7 +175,7 @@ test_set_out_of_range(void)
// We can insert outside the range forcibly.
NUTS_PASS(nni_id_set(&m, 1, &x));
NUTS_PASS(nni_id_set(&m, 100, &x));
- NUTS_PASS(nni_id_alloc(&m, &id, &x));
+ NUTS_PASS(nni_id_alloc32(&m, &id, &x));
NUTS_TRUE(id == 10);
nni_id_map_fini(&m);
}
diff --git a/src/core/idhash.c b/src/core/idhash.c
index c56c8191..67ae67ea 100644
--- a/src/core/idhash.c
+++ b/src/core/idhash.c
@@ -1,5 +1,5 @@
//
-// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
@@ -13,7 +13,7 @@
#include <string.h>
struct nni_id_entry {
- uint32_t key;
+ uint64_t key;
uint32_t skips;
void *val;
};
@@ -24,7 +24,7 @@ static nni_id_map **id_reg_map = NULL;
static nni_mtx id_reg_mtx = NNI_MTX_INITIALIZER;
void
-nni_id_map_init(nni_id_map *m, uint32_t lo, uint32_t hi, bool randomize)
+nni_id_map_init(nni_id_map *m, uint64_t lo, uint64_t hi, bool randomize)
{
if (lo == 0) {
lo = 1;
@@ -68,7 +68,7 @@ nni_id_map_fini(nni_id_map *m)
#define ID_INDEX(m, j) ((j) & (m->id_cap - 1))
static size_t
-id_find(nni_id_map *m, uint32_t id)
+id_find(nni_id_map *m, uint64_t id)
{
size_t index;
size_t start;
@@ -98,7 +98,7 @@ id_find(nni_id_map *m, uint32_t id)
}
void *
-nni_id_get(nni_id_map *m, uint32_t id)
+nni_id_get(nni_id_map *m, uint64_t id)
{
size_t index;
if ((index = id_find(m, id)) == (size_t) -1) {
@@ -130,7 +130,8 @@ id_map_register(nni_id_map *m)
}
id_reg_len = len;
if (id_reg_map != NULL)
- memcpy(mr, id_reg_map, id_reg_num * sizeof(nni_id_map *));
+ memcpy(
+ mr, id_reg_map, id_reg_num * sizeof(nni_id_map *));
id_reg_map = mr;
}
id_reg_map[id_reg_num++] = m;
@@ -233,7 +234,7 @@ id_resize(nni_id_map *m)
}
int
-nni_id_remove(nni_id_map *m, uint32_t id)
+nni_id_remove(nni_id_map *m, uint64_t id)
{
size_t index;
size_t probe;
@@ -251,7 +252,7 @@ nni_id_remove(nni_id_map *m, uint32_t id)
nni_id_entry *entry;
// The load was increased once each hashing operation we used
- // to place the the item. Decrement it accordingly.
+ // to place the item. Decrement it accordingly.
m->id_load--;
entry = &m->id_entries[probe];
if (probe == index) {
@@ -273,7 +274,7 @@ nni_id_remove(nni_id_map *m, uint32_t id)
}
int
-nni_id_set(nni_id_map *m, uint32_t id, void *val)
+nni_id_set(nni_id_map *m, uint64_t id, void *val)
{
size_t index;
nni_id_entry *ent;
@@ -314,9 +315,9 @@ nni_id_set(nni_id_map *m, uint32_t id, void *val)
}
int
-nni_id_alloc(nni_id_map *m, uint32_t *idp, void *val)
+nni_id_alloc(nni_id_map *m, uint64_t *idp, void *val)
{
- uint32_t id;
+ uint64_t id;
int rv;
NNI_ASSERT(val != NULL);
@@ -355,3 +356,14 @@ nni_id_alloc(nni_id_map *m, uint32_t *idp, void *val)
}
return (rv);
}
+
+int
+nni_id_alloc32(nni_id_map *m, uint32_t *idp, void *val)
+{
+ uint64_t id;
+ int rv;
+ rv = nni_id_alloc(m, &id, val);
+ NNI_ASSERT(id < (1ULL << 32));
+ *idp = (uint32_t) id;
+ return (rv);
+} \ No newline at end of file
diff --git a/src/core/idhash.h b/src/core/idhash.h
index e8894dfb..b2c07062 100644
--- a/src/core/idhash.h
+++ b/src/core/idhash.h
@@ -1,5 +1,5 @@
//
-// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
@@ -28,16 +28,17 @@ typedef struct nni_id_entry nni_id_entry;
// NB: These details are entirely private to the hash implementation.
// They are provided here to facilitate inlining in structures.
+// We can support at most 2^32 ~ 4 billion ~ entries.
struct nni_id_map {
+ uint32_t id_flags;
uint32_t id_cap;
uint32_t id_count;
uint32_t id_load;
uint32_t id_min_load; // considers placeholders
uint32_t id_max_load;
- uint32_t id_min_val;
- uint32_t id_max_val;
- uint32_t id_dyn_val;
- uint32_t id_flags;
+ uint64_t id_min_val;
+ uint64_t id_max_val;
+ uint64_t id_dyn_val;
nni_id_entry *id_entries;
};
@@ -45,12 +46,13 @@ struct nni_id_map {
#define NNI_ID_FLAG_RANDOM 2 // start at a random value
#define NNI_ID_FLAG_REGISTER 4 // map is registered for finalization
-extern void nni_id_map_init(nni_id_map *, uint32_t, uint32_t, bool);
+extern void nni_id_map_init(nni_id_map *, uint64_t, uint64_t, bool);
extern void nni_id_map_fini(nni_id_map *);
-extern void *nni_id_get(nni_id_map *, uint32_t);
-extern int nni_id_set(nni_id_map *, uint32_t, void *);
-extern int nni_id_alloc(nni_id_map *, uint32_t *, void *);
-extern int nni_id_remove(nni_id_map *, uint32_t);
+extern void *nni_id_get(nni_id_map *, uint64_t);
+extern int nni_id_set(nni_id_map *, uint64_t, void *);
+extern int nni_id_alloc(nni_id_map *, uint64_t *, void *);
+extern int nni_id_alloc32(nni_id_map *, uint32_t *, void *);
+extern int nni_id_remove(nni_id_map *, uint64_t);
extern void nni_id_map_sys_fini(void);
#define NNI_ID_MAP_INITIALIZER(min, max, flags) \
diff --git a/src/core/listener.c b/src/core/listener.c
index 7d3e3e0d..53d5c843 100644
--- a/src/core/listener.c
+++ b/src/core/listener.c
@@ -243,7 +243,7 @@ nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
nni_aio_init(&l->l_tmo_aio, listener_timer_cb, l);
nni_mtx_lock(&listeners_lk);
- rv = nni_id_alloc(&listeners, &l->l_id, l);
+ rv = nni_id_alloc32(&listeners, &l->l_id, l);
nni_mtx_unlock(&listeners_lk);
#ifdef NNG_ENABLE_STATS
diff --git a/src/core/pipe.c b/src/core/pipe.c
index 58267d69..10a1f35a 100644
--- a/src/core/pipe.c
+++ b/src/core/pipe.c
@@ -259,7 +259,7 @@ pipe_create(nni_pipe **pp, nni_sock *sock, nni_sp_tran *tran, void *tran_data)
nni_cv_init(&p->p_cv, &pipes_lk);
nni_mtx_lock(&pipes_lk);
- rv = nni_id_alloc(&pipes, &p->p_id, p);
+ rv = nni_id_alloc32(&pipes, &p->p_id, p);
nni_mtx_unlock(&pipes_lk);
#ifdef NNG_ENABLE_STATS
diff --git a/src/core/socket.c b/src/core/socket.c
index 1f44ebfa..d9fd5266 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -641,7 +641,7 @@ nni_sock_open(nni_sock **sockp, const nni_proto *proto)
}
nni_mtx_lock(&sock_lk);
- if ((rv = nni_id_alloc(&sock_ids, &s->s_id, s)) != 0) {
+ if ((rv = nni_id_alloc32(&sock_ids, &s->s_id, s)) != 0) {
nni_mtx_unlock(&sock_lk);
sock_destroy(s);
return (rv);
@@ -1343,7 +1343,7 @@ nni_ctx_open(nni_ctx **ctxp, nni_sock *sock)
nni_free(ctx, ctx->c_size);
return (NNG_ECLOSED);
}
- if ((rv = nni_id_alloc(&ctx_ids, &ctx->c_id, ctx)) != 0) {
+ if ((rv = nni_id_alloc32(&ctx_ids, &ctx->c_id, ctx)) != 0) {
nni_mtx_unlock(&sock_lk);
nni_free(ctx, ctx->c_size);
return (rv);