Updated README file.

This commit is contained in:
LoRd_MuldeR 2022-11-24 18:32:05 +01:00
parent ebcb4d64f9
commit 0de14dfe4c
3 changed files with 106 additions and 17 deletions

105
README.md
View File

@ -23,7 +23,7 @@ int main(int argc, char* argv[])
uint64_t value; uint64_t value;
/* create new hash set instance */ /* create new hash set instance */
hash_set_t *const hash_set = hash_set_create(0U, -1.0, 0U); hash_set_t *const hash_set = hash_set_create(0U, -1.0);
if (!hash_set) if (!hash_set)
{ {
fputs("Allocation has failed!\n", stderr); fputs("Allocation has failed!\n", stderr);
@ -72,12 +72,14 @@ int main(int argc, char* argv[])
API Reference API Reference
============= =============
This section describes the LibHashSet C99 programming interface.
Types Types
----- -----
### hash_set_t ### hash_set_t
A `struct` that represents a hash set instance. Instances can be allocated and de-allocated via the [hash_set_create()](#hashsetcreate) and [hash_set_destroy()](#hashsetdestroy) functions, respectively. 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.
***Note:*** Application code shall treat this `struct` as opaque! ***Note:*** Application code shall treat this `struct` as opaque!
@ -102,16 +104,16 @@ hash_set_t *hash_set_create(
#### Parameters #### Parameters
* `initial_capacity` * `initial_capacity`
The initial capacity of the hash set (number of items). The given value will be rounded to the next power of two. If this parameter is set to *zero*, the the *default* initial capacity is used. 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.
* `load_factor` * `load_factor`
The load factor to be used for the hash set. The given value will be clipped to the **0.1** to **1.0** range. If this parameter is less than or equal to *zero*, the recommended *default* load factor 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.
#### Return value #### Return value
On success, this function returns a pointer to a new hash set instance. On error, a `NULL` pointer is returned. On success, this function returns a pointer to a new hash set instance. On error, a `NULL` pointer is returned.
***Note:*** To avoid a memory leak, the returned pointer must be de-allocated by the application using the [hash_set_destroy()](#hashsetdestroy) function, as soon as the instance is *not* needed anymore! ***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!
### hash_set_destroy() ### hash_set_destroy()
@ -126,7 +128,7 @@ void hash_set_destroy(
#### Parameters #### Parameters
* `instance` * `instance`
A pointer to the hash set instance that is to be destroyed, as returned by the [hash_set_create()](#hashsetcreate) function. A pointer to the hash set instance that is to be destroyed, as returned by the [hash_set_create()](#hash_set_create) function.
***Note:*** The given pointer is *invalidated* by this function, and it **must not** be used afterwards! ***Note:*** The given pointer is *invalidated* by this function, and it **must not** be used afterwards!
### hash_set_insert() ### hash_set_insert()
@ -145,7 +147,7 @@ errno_t hash_set_insert(
#### Parameters #### Parameters
* `instance` * `instance`
A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hashsetcreate) function. A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hash_set_create) function.
* `value` * `value`
The value (key) to be inserted into the hash set. It can be *any* value in the `0U` to `UINT64_MAX` range. The value (key) to be inserted into the hash set. It can be *any* value in the `0U` to `UINT64_MAX` range.
@ -182,7 +184,7 @@ errno_t hash_set_remove(
#### Parameters #### Parameters
* `instance` * `instance`
A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hashsetcreate) function. A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hash_set_create) function.
* `value` * `value`
The value (key) to be removed from the hash set. It can be *any* value in the `0U` to `UINT64_MAX` range. The value (key) to be removed from the hash set. It can be *any* value in the `0U` to `UINT64_MAX` range.
@ -212,7 +214,7 @@ errno_t hash_set_clear(
#### Parameters #### Parameters
* `instance` * `instance`
A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hashsetcreate) function. A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hash_set_create) function.
#### Return value #### Return value
@ -241,7 +243,7 @@ errno_t hash_set_contains(
#### Parameters #### Parameters
* `instance` * `instance`
A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hashsetcreate) function. A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hash_set_create) function.
* `value` * `value`
The value (key) to be searched in the hash set. It can be *any* value in the `0U` to `UINT64_MAX` range. The value (key) to be searched in the hash set. It can be *any* value in the `0U` to `UINT64_MAX` range.
@ -261,6 +263,12 @@ On success, this function returns *zero*. On error, the appropriate error code i
### hash_set_iterate() ### hash_set_iterate()
Iterates through the values stored in the hash set. The elements are iterated in **no** particular order.
This function returns one value at a time. It should be called repeatedly, until the end of the set is encountered.
***Warning:*** The result is undefined, if the set is modified while the iteration is in progress!
```C ```C
errno_t hash_set_iterate( errno_t hash_set_iterate(
const hash_set_t *const instance, const hash_set_t *const instance,
@ -269,16 +277,55 @@ errno_t hash_set_iterate(
); );
``` ```
#### Parameters
* `instance`
A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hash_set_create) function.
* `offset`
A pointer to a variable of type `size_t` where the current position in the set is maintained.
This variable **must** be initialized to *zero* before the *first* invocation; it is updated on subsequent invocations.
* `value`
A pointer to a variable of type `uint64_t` where the next value in the set is stored on success.
The content of the variable should be considered *undefined*, if the invocation has failed.
#### 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`.
* `ENOENT`
No more values. The end of the set has been encountered.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_set_size() ### hash_set_size()
Returns the current number of values in the hash set.
```C ```C
size_t hash_set_size( size_t hash_set_size(
const hash_set_t *const instance const hash_set_t *const instance
); );
``` ```
#### Parameters
* `instance`
A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hash_set_create) function.
#### Return value
This function returns the number of values in the hash set.
### hash_set_info() ### hash_set_info()
Returns technical information about the hash set.
```C ```C
errno_t hash_set_info( errno_t hash_set_info(
const hash_set_t *const instance, const hash_set_t *const instance,
@ -289,6 +336,44 @@ errno_t hash_set_info(
); );
``` ```
#### Parameters
* `instance`
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!
License License
======= =======

View File

@ -201,9 +201,10 @@ static int test_function_2(hash_set_t *const hash_set)
random_t random; random_t random;
random_init(&random); random_init(&random);
for (size_t i = 0U, offset = 0U; i < 5U; ++i, offset = 0U) memset(test, 0, sizeof(test));
for (size_t r = 0U, offset = 0U; r < 8U; ++r, offset = 0U)
{ {
memset(test, 0, sizeof(test));
for (size_t j = 0U; j < ARRSIZE / 3U; ++j) for (size_t j = 0U; j < ARRSIZE / 3U; ++j)
{ {
size_t rnd; size_t rnd;
@ -212,7 +213,7 @@ static int test_function_2(hash_set_t *const hash_set)
rnd = random_next(&random) % ARRSIZE; rnd = random_next(&random) % ARRSIZE;
} }
while (test[rnd]); while (test[rnd]);
test[rnd] = 1U; test[rnd] = UINT8_C(1);
} }
for (size_t j = 0U; j < ARRSIZE; ++j) for (size_t j = 0U; j < ARRSIZE; ++j)
{ {
@ -227,7 +228,7 @@ static int test_function_2(hash_set_t *const hash_set)
PRINT_SET_INFO(); PRINT_SET_INFO();
} }
} }
while (hash_set_iterate(hash_set, &offset, &value) == 0) while (!hash_set_iterate(hash_set, &offset, &value))
{ {
if (!test[value]) if (!test[value])
{ {
@ -246,6 +247,7 @@ static int test_function_2(hash_set_t *const hash_set)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
PRINT_SET_INFO(); PRINT_SET_INFO();
test[j] = UINT8_C(0);
} }
} }
if (hash_set_size(hash_set) != 0U) if (hash_set_size(hash_set) != 0U)
@ -386,6 +388,8 @@ static int test_function_4(hash_set_t *const hash_set)
int main(void) int main(void)
{ {
printf("LibHashSet Test [%s]\n\n", __DATE__);
hash_set_t *const hash_set = hash_set_create(0U, -1.0); hash_set_t *const hash_set = hash_set_create(0U, -1.0);
if (!hash_set) if (!hash_set)
{ {

View File

@ -41,9 +41,9 @@ struct _hash_set
struct _hash_set_data data; struct _hash_set_data data;
}; };
static const size_t MINIMUM_CAPACITY = 128U; static const size_t MINIMUM_CAPACITY = 128U;
static const size_t DEFAULT_CAPACITY = 16384U; static const size_t DEFAULT_CAPACITY = 8192U;
static const double DEFAULT_LOADFCTR = 0.8; static const double DEFAULT_LOADFCTR = 0.8;
/* ========================================================================= */ /* ========================================================================= */
/* PRIVATE FUNCTIONS */ /* PRIVATE FUNCTIONS */