ucx/linked_list.c

branch
dav-2
changeset 886
da79af4baec8
parent 854
1c8401ece69e
child 889
42cdbf9bbd49
--- a/ucx/linked_list.c	Tue Sep 09 16:01:30 2025 +0200
+++ b/ucx/linked_list.c	Tue Sep 09 20:56:47 2025 +0200
@@ -401,7 +401,7 @@
 ) {
     void *sbo[CX_LINKED_LIST_SORT_SBO_SIZE];
     void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ?
-                    malloc(sizeof(void *) * length) : sbo;
+                    cxMallocDefault(sizeof(void *) * length) : sbo;
     if (sorted == NULL) abort();
     void *rc, *lc;
 
@@ -439,7 +439,7 @@
     *begin = sorted[0];
     *end = sorted[length - 1];
     if (sorted != sbo) {
-        free(sorted);
+        cxFreeDefault(sorted);
     }
 }
 
@@ -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;
@@ -613,7 +614,9 @@
 
     // initialize new new_node
     new_node->prev = new_node->next = NULL;
-    memcpy(new_node->payload, elem, list->collection.elem_size);
+    if (elem != NULL) {
+        memcpy(new_node->payload, elem, list->collection.elem_size);
+    }
 
     // insert
     cx_linked_list *ll = (cx_linked_list *) list;
@@ -659,12 +662,26 @@
     return n;
 }
 
-static int cx_ll_insert_element(
+static void *cx_ll_insert_element(
         struct cx_list_s *list,
         size_t index,
         const void *element
 ) {
-    return 1 != cx_ll_insert_array(list, index, element, 1);
+    // out-of-bounds check
+    if (index > list->collection.size) return NULL;
+
+    // find position efficiently
+    cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
+
+    // perform first insert
+    if (cx_ll_insert_at(list, node, element)) return NULL;
+
+    // return a pointer to the data of the inserted node
+    if (node == NULL) {
+        return ((cx_linked_list *) list)->begin->payload;
+    } else {
+        return node->next->payload;
+    }
 }
 
 static _Thread_local cx_compare_func cx_ll_insert_sorted_cmp_func;
@@ -920,6 +937,8 @@
         const void *elem,
         bool remove
 ) {
+    if (list->collection.size == 0) return 0;
+
     size_t index;
     cx_linked_list *ll = ((cx_linked_list *) list);
     cx_linked_list_node *node = cx_linked_list_find(
@@ -1054,12 +1073,12 @@
         }
         return result;
     } else {
-        int result = cx_ll_insert_element(list, list->collection.size, elem);
-        if (result == 0) {
-            iter->elem_count++;
-            iter->index = list->collection.size;
+        if (cx_ll_insert_element(list, list->collection.size, elem) == NULL) {
+            return 1;
         }
-        return result;
+        iter->elem_count++;
+        iter->index = list->collection.size;
+        return 0;
     }
 }
 

mercurial