From 3298ac1e93742e7a1ef5c4dc2e9b603dfa89d3cb Mon Sep 17 00:00:00 2001
From: Garrett D'Amore <garrett@damore.org>
Date: Fri, 29 Dec 2023 17:43:50 -0800
Subject: 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.
---
 docs/man/nng_id_map.3supp.adoc | 100 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 docs/man/nng_id_map.3supp.adoc

(limited to 'docs/man/nng_id_map.3supp.adoc')

diff --git a/docs/man/nng_id_map.3supp.adoc b/docs/man/nng_id_map.3supp.adoc
new file mode 100644
index 00000000..bd5dace3
--- /dev/null
+++ b/docs/man/nng_id_map.3supp.adoc
@@ -0,0 +1,100 @@
+= nng_id_map(3supp)
+//
+// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech>
+//
+// This document 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.
+//
+
+== NAME
+
+nng_id_map - identifier based mapping table
+
+== SYNOPSIS
+
+[source, c]
+----
+#include <nng/nng.h>
+#include <nng/supplemental/idhash/idhash.h>
+
+typedef struct nng_id_map_s nng_id_map;
+
+#define NNG_MAP_RANDOM 1
+
+int   nng_id_map_alloc(nng_id_map **map_p, uint64_t lo, uint64_t hi, int flags);
+void  nng_id_map_free(nng_id_map *map);
+void *nng_id_get(nng_id_map *map, uint64_t id);
+int   nng_id_set(nng_id_map *map, uint64_t, void *value);
+int   nng_id_alloc(nng_id_map *map, uint64_t *id_p, void *value);
+int   nng_id_remove(nng_id_map *map, uint64_t id);
+
+----
+
+== DESCRIPTION
+
+These functions provide support for managing tables of data based on
+identifiers, ensuring that identifiers are allocated uniquely and within
+specified range limits.
+
+The table stores data pointers (which must not be `NULL`) at a logical numeric index.
+It does so efficiently, even if large gaps exist, and it provides a means to efficiently
+allocate a numeric identifier from a pool of unused identifiers.
+
+Identifiers are allocated in increasing order, without reusing old identifiers until the
+largest possible identifier is allocated.  After wrapping, only identifiers that are no longer
+in use will be considered.
+No effort to order the availability of identifiers based on when they were freed is made.
+
+An initial table is allocated with `nng_id_map_alloc()`, which takes the lowest legal identifier in _lo_,
+and the largest legal identifier in _hi_.
+The new table is returned in _map_p_, and should be used as the _map_ argument to the rest of these functions.
+
+****
+As a special convenience, if these are specified as zero, then a full range of 32-bit identifiers is assumed.
+If identifiers larger than or equal to 2^32^ are required, then both _lo_ and _hi_ must be specified with the
+exact values desired.
+****
+
+The _flags_ argument is a bit mask of flags for the table.
+If `NNG_MAP_RANDOM` is specified, then the starting point for allocations is randomized, but subsequent allocations will then be monotonically increasing.
+This is useful to reduce the odds of different instances of an application using the same identifiers at the same time.
+
+The `nng_id_get()` function returns the value previously stored with the given identifier.
+If no value is currently associated with the identifer, it returns `NULL`.
+
+The `nng_id_set()` function sets the value with the associated identifier.
+This can be used to replace a previously allocated identifier.
+If the identifier was not previously allocated, then it is allocated as part of the call.
+This function does not necessarily honor the identifier range limits set for the map when it was allocated.
+
+The `nng_id_alloc()` function allocates a new identifier from the range for the map, and associates it with
+the supplied _value_.
+
+The `nng_id_remove()` function removes the identifier and its associated value from the table.
+
+NOTE: These functions are limited to storing at most 2^32^ identifiers, even though the identifers may
+themselves be larger than 2^32^.
+
+IMPORTANT: These functions are *not* thread-safe.
+Callers should use a xref:nng_mtx_lock.3supp[mutex] or similar approach when thread-safety is needed.
+
+== RETURN VALUES
+
+The `nng_id_map_alloc()`, `nng_id_set()`, `nng_id_alloc()`, and `nng_id_remove()` functions
+return 0 on success, or -1 on failure.
+
+The `nng_id_map_get()` function returns the requested data pointer, or `NULL` if the identifier was not found.
+
+== ERRORS
+
+[horizontal]
+`NNG_ENOENT`:: The _id_ does not exist in the table.
+`NNG_ENOMEM`:: Insufficient memory is available, or the table is full.
+
+== SEE ALSO
+
+[.text-left]
+xref:nng_mtx_lock.3supp.adoc[nng(7)]
+xref:nng.7.adoc[nng(7)]
-- 
cgit v1.2.3-70-g09d2

