Mon, 01 Sep 2025 20:20:12 +0200
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; }