disallow setting a key that already exists

Sat, 20 Sep 2025 12:27:36 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 20 Sep 2025 12:27:36 +0200
changeset 1382
f61119884dcd
parent 1381
ee421d6b95ef
child 1383
3db28cb1e5ec

disallow setting a key that already exists

relates to #461

src/kv_list.c file | annotate | diff | comparison | revisions
tests/test_kv_list.c file | annotate | diff | comparison | revisions
--- a/src/kv_list.c	Sat Sep 20 12:19:49 2025 +0200
+++ b/src/kv_list.c	Sat Sep 20 12:27:36 2025 +0200
@@ -470,8 +470,13 @@
         cx_hash_murmur(&key);
     }
 
-    // add the key to the map
-    // TODO: what happens when we are _replacing_ an existing key?
+    // check if the key is already assigned
+    if (kv_list->map_methods->get(&kv_list->map->map_base.base, key) != NULL) {
+        // key is already assigned, we disallow re-assignment
+        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;
     }
--- a/tests/test_kv_list.c	Sat Sep 20 12:19:49 2025 +0200
+++ b/tests/test_kv_list.c	Sat Sep 20 12:27:36 2025 +0200
@@ -424,6 +424,39 @@
     cxListFree(list);
 }
 
+CX_TEST(test_kv_list_set_key_already_exists) {
+    CxList *list = cxKvListCreateSimple(sizeof(int));
+    int x;
+    CX_TEST_DO {
+        x = 47;
+        cxListAdd(list, &x);
+        x = 11;
+        cxListAdd(list, &x);
+        CX_TEST_ASSERT(0 == cxKvListSetKey(list, 1, "xyz"));
+        // already exists
+        CX_TEST_ASSERT(0 != cxKvListSetKey(list, 0, "xyz"));
+
+        CxMap *map = cxKvListAsMap(list);
+
+        CX_TEST_ASSERT(cxMapSize(map) == 1);
+
+        int *y = cxMapGet(map, "xyz");
+        CX_TEST_ASSERT(y != NULL);
+        CX_TEST_ASSERT(*y == 11);
+
+        CX_TEST_ASSERT(0 == cxMapRemove(map, "xyz"));
+        CX_TEST_ASSERT(cxMapGet(map, "xyz") == NULL);
+        CX_TEST_ASSERT(cxListSize(list) == 1);
+
+        // now we can assign the key again
+        CX_TEST_ASSERT(0 == cxKvListSetKey(list, 0, "xyz"));
+        y = cxMapGet(map, "xyz");
+        CX_TEST_ASSERT(y != NULL);
+        CX_TEST_ASSERT(*y == 47);
+    }
+    cxListFree(list);
+}
+
 CX_TEST(test_kv_list_remove_key) {
     CxList *list = cxKvListCreateSimple(sizeof(int));
     int x;
@@ -765,6 +798,7 @@
     cx_test_register(suite, test_kv_list_map_remove);
     cx_test_register(suite, test_kv_list_map_remove_and_get);
     cx_test_register(suite, test_kv_list_set_key);
+    cx_test_register(suite, test_kv_list_set_key_already_exists);
     cx_test_register(suite, test_kv_list_remove_key);
     cx_test_register(suite, test_kv_list_insert_with_key);
     cx_test_register(suite, test_kv_list_insert_ptr_with_key);

mercurial