hash_map_insert(): Added parameter 'update' to specify if the value of an existing key should be updated +
hash_map_remove(): Added parameter 'value' to return the value that was associated with the deleted key (optional).
This commit is contained in:
parent
f229c7ccfb
commit
669bf3a28b
18
README.md
18
README.md
@ -514,15 +514,14 @@ void hash_map_destroy(
|
||||
|
||||
Tries to insert the given key-value pair into the hash map.
|
||||
|
||||
If the map already contains the given key, then the value associated with the existing key is updated.
|
||||
|
||||
***Note:*** If the key is actually inserted, then the hash map *may* need to grow.
|
||||
|
||||
```C
|
||||
errno_t hash_map_insert(
|
||||
hash_map_t *const instance,
|
||||
const value_t key,
|
||||
const value_t value
|
||||
const value_t value,
|
||||
const int update
|
||||
);
|
||||
```
|
||||
|
||||
@ -537,6 +536,9 @@ errno_t hash_map_insert(
|
||||
* `value`
|
||||
The value to be associated with the given key.
|
||||
|
||||
* `update`
|
||||
If the map already contains the specified key, then if this parameter is *non-zero*, the value associated with the existing key will be updated; otherwise, the value currently associated with key remains unchanged.
|
||||
|
||||
#### Return value
|
||||
|
||||
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
|
||||
@ -546,7 +548,7 @@ On success, this function returns *zero*. On error, the appropriate error code i
|
||||
|
||||
* `EEXIST`
|
||||
The given key was *not* inserted into the hash map (again), because it was already present.
|
||||
Nonetheless, the value associated with the existing key has been updated!
|
||||
Nonetheless, if `update` was non-zero, the value associated with the existing key has been updated.
|
||||
|
||||
* `ENOMEM`
|
||||
The key could *not* be inserted, because the required amount of memory could *not* be allocated.
|
||||
@ -565,7 +567,8 @@ The value associated with the removed key is discarded.
|
||||
```C
|
||||
errno_t hash_map_remove(
|
||||
hash_map_t *const instance,
|
||||
const value_t key
|
||||
const value_t key,
|
||||
value_t *const value
|
||||
);
|
||||
```
|
||||
|
||||
@ -577,6 +580,11 @@ errno_t hash_map_remove(
|
||||
* `key`
|
||||
The key to be removed from the hash map.
|
||||
|
||||
* `value`
|
||||
A pointer to a variable of type `value_t` where the value that was associated with the deleted key is stored.
|
||||
The content of the variable should be considered *undefined*, if the key could *not* be removed.
|
||||
***Note:*** This parameter can be set to `NULL`, in which case the value will *not* be reported to the application.
|
||||
|
||||
#### Return value
|
||||
|
||||
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
|
||||
|
@ -35,7 +35,7 @@ int main(void)
|
||||
while (have_more_items(offset))
|
||||
{
|
||||
const pair_t input = get_next_item(offset++);
|
||||
const errno_t error = hash_map_insert64(hash_map, input.key, input.value);
|
||||
const errno_t error = hash_map_insert64(hash_map, input.key, input.value, 1);
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr, "Insert operation failed! (error: %d)\n", error);
|
||||
|
@ -72,13 +72,13 @@ HASHSET_API void hash_map_destroy16(hash_map16_t *const instance);
|
||||
HASHSET_API void hash_map_destroy32(hash_map32_t *const instance);
|
||||
HASHSET_API void hash_map_destroy64(hash_map64_t *const instance);
|
||||
|
||||
HASHSET_API errno_t hash_map_insert16(hash_map16_t *const instance, const uint16_t key, const uint16_t value);
|
||||
HASHSET_API errno_t hash_map_insert32(hash_map32_t *const instance, const uint32_t key, const uint32_t value);
|
||||
HASHSET_API errno_t hash_map_insert64(hash_map64_t *const instance, const uint64_t key, const uint64_t value);
|
||||
HASHSET_API errno_t hash_map_insert16(hash_map16_t *const instance, const uint16_t key, const uint16_t value, const int update);
|
||||
HASHSET_API errno_t hash_map_insert32(hash_map32_t *const instance, const uint32_t key, const uint32_t value, const int update);
|
||||
HASHSET_API errno_t hash_map_insert64(hash_map64_t *const instance, const uint64_t key, const uint64_t value, const int update);
|
||||
|
||||
HASHSET_API errno_t hash_map_remove16(hash_map16_t *const instance, const uint16_t key);
|
||||
HASHSET_API errno_t hash_map_remove32(hash_map32_t *const instance, const uint32_t key);
|
||||
HASHSET_API errno_t hash_map_remove64(hash_map64_t *const instance, const uint64_t key);
|
||||
HASHSET_API errno_t hash_map_remove16(hash_map16_t *const instance, const uint16_t key, uint16_t *const value);
|
||||
HASHSET_API errno_t hash_map_remove32(hash_map32_t *const instance, const uint32_t key, uint32_t *const value);
|
||||
HASHSET_API errno_t hash_map_remove64(hash_map64_t *const instance, const uint64_t key, uint64_t *const value);
|
||||
|
||||
HASHSET_API errno_t hash_map_clear16(hash_map16_t *const instance);
|
||||
HASHSET_API errno_t hash_map_clear32(hash_map32_t *const instance);
|
||||
|
@ -230,7 +230,7 @@ void DECLARE(hash_map_destroy)(hash_map_t *instance)
|
||||
}
|
||||
}
|
||||
|
||||
errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const value_t key, const value_t value)
|
||||
errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const value_t key, const value_t value, const bool_t update)
|
||||
{
|
||||
size_t index = SIZE_MAX;
|
||||
bool_t slot_reused;
|
||||
@ -241,12 +241,17 @@ errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const value_t key,
|
||||
}
|
||||
|
||||
if (find_slot(&instance->data, instance->basis, key, &index, &slot_reused))
|
||||
{
|
||||
if (update)
|
||||
{
|
||||
instance->data.entries[index].value = value;
|
||||
}
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
if ((!slot_reused) && (safe_add(instance->valid, instance->deleted) >= instance->limit))
|
||||
{
|
||||
if (instance->data.capacity < SIZE_MAX)
|
||||
{
|
||||
const errno_t error = rebuild_map(instance, safe_times2(instance->data.capacity));
|
||||
if (error)
|
||||
@ -258,6 +263,11 @@ errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const value_t key,
|
||||
return EFAULT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ENOMEM; /*can not grow any futher!*/
|
||||
}
|
||||
}
|
||||
|
||||
put_entry(&instance->data, index, key, value, slot_reused);
|
||||
|
||||
@ -298,7 +308,7 @@ errno_t DECLARE(hash_map_get)(const hash_map_t *const instance, const value_t ke
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno_t DECLARE(hash_map_remove)(hash_map_t *const instance, const value_t key)
|
||||
errno_t DECLARE(hash_map_remove)(hash_map_t *const instance, const value_t key, value_t *const value)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
@ -312,6 +322,7 @@ errno_t DECLARE(hash_map_remove)(hash_map_t *const instance, const value_t key)
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
SAFE_SET(value, instance->data.entries[index].value);
|
||||
set_flag(instance->data.deleted, index);
|
||||
instance->deleted = safe_incr(instance->deleted);
|
||||
instance->valid = safe_decr(instance->valid);
|
||||
|
@ -237,6 +237,8 @@ errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const value_t item)
|
||||
}
|
||||
|
||||
if ((!slot_reused) && (safe_add(instance->valid, instance->deleted) >= instance->limit))
|
||||
{
|
||||
if (instance->data.capacity < SIZE_MAX)
|
||||
{
|
||||
const errno_t error = rebuild_set(instance, safe_times2(instance->data.capacity));
|
||||
if (error)
|
||||
@ -248,6 +250,11 @@ errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const value_t item)
|
||||
return EFAULT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ENOMEM; /*can not grow any futher!*/
|
||||
}
|
||||
}
|
||||
|
||||
put_item(&instance->data, index, item, slot_reused);
|
||||
|
||||
|
@ -86,7 +86,7 @@ int test_function_1(hash_map64_t *const hash_map)
|
||||
{
|
||||
if (test_key1[j])
|
||||
{
|
||||
const errno_t error = hash_map_insert64(hash_map, j, test_data[j] = random_next(&random));
|
||||
const errno_t error = hash_map_insert64(hash_map, j, test_data[j] = random_next(&random), 1);
|
||||
if (error)
|
||||
{
|
||||
printf("Insert operation has failed! (error: %d)\n", error);
|
||||
@ -153,7 +153,7 @@ int test_function_1(hash_map64_t *const hash_map)
|
||||
{
|
||||
if (test_key1[j])
|
||||
{
|
||||
const errno_t error = hash_map_remove64(hash_map, j);
|
||||
const errno_t error = hash_map_remove64(hash_map, j, NULL);
|
||||
if (error)
|
||||
{
|
||||
printf("Remove operation has failed! (error: %d)\n", error);
|
||||
@ -238,7 +238,7 @@ int test_function_2(hash_map64_t *const hash_map)
|
||||
{
|
||||
if (test_key[j])
|
||||
{
|
||||
const errno_t error = hash_map_insert64(hash_map, j, test_val[j] = random_next(&random));
|
||||
const errno_t error = hash_map_insert64(hash_map, j, test_val[j] = random_next(&random), 1);
|
||||
if (error)
|
||||
{
|
||||
printf("Insert operation has failed! (error: %d)\n", error);
|
||||
@ -255,7 +255,7 @@ int test_function_2(hash_map64_t *const hash_map)
|
||||
{
|
||||
if (test_key[j])
|
||||
{
|
||||
const errno_t error = hash_map_insert64(hash_map, j, test_val[j] = random_next(&random));
|
||||
const errno_t error = hash_map_insert64(hash_map, j, test_val[j] = random_next(&random), 1);
|
||||
if (error != EEXIST)
|
||||
{
|
||||
printf("Insert operation has failed! (error: %d)\n", error);
|
||||
@ -325,7 +325,7 @@ int test_function_3(hash_map64_t *const hash_map)
|
||||
for (;;)
|
||||
{
|
||||
const uint64_t rnd = random_next(&random) & UINT64_C(0x1FFFFFFFFFFFFFF);
|
||||
const errno_t error = hash_map_insert64(hash_map, rnd, VALUE(rnd));
|
||||
const errno_t error = hash_map_insert64(hash_map, rnd, VALUE(rnd), 1);
|
||||
if (error)
|
||||
{
|
||||
if (error != EEXIST)
|
||||
@ -391,7 +391,7 @@ int test_function_4(hash_map64_t *const hash_map)
|
||||
|
||||
for (key = 0U; key < LIMIT; ++key)
|
||||
{
|
||||
const errno_t error = hash_map_insert64(hash_map, key, VALUE(key));
|
||||
const errno_t error = hash_map_insert64(hash_map, key, VALUE(key), 1);
|
||||
if (error)
|
||||
{
|
||||
PRINT_SET_INFO(4);
|
||||
@ -411,7 +411,7 @@ int test_function_4(hash_map64_t *const hash_map)
|
||||
|
||||
for (key = 0U; key < LIMIT; ++key)
|
||||
{
|
||||
const errno_t error = hash_map_remove64(hash_map, key);
|
||||
const errno_t error = hash_map_remove64(hash_map, key, NULL);
|
||||
if (error)
|
||||
{
|
||||
PRINT_SET_INFO(4);
|
||||
|
Loading…
Reference in New Issue
Block a user