make test_kv_list_map_put() pass default tip

Mon, 01 Sep 2025 20:20:12 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 01 Sep 2025 20:20:12 +0200
changeset 1358
dda9c330e3e5
parent 1357
cb25a4a12edd

make test_kv_list_map_put() pass

relates to #461

src/kv_list.c file | annotate | diff | comparison | revisions
--- a/src/kv_list.c	Sun Aug 31 13:37:00 2025 +0200
+++ b/src/kv_list.c	Mon Sep 01 20:20:12 2025 +0200
@@ -168,6 +168,47 @@
     return kv_list->list_methods->iterator(list, index, backward);
 }
 
+static void cx_kvl_map_deallocate(struct cx_map_s *map) {
+    cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
+    kv_list->map_methods->deallocate(map);
+    kv_list->list_methods->deallocate(&kv_list->list.list_base);
+}
+
+static void cx_kvl_map_clear(struct cx_map_s *map) {
+    cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
+    // TODO: iterate through the map elements and remove the key from the referenced list items
+    kv_list->map_methods->clear(map);
+}
+
+static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) {
+    cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
+    // insert the data into the list first (assume that insertion destroys the sorted property)
+    kv_list->list.list_base.collection.sorted = false;
+    // TODO: use the same trick as above to increase the element size temporarily to add the key to the data
+    void *node_data = kv_list->list_methods->insert_element(
+        &kv_list->list.list_base, kv_list->list.list_base.collection.size, value);
+    if (node_data == NULL) return NULL; // LCOV_EXCL_LINE
+    // then insert the key into the map, referring to the node data
+    // TODO: check if we still get a correct pointer when the list is storing pointers
+    return kv_list->map_methods->put(map, key, node_data);
+}
+
+void *cx_kvl_map_get(const CxMap *map, CxHashKey key) {
+    cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
+    return kv_list->map_methods->get(map, key);
+}
+
+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);
+}
+
+CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) {
+    cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
+    return kv_list->map_methods->iterator(map, type);
+}
+
 static cx_list_class cx_kv_list_class = {
     cx_kvl_deallocate,
     cx_kvl_insert_element,
@@ -185,6 +226,15 @@
     cx_kvl_iterator,
 };
 
+static cx_map_class cx_kv_map_class = {
+    cx_kvl_map_deallocate,
+    cx_kvl_map_clear,
+    cx_kvl_map_put,
+    cx_kvl_map_get,
+    cx_kvl_map_remove,
+    cx_kvl_map_iterator,
+};
+
 CxList *cxKvListCreate(
         const CxAllocator *allocator,
         cx_compare_func comparator,
@@ -211,7 +261,7 @@
     struct cx_kv_list_map_s *kv_map = cxRealloc(allocator, map, sizeof(struct cx_kv_list_map_s));
     
     // reallocate the list to add memory for storing the metadata
-    cx_kv_list *kv_list = cxRealloc(allocator, list, sizeof(cx_kv_list));
+    cx_kv_list *kv_list = cxRealloc(allocator, list, sizeof(struct cx_kv_list_s));
 
     // if any of the reallocations failed, we bail out
     if (kv_map != NULL && kv_list != NULL) {
@@ -229,6 +279,7 @@
 
     // 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;
@@ -236,8 +287,6 @@
         kv_list->list_methods = list->climpl;
         list->climpl = &cx_kv_list_class;
     }
-    // TODO: override all map members
-    //       and remember to set the sorted flag of the list to false in the put/emplace methods!
 
     return list;
 }

mercurial