LibHashSet supports sets containing values of type `uint32_t` or `uint64_t`. For each value type, separate functions are provided. The functions for `uint32_t`- and `uint64_t`-based hash sets can be distinguished by the suffix `…32` and `…64` suffix, respectively. In the following, the functions are described in their "generic" form.
***Note:*** On Microsoft Windows, when using LibHashSet as a "shared" library (DLL), the macro `HASHSET_DLL` must be defined *before* including `<hash_set.h>`! This is **not** required or allowed when using the "static" library.
A `struct` that represents a hash set instance. Instances can be allocated and de-allocated via the [hash_set_create()](#hash_set_create) and [hash_set_destroy()](#hash_set_destroy) functions, respectively.
The initial capacity of the hash set (number of values). The given value will be rounded to the next power of two. If the number of values (keys) to be inserted into the hash set can be estimated beforehand, then the initial capacity should be adjusted accordingly to avoid unnecessary re-allocations. In any case, the hash set will be able to grow dynamically as needed. If this parameter is set to *zero*, the the *default* initial capacity (8192) is used.
The load factor to be applied to the hash set. The given value will be clipped to the **0.1** to **1.0** range. Generally, the default load factor (0.8) offers a good trade-off between performance and memory usage. Higher values decrease the memory overhead, but may increase the time required for insert/lookup operations when the hash set is almost completely filled. If this parameter is less than or equal to *zero*, the *default* load factor is used.
***Note:*** To avoid a memory leak, the returned pointer must be de-allocated by the application using the [hash_set_destroy()](#hash_set_destroy) function, as soon as the instance is *not* needed anymore!
A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hash_set_create) function.
*`capacity`
A pointer to a variable of type `size_t` where the current total *capacity* of the hash set is stored.
This value will always be greater than or equal to the sum of the *valid* and *deleted* entries.
*`valid`
A pointer to a variable of type `size_t` where the current number of *valid* entries in the hash set is stored.
This value is equivalent to the return value of the [hash_set_size()](#hash_set_size) function.
*`deleted`
A pointer to a variable of type `size_t` where the current number of *deleted* entries in the hash set is stored.
For technical reasons, entires are *not* removed from the set immediately, but are marked as "deleted".
*`limit`
A pointer to a variable of type `size_t` where the current "grow" *limit* of the hash set is stored.
The hash set is grown automatically, as soon as the sum of the *valid* and *deleted* entries exceeds this limit.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
*`EINVAL`
An invalid argument was given, e.g. `instance` was set to `NULL`.
*`EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
Thread Safety
-------------
LibHashSet is ***thread-safe***, in the sense that all public functions operate *exclusively* on the given `hash_set_t` instance; there is **no** implicit shared "global" state. This means that **no** synchronization is required in multi-threaded applications, provided that each `hash_set_t` instance is created and accessed only by a *single* thread.
However, LibHashSet does ***nothing*** to synchronize access to a particular `hash_set_t` instance! Consequently, in situations where the *same*`hash_set_t` instance needs to be shared across *multiple* concurrent threads, the calling application is responsible for serializing all access to the "shared" instance, e.g. by using a [*mutex*](https://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_mutex_lock.html) lock!