src/kv_list.c

changeset 1375
e0ba5e20e77a
parent 1373
a6aaa77b6809
--- a/src/kv_list.c	Sat Sep 13 20:55:56 2025 +0200
+++ b/src/kv_list.c	Sat Sep 13 20:57:59 2025 +0200
@@ -54,7 +54,7 @@
     void *map_destr_data;
 };
 
-static void cx_kv_list_destructor_wrapper_list(void *list_ptr, void *elem) {
+static void cx_kv_list_destructor_wrapper(void *list_ptr, void *elem) {
     const cx_kv_list *kv_list = list_ptr;
     // list destructor is already called with proper deref of the elem
     if (kv_list->list_destr) {
@@ -78,10 +78,10 @@
         list->list_destr = list->list.base.collection.simple_destructor;
         list->list.base.collection.simple_destructor = NULL;
     }
-    if (list->list.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper_list) {
+    if (list->list.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper) {
         list->list_destr2 = list->list.base.collection.advanced_destructor;
         list->list_destr_data = list->list.base.collection.destructor_data;
-        list->list.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper_list;
+        list->list.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper;
         list->list.base.collection.destructor_data = list;
     }
     if (list->map->map_base.base.collection.simple_destructor != NULL) {
@@ -204,9 +204,35 @@
         bool remove
 ) {
     cx_kv_list *kv_list = (cx_kv_list*)list;
-    cx_kv_list_update_destructors(kv_list);
-    // TODO: implement removal of the key in the map
-    return kv_list->list_methods->find_remove(list, elem, remove);
+    // we do not use the original list methods,
+    // because that would need two passes for removal
+    // (the first to find the index, the second to get a pointer)
+    if (list->collection.size == 0) return 0;
+
+    size_t index;
+    cx_linked_list *ll = &kv_list->list;
+    char *node = cx_linked_list_find(
+            ll->begin,
+            ll->loc_next, ll->loc_data,
+            list->collection.cmpfunc, elem,
+            &index
+    );
+    if (node == NULL) {
+        return list->collection.size;
+    }
+    if (remove) {
+        cx_kv_list_update_destructors(kv_list);
+        cx_invoke_advanced_destructor(list, node + ll->loc_data);
+        cx_linked_list_remove(&ll->begin, &ll->end,
+                              ll->loc_prev, ll->loc_next, node);
+        CxHashKey *key = cx_kv_list_loc_key(kv_list, node + ll->loc_data);
+        if (key->hash != 0) {
+            kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL);
+        }
+        list->collection.size--;
+        cxFree(list->collection.allocator, node);
+    }
+    return index;
 }
 
 static void cx_kvl_sort(struct cx_list_s *list) {

mercurial