Tue, 02 Sep 2025 21:12:51 +0200
implement cx_kvl_map_remove()
relates to #461
src/kv_list.c | file | annotate | diff | comparison | revisions | |
src/linked_list.c | file | annotate | diff | comparison | revisions | |
tests/test_kv_list.c | file | annotate | diff | comparison | revisions |
--- a/src/kv_list.c Tue Sep 02 20:26:10 2025 +0200 +++ b/src/kv_list.c Tue Sep 02 21:12:51 2025 +0200 @@ -30,6 +30,8 @@ #include "cx/hash_map.h" #include "cx/linked_list.h" +#include <string.h> + typedef struct cx_kv_list_s cx_kv_list; struct cx_kv_list_map_s { @@ -200,8 +202,43 @@ int cx_kvl_map_remove(CxMap *map, CxHashKey key, void *targetbuf) { cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; - // TODO: also remove the item from the list - return kv_list->map_methods->remove(map, key, targetbuf); + void *node_data; + if (kv_list->map_methods->remove(map, key, &node_data)) { + return 1; + } + // we cannot just call a list method (because we don't have the index) + // and tbh. we also don't want to (because it's not performant when we + // can have the node ptr directly instead) + // therefore, we re-implement the logic ourselves + + // check if the outside caller want's us to return or to destroy the element + if (targetbuf == NULL) { + // destroy the element + cx_invoke_destructor(&kv_list->list.list_base, node_data); + } else { + // copy the element to the target buffer + memcpy(targetbuf, node_data, kv_list->list.list_base.collection.elem_size); + } + + // calculate the address of the node + void *node_ptr = (char*)node_data - 2*sizeof(void*); + + // unlink the node + cx_linked_list_remove( + &kv_list->list.begin, + &kv_list->list.end, + 0, + sizeof(void*), + node_ptr + ); + + // decrement the list's size + kv_list->list.list_base.collection.size--; + + // deallocate the node + cxFree(kv_list->list.list_base.collection.allocator, node_ptr); + + return 0; } CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) {
--- a/src/linked_list.c Tue Sep 02 20:26:10 2025 +0200 +++ b/src/linked_list.c Tue Sep 02 21:12:51 2025 +0200 @@ -565,6 +565,7 @@ // HIGH LEVEL LINKED LIST IMPLEMENTATION typedef struct cx_linked_list_node cx_linked_list_node; +// IMPORTANT: the layout must stay exactly like this, because kv_list.c uses that! struct cx_linked_list_node { cx_linked_list_node *prev; cx_linked_list_node *next;