src/kv_list.c

changeset 1360
8b29d732f97b
parent 1358
dda9c330e3e5
--- 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) {

mercurial