Welcome to little lamb

Code » limb » master » tree

[master] / src / doc / hmap.h / hmap_init.3.md

% limb manual
% hmap_init(3)
% limb 0.1.0
% 2023-07-24

# NAME

hmap_init, hmap_next, hmap_set, hmap_get, hmap_free - hash table management

# SYNOPSIS

    #include <limb/hmap.h>

```pre hl
int hmap_init(size_t <em>dlen</em>, size_t <em>n</em>, hmap *<em>hmap</em>)
void *hmap_next(u32 *<em>key</em>, hmap *<em>hmap</em>)
int hmap_set(u32 <em>key</em>, void *<em>data</em>, hmap *<em>hmap</em>)
void *hmap_get(u32 <em>key</em>, hmap *<em>hmap</em>)
void hmap_free(hmap *<em>hmap</em>)
```

# DESCRIPTION

These functions allow the caller to manage a hash table containing entries
consisting of a key (a 32bit unsigned integer) and its associated data. The last
argument, `hmap`, points to a structure that describes the table on which the
function operates, and should be treated as opaque (i.e. do not attempt to
directly access or modify the fields in this structure.).

The size of the associated data are defined by the `hmap_init`() call, they can
therefore be different for each hash table, but are of fixed size on a per-table
basis (and cannot be modified).

First, the `hmap_init`() function must be used to initialize the structure
pointed to by `hmap` for a hash table of `n` elements, using `dlen` bytes as
per-element data size.

The hash table will automatically grow as needed when adding new elements, but
it is not possible to shrunk it down, nor is it possible to remove elements.
Note also that the actual size of the table must be a power of two, and will
therefore be adjusted accordingly (e.g.  using 10 as `n` will actually result in
a table initialized for 16 elements).

The `hmap_set`() function searches the table for an element with the given `key`
and sets its associated data to that pointed to by `data` (which must be of the
size given as `dlen` to `hmap_init`() earlier). Note that the actual data
pointed will be copied into the table.

If not such element exists, it is added to the table. If needed the table might
grow its size in order to add the new element.

To get a valid 32bit key from a data blob (e.g. a string), you might want to use
[hlookup32](3).

The `hmap_get`() function searches the table for an element with the given `key`
and returns a pointer to its associated data when found, or NULL if no such
element exists in the table.

The `hmap_next`() function allows to iterate over all elements in the table,
although this is not an optimized path. It will locate the element for the key
pointed to by `key`, set it to the key of the next element and return a pointer
to its associated data. If there are no more elements in the table, it will
return *NULL*.

The first call to `hmap_next`() must have the value pointe by `key` by zero,
successive calls must them re-use the value in order to move forward. Although
changing an element's /data/ is allowed, one should not change the table's
content during such iteration (i.e. do not add elements to the table).

The `hmap_free`() function frees all memory allocated by the table and returns
it into a uninitialized state. It is then possible to re-use it with
`hmap_init`() with different parameters.

# RETURN VALUE

The `hmap_init`() and `hmap_set`() functions return 1 on success, and zero on
error, with `errno` set to indicate the cause of the error.

The `hmap_get`() function returns a pointer to the data associated with the
element if found, or NULL otherwise. It cannot fail.

The `hmap_next`() function returns a pointer to the data associated with the
element, or NULL is the table is empty or has been fully iterated (no more
elements past the one whose key is pointed to by `key`). It cannot fail.

# ERRORS

The `hmap_init`() function may fail if :

: *EINVAL*
:: `hmap` is NULL, `dlen` or `n` is zero

: *ENOMEM*
:: Not enough memory to allocate the table

The `hmap_set`() function may fail if :

: *ENOENT*
:: `data` was NULL but no element with the given `key` was found

: *ENOMEM*
:: Not enough memory to grow the table in order to add the element. Note that in
such a case, the table remains in valid state and can still be used as before.