--- a/ucx/kv_list.c Wed Dec 17 18:31:20 2025 +0100 +++ b/ucx/kv_list.c Thu Dec 18 17:50:15 2025 +0100 @@ -221,11 +221,12 @@ size_t index; cx_linked_list *ll = &kv_list->list; - char *node = cx_linked_list_find( + char *node = cx_linked_list_find_c( ll->begin, ll->loc_next, ll->loc_data, - list->collection.cmpfunc, elem, - &index + elem, &index, + cx_list_compare_wrapper, + list ); if (node == NULL) { return list->collection.size; @@ -348,7 +349,7 @@ return 0; } -static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { +static CxMapEntry cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; // if the hash has not yet been computed, do it now if (key.hash == 0) { @@ -359,8 +360,8 @@ cx_kvl_map_remove(map, key, NULL); // now reserve new memory in the map - void **map_data = kv_list->map_methods->put(map, key, NULL); - if (map_data == NULL) return NULL; // LCOV_EXCL_LINE + CxMapEntry map_entry = kv_list->map_methods->put(map, key, NULL); + if (map_entry.key == NULL) return (CxMapEntry){NULL, NULL}; // LCOV_EXCL_LINE // insert the data into the list (which most likely destroys the sorted property) kv_list->list.base.collection.sorted = false; @@ -369,20 +370,20 @@ kv_list->list.base.collection.store_pointer ? &value : value); if (node_data == NULL) { // LCOV_EXCL_START // non-destructively remove the key again - kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data); - return NULL; + void *dummy; + kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &dummy); + return (CxMapEntry){NULL, NULL}; } // LCOV_EXCL_STOP // write the node pointer to the map entry - *map_data = node_data; + *(void**)map_entry.value = node_data; // copy the key to the node data CxHashKey *key_ptr = cx_kv_list_loc_key(kv_list, node_data); - *key_ptr = key; + *key_ptr = *map_entry.key; - // we must return node_data here and not map_data, - // because the node_data is the actual element of this collection - return node_data; + // we must return an entry that points to the node data! + return (CxMapEntry ){key_ptr, node_data}; } static void *cx_kvl_iter_current_entry(const void *it) { @@ -552,7 +553,6 @@ CxList *cxKvListCreate( const CxAllocator *allocator, - cx_compare_func comparator, size_t elem_size ) { if (allocator == NULL) { @@ -560,7 +560,7 @@ } // create a normal linked list and a normal hash map, first - CxList *list = cxLinkedListCreate(allocator, comparator, elem_size); + CxList *list = cxLinkedListCreate(allocator, elem_size); if (list == NULL) return NULL; // LCOV_EXCL_LINE cx_linked_list *ll = (cx_linked_list*)list; cx_linked_list_extra_data(ll, sizeof(CxHashKey)); @@ -600,23 +600,17 @@ // remember the base methods and override them kv_list->map_methods = map->cl; map->cl = &cx_kv_map_class; - if (list->climpl == NULL) { - kv_list->list_methods = list->cl; - list->cl = &cx_kv_list_class; - } else { - kv_list->list_methods = list->climpl; - list->climpl = &cx_kv_list_class; - } + kv_list->list_methods = list->cl; + list->cl = &cx_kv_list_class; return list; } CxMap *cxKvListCreateAsMap( const CxAllocator *allocator, - cx_compare_func comparator, size_t elem_size ) { - CxList *list = cxKvListCreate(allocator, comparator, elem_size); + CxList *list = cxKvListCreate(allocator, elem_size); return list == NULL ? NULL : cxKvListAsMap(list); } @@ -649,14 +643,14 @@ return 1; } - // add the key to the map; - if (NULL == kv_list->map_methods->put(&kv_list->map->map_base.base, key, node_data)) { - return 1; // LCOV_EXCL_LINE - } + // add the key to the map + const CxMapEntry entry = kv_list->map_methods->put( + &kv_list->map->map_base.base, key, node_data); + if (entry.key == NULL) return 1; // LCOV_EXCL_LINE // write the key to the list's node CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); - *loc_key = key; + *loc_key = *entry.key; return 0; } @@ -698,22 +692,23 @@ cx_kv_list *kv_list = (cx_kv_list*)list; // reserve memory in the map - void **map_data = kv_list->map_methods->put(&kv_list->map->map_base.base, key, NULL); - if (map_data == NULL) return 1; // LCOV_EXCL_LINE + CxMapEntry map_entry = kv_list->map_methods->put(&kv_list->map->map_base.base, key, NULL); + if (map_entry.key == NULL) return 1; // LCOV_EXCL_LINE // insert the node void *node_data = kv_list->list_methods->insert_element(&kv_list->list.base, index, kv_list->list.base.collection.store_pointer ? &value : value); if (node_data == NULL) { // LCOV_EXCL_START // non-destructively remove the key again - kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data); + void *dummy; + kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &dummy); return 1; } // LCOV_EXCL_STOP - *map_data = node_data; + *(void**)map_entry.value = node_data; // write the key to the node CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); - *loc_key = key; + *loc_key = *map_entry.key; return 0; }