src/kv_list.c

Sat, 20 Sep 2025 18:34:15 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 20 Sep 2025 18:34:15 +0200
changeset 1384
a2cfbff39e5d
parent 1383
3db28cb1e5ec
permissions
-rw-r--r--

implement non-mutating iterator

relates to #461

1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
4 * Copyright 2025 Mike Becker, Olaf Wintermann All rights reserved.
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 *
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 *
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 *
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 *
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 */
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29 #include "cx/kv_list.h"
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
30 #include "cx/hash_map.h"
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
31 #include "cx/linked_list.h"
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
32
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
33 #include <string.h>
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
34 #include <assert.h>
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
35
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
36 typedef struct cx_kv_list_s cx_kv_list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
37
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
38 struct cx_kv_list_map_s {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
39 struct cx_hash_map_s map_base;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
40 /** Back-reference to the list. */
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
41 cx_kv_list *list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
42 };
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
43
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
44 struct cx_kv_list_s {
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
45 struct cx_linked_list_s list;
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
46 /** The lookup map - stores pointers to the nodes. */
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
47 struct cx_kv_list_map_s *map;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
48 const cx_list_class *list_methods;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
49 const cx_map_class *map_methods;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
50 cx_destructor_func list_destr;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
51 cx_destructor_func2 list_destr2;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
52 void *list_destr_data;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
53 cx_destructor_func map_destr;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
54 cx_destructor_func2 map_destr2;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
55 void *map_destr_data;
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
56 };
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
57
1375
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
58 static void cx_kv_list_destructor_wrapper(void *list_ptr, void *elem) {
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
59 const cx_kv_list *kv_list = list_ptr;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
60 // list destructor is already called with proper deref of the elem
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
61 if (kv_list->list_destr) {
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
62 kv_list->list_destr(elem);
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
63 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
64 if (kv_list->list_destr2) {
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
65 kv_list->list_destr2(kv_list->list_destr_data, elem);
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
66 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
67 if (kv_list->map_destr) {
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
68 kv_list->map_destr(elem);
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
69 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
70 if (kv_list->map_destr2) {
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
71 kv_list->map_destr2(kv_list->map_destr_data, elem);
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
72 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
73 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
74
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
75 static void cx_kv_list_update_destructors(cx_kv_list *list) {
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
76 // we copy the destructors to our custom fields and register
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
77 // an own destructor function which invokes all these
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
78 if (list->list.base.collection.simple_destructor != NULL) {
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
79 list->list_destr = list->list.base.collection.simple_destructor;
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
80 list->list.base.collection.simple_destructor = NULL;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
81 }
1375
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
82 if (list->list.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper) {
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
83 list->list_destr2 = list->list.base.collection.advanced_destructor;
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
84 list->list_destr_data = list->list.base.collection.destructor_data;
1375
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
85 list->list.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper;
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
86 list->list.base.collection.destructor_data = list;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
87 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
88 if (list->map->map_base.base.collection.simple_destructor != NULL) {
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
89 list->map_destr = list->map->map_base.base.collection.simple_destructor;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
90 list->map->map_base.base.collection.simple_destructor = NULL;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
91 }
1368
19025ca34caa change kv-list destructor strategy to only use the list destructors
Mike Becker <universe@uap-core.de>
parents: 1367
diff changeset
92 if (list->map->map_base.base.collection.advanced_destructor != NULL) {
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
93 list->map_destr2 = list->map->map_base.base.collection.advanced_destructor;
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
94 list->map_destr_data = list->map->map_base.base.collection.destructor_data;
1368
19025ca34caa change kv-list destructor strategy to only use the list destructors
Mike Becker <universe@uap-core.de>
parents: 1367
diff changeset
95 list->map->map_base.base.collection.advanced_destructor = NULL;
19025ca34caa change kv-list destructor strategy to only use the list destructors
Mike Becker <universe@uap-core.de>
parents: 1367
diff changeset
96 list->map->map_base.base.collection.destructor_data = NULL;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
97 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
98 }
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
99
1373
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
100 static CxHashKey *cx_kv_list_loc_key(cx_kv_list *list, void *node_data) {
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
101 return (CxHashKey*)((char*)node_data + list->list.base.collection.elem_size);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
102 }
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
103
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
104 static void cx_kvl_deallocate(struct cx_list_s *list) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
105 cx_kv_list *kv_list = (cx_kv_list*)list;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
106 // patch the destructors
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
107 cx_kv_list_update_destructors(kv_list);
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
108 kv_list->map_methods->deallocate(&kv_list->map->map_base.base);
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
109 // then free the list, now the destructors may be called
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
110 kv_list->list_methods->deallocate(list);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
111 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
112
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
113 static void *cx_kvl_insert_element(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
114 struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
115 size_t index,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
116 const void *data
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
117 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
118 cx_kv_list *kv_list = (cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
119 return kv_list->list_methods->insert_element(list, index, data);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
120 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
121
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
122 static size_t cx_kvl_insert_array(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
123 struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
124 size_t index,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
125 const void *data,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
126 size_t n
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
127 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
128 cx_kv_list *kv_list = (cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
129 return kv_list->list_methods->insert_array(list, index, data, n);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
130 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
131
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
132 static size_t cx_kvl_insert_sorted(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
133 struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
134 const void *sorted_data,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
135 size_t n
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
136 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
137 cx_kv_list *kv_list = (cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
138 return kv_list->list_methods->insert_sorted(list, sorted_data, n);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
139 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
140
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
141 static int cx_kvl_insert_iter(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
142 struct cx_iterator_s *iter,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
143 const void *elem,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
144 int prepend
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
145 ) {
1362
d886626a9526 add several fixme and todo comments regarding invoking destructors
Mike Becker <universe@uap-core.de>
parents: 1361
diff changeset
146 cx_kv_list *kv_list = iter->src_handle.m;
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
147 return kv_list->list_methods->insert_iter(iter, elem, prepend);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
148 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
149
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
150 static size_t cx_kvl_remove(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
151 struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
152 size_t index,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
153 size_t num,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
154 void *targetbuf
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
155 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
156 cx_kv_list *kv_list = (cx_kv_list*)list;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
157 // patch the destructors
1373
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
158 // we also have to do that when targetbuf is NULL,
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
159 // because we do not want wrong destructors to be called when we remove keys from the map
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
160 cx_kv_list_update_destructors(kv_list);
1373
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
161 // iterate through the elements first and remove their keys from the map
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
162 CxIterator iter = kv_list->list_methods->iterator(list, index, false);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
163 for (size_t i = 0; i < num && cxIteratorValid(iter); i++) {
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
164 void *node_data = cxIteratorCurrent(iter);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
165 CxHashKey *key = cx_kv_list_loc_key(kv_list, node_data);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
166 // when the hash is zero, there is no key assigned to that element
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
167 if (key->hash != 0) {
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
168 kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
169 }
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
170 cxIteratorNext(iter);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
171 }
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
172 return kv_list->list_methods->remove(list, index, num, targetbuf);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
173 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
174
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
175 static void cx_kvl_clear(struct cx_list_s *list) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
176 cx_kv_list *kv_list = (cx_kv_list*)list;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
177 // patch the destructors
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
178 cx_kv_list_update_destructors(kv_list);
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
179 // clear the list
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
180 kv_list->list_methods->clear(list);
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
181 // then clear the map
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
182 kv_list->map_methods->clear(&kv_list->map->map_base.base);
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
183 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
184
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
185 static int cx_kvl_swap(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
186 struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
187 size_t i,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
188 size_t j
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
189 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
190 cx_kv_list *kv_list = (cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
191 return kv_list->list_methods->swap(list, i, j);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
192 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
193
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
194 static void *cx_kvl_at(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
195 const struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
196 size_t index
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
197 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
198 const cx_kv_list *kv_list = (const cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
199 return kv_list->list_methods->at(list, index);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
200 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
201
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
202 static size_t cx_kvl_find_remove(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
203 struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
204 const void *elem,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
205 bool remove
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
206 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
207 cx_kv_list *kv_list = (cx_kv_list*)list;
1375
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
208 // we do not use the original list methods,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
209 // because that would need two passes for removal
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
210 // (the first to find the index, the second to get a pointer)
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
211 if (list->collection.size == 0) return 0;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
212
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
213 size_t index;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
214 cx_linked_list *ll = &kv_list->list;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
215 char *node = cx_linked_list_find(
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
216 ll->begin,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
217 ll->loc_next, ll->loc_data,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
218 list->collection.cmpfunc, elem,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
219 &index
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
220 );
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
221 if (node == NULL) {
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
222 return list->collection.size;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
223 }
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
224 if (remove) {
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
225 cx_kv_list_update_destructors(kv_list);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
226 cx_invoke_advanced_destructor(list, node + ll->loc_data);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
227 cx_linked_list_remove(&ll->begin, &ll->end,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
228 ll->loc_prev, ll->loc_next, node);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
229 CxHashKey *key = cx_kv_list_loc_key(kv_list, node + ll->loc_data);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
230 if (key->hash != 0) {
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
231 kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
232 }
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
233 list->collection.size--;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
234 cxFree(list->collection.allocator, node);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
235 }
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
236 return index;
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
237 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
238
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
239 static void cx_kvl_sort(struct cx_list_s *list) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
240 cx_kv_list *kv_list = (cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
241 kv_list->list_methods->sort(list);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
242 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
243
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
244 static void cx_kvl_reverse(struct cx_list_s *list) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
245 cx_kv_list *kv_list = (cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
246 kv_list->list_methods->reverse(list);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
247 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
248
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
249 static struct cx_iterator_s cx_kvl_iterator(
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
250 const struct cx_list_s *list,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
251 size_t index,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
252 bool backward
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
253 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
254 const cx_kv_list *kv_list = (const cx_kv_list*)list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
255 // TODO: cannot really forward, because mutating iterators must be able to remove the element
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
256 return kv_list->list_methods->iterator(list, index, backward);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
257 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
258
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
259 static void cx_kvl_map_deallocate(struct cx_map_s *map) {
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
260 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
261 kv_list->map_methods->deallocate(map);
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
262 kv_list->list_methods->deallocate(&kv_list->list.base);
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
263 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
264
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
265 static void cx_kvl_map_clear(struct cx_map_s *map) {
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
266 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
267 cx_kv_list_update_destructors(kv_list);
1368
19025ca34caa change kv-list destructor strategy to only use the list destructors
Mike Becker <universe@uap-core.de>
parents: 1367
diff changeset
268 kv_list->list_methods->clear(&kv_list->list.base);
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
269 kv_list->map_methods->clear(map);
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
270 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
271
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
272 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) {
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
273 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
1381
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
274 // if the hash has not yet been computed, do it now
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
275 if (key.hash == 0) {
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
276 cx_hash_murmur(&key);
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
277 }
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
278
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
279 // reserve memory in the map first
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
280 void **map_data = kv_list->map_methods->put(map, key, NULL);
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
281 if (map_data == NULL) return NULL; // LCOV_EXCL_LINE
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
282
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
283 // insert the data into the list (which most likely destroys the sorted property)
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
284 kv_list->list.base.collection.sorted = false;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
285 void *node_data = kv_list->list_methods->insert_element(
1370
607f822c79fe kv-list: fix support for CX_STORE_POINTERS when using the map interface
Mike Becker <universe@uap-core.de>
parents: 1369
diff changeset
286 &kv_list->list.base, kv_list->list.base.collection.size,
607f822c79fe kv-list: fix support for CX_STORE_POINTERS when using the map interface
Mike Becker <universe@uap-core.de>
parents: 1369
diff changeset
287 kv_list->list.base.collection.store_pointer ? &value : value);
1381
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
288 if (node_data == NULL) { // LCOV_EXCL_START
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
289 // non-destructively remove the key again
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
290 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data);
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
291 return NULL;
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
292 } // LCOV_EXCL_STOP
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
293
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
294 // write the node pointer to the map entry
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
295 *map_data = node_data;
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
296
1373
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
297 // copy the key to the node data
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
298 CxHashKey *key_ptr = cx_kv_list_loc_key(kv_list, node_data);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
299 *key_ptr = key;
1381
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
300 return map_data;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
301 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
302
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
303 void *cx_kvl_map_get(const CxMap *map, CxHashKey key) {
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
304 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
1370
607f822c79fe kv-list: fix support for CX_STORE_POINTERS when using the map interface
Mike Becker <universe@uap-core.de>
parents: 1369
diff changeset
305 void *node_data = kv_list->map_methods->get(map, key);
607f822c79fe kv-list: fix support for CX_STORE_POINTERS when using the map interface
Mike Becker <universe@uap-core.de>
parents: 1369
diff changeset
306 if (node_data == NULL) return NULL; // LCOV_EXCL_LINE
607f822c79fe kv-list: fix support for CX_STORE_POINTERS when using the map interface
Mike Becker <universe@uap-core.de>
parents: 1369
diff changeset
307 // return the node data
607f822c79fe kv-list: fix support for CX_STORE_POINTERS when using the map interface
Mike Becker <universe@uap-core.de>
parents: 1369
diff changeset
308 return kv_list->list.base.collection.store_pointer ? *(void**)node_data : node_data;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
309 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
310
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
311 int cx_kvl_map_remove(CxMap *map, CxHashKey key, void *targetbuf) {
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
312 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
313
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
314 void *node_data;
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
315 if (kv_list->map_methods->remove(map, key, &node_data)) {
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
316 return 1;
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
317 }
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
318 // we cannot just call a list method (because we don't have the index)
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
319 // and tbh. we also don't want to (because it's not performant when we
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
320 // can have the node ptr directly instead)
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
321 // therefore, we re-implement the logic ourselves
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
322
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
323 // check if the outside caller want's us to return or to destroy the element
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
324 if (targetbuf == NULL) {
1365
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
325 // patch the destructors and invoke them through the wrapper
e4135791687e implement a patch function that results in (almost) always calling the correct destructors
Mike Becker <universe@uap-core.de>
parents: 1362
diff changeset
326 cx_kv_list_update_destructors(kv_list);
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
327 cx_invoke_advanced_destructor(&kv_list->list.base, node_data);
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
328 } else {
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
329 // copy the element to the target buffer
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
330 memcpy(targetbuf, node_data, kv_list->list.base.collection.elem_size);
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
331 }
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
332
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
333 // calculate the address of the node
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
334 void *node_ptr = (char*)node_data - kv_list->list.loc_data;
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
335
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
336 // unlink the node
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
337 cx_linked_list_remove(
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
338 &kv_list->list.begin,
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
339 &kv_list->list.end,
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
340 kv_list->list.loc_prev,
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
341 kv_list->list.loc_next,
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
342 node_ptr
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
343 );
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
344
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
345 // decrement the list's size
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
346 kv_list->list.base.collection.size--;
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
347
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
348 // deallocate the node
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
349 cxFree(kv_list->list.base.collection.allocator, node_ptr);
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
350
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
351 return 0;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
352 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
353
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
354 static void *cx_kvl_iter_current_entry(const void *it) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
355 const CxMapIterator *iter = it;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
356 return (void*)&iter->entry;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
357 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
358
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
359 static void *cx_kvl_iter_current_key(const void *it) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
360 const CxMapEntry *entry = cx_kvl_iter_current_entry(it);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
361 return (void*)entry->key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
362 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
363
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
364 static void *cx_kvl_iter_current_value(const void *it) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
365 const CxMapEntry *entry = cx_kvl_iter_current_entry(it);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
366 return entry->value;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
367 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
368
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
369 static void cx_kvl_iter_next(void *it) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
370 CxMapIterator *iter = it;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
371 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)iter->map.m)->list;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
372
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
373 // find the next list entry that has a key assigned
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
374 CxHashKey *key = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
375 char *next = iter->elem;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
376 while (true) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
377 next = *(char**)(next + kv_list->list.loc_next);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
378 if (next == NULL) break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
379 key = cx_kv_list_loc_key(kv_list, next + kv_list->list.loc_data);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
380 if (key->hash != 0) break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
381 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
382 if (next == NULL) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
383 iter->index = kv_list->list.base.collection.size;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
384 iter->elem = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
385 iter->entry = (CxMapEntry){NULL, NULL};
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
386 return;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
387 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
388
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
389 // TODO: implement removal
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
390
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
391 // advance to the next element
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
392 iter->index++;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
393 iter->elem = next;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
394 iter->entry.key = key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
395 if (kv_list->list.base.collection.store_pointer) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
396 iter->entry.value = *(void**)(next + kv_list->list.loc_data);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
397 } else {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
398 iter->entry.value = (void*)(next + kv_list->list.loc_data);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
399 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
400 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
401
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
402 static bool cx_kvl_iter_valid(const void *it) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
403 const CxMapIterator *iter = it;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
404 return iter->elem != NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
405 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
406
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
407 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) {
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
408 CxMapIterator iter = {};
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
409
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
410 iter.type = type;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
411 iter.map.c = map;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
412 // although we iterate over the list, we only report that many elements that have a key in the map
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
413 iter.elem_count = map->collection.size;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
414
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
415 switch (type) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
416 case CX_MAP_ITERATOR_PAIRS:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
417 iter.elem_size = sizeof(CxMapEntry);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
418 iter.base.current = cx_kvl_iter_current_entry;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
419 break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
420 case CX_MAP_ITERATOR_KEYS:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
421 iter.elem_size = sizeof(CxHashKey);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
422 iter.base.current = cx_kvl_iter_current_key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
423 break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
424 case CX_MAP_ITERATOR_VALUES:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
425 iter.elem_size = map->collection.elem_size;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
426 iter.base.current = cx_kvl_iter_current_value;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
427 break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
428 default:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
429 assert(false); // LCOV_EXCL_LINE
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
430 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
431
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
432 iter.base.next = cx_kvl_iter_next;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
433 iter.base.valid = cx_kvl_iter_valid;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
434
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
435 // find the first list entry that has a key assigned
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
436 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
437 CxHashKey *key = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
438 char *next = kv_list->list.begin;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
439 while (next != NULL) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
440 key = cx_kv_list_loc_key(kv_list, next + kv_list->list.loc_data);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
441 if (key->hash != 0) break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
442 next = *(char**)(next + kv_list->list.loc_next);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
443 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
444 if (next == NULL) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
445 iter.elem = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
446 iter.entry = (CxMapEntry){NULL, NULL};
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
447 } else {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
448 iter.elem = next;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
449 iter.entry.key = key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
450 if (kv_list->list.base.collection.store_pointer) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
451 iter.entry.value = *(void**)(next + kv_list->list.loc_data);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
452 } else {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
453 iter.entry.value = (void*)(next + kv_list->list.loc_data);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
454 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
455 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
456
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
457 return iter;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
458 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
459
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
460 static cx_list_class cx_kv_list_class = {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
461 cx_kvl_deallocate,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
462 cx_kvl_insert_element,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
463 cx_kvl_insert_array,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
464 cx_kvl_insert_sorted,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
465 cx_kvl_insert_iter,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
466 cx_kvl_remove,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
467 cx_kvl_clear,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
468 cx_kvl_swap,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
469 cx_kvl_at,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
470 cx_kvl_find_remove,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
471 cx_kvl_sort,
1352
8428516137dd make comparisons between kv_list and linked_list optimizable
Mike Becker <universe@uap-core.de>
parents: 1350
diff changeset
472 NULL,
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
473 cx_kvl_reverse,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
474 cx_kvl_iterator,
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
475 };
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
476
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
477 static cx_map_class cx_kv_map_class = {
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
478 cx_kvl_map_deallocate,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
479 cx_kvl_map_clear,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
480 cx_kvl_map_put,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
481 cx_kvl_map_get,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
482 cx_kvl_map_remove,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
483 cx_kvl_map_iterator,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
484 };
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
485
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
486 CxList *cxKvListCreate(
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
487 const CxAllocator *allocator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
488 cx_compare_func comparator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
489 size_t elem_size
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
490 ) {
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
491 if (allocator == NULL) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
492 allocator = cxDefaultAllocator;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
493 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
494
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
495 // create a normal linked list and a normal hash map, first
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
496 CxList *list = cxLinkedListCreate(allocator, comparator, elem_size);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
497 if (list == NULL) return NULL; // LCOV_EXCL_LINE
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
498 cx_linked_list *ll = (cx_linked_list*)list;
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
499 ll->extra_data_len = sizeof(CxHashKey);
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
500 CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
501 if (map == NULL) { // LCOV_EXCL_START
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
502 cxListFree(list);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
503 return NULL;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
504 } // LCOV_EXCL_STOP
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
505
1352
8428516137dd make comparisons between kv_list and linked_list optimizable
Mike Becker <universe@uap-core.de>
parents: 1350
diff changeset
506 // patch the kv-list class with the compare function of the linked list
8428516137dd make comparisons between kv_list and linked_list optimizable
Mike Becker <universe@uap-core.de>
parents: 1350
diff changeset
507 // this allows cxListCompare() to optimize comparisons between linked lists and kv-list
8428516137dd make comparisons between kv_list and linked_list optimizable
Mike Becker <universe@uap-core.de>
parents: 1350
diff changeset
508 cx_kv_list_class.compare = list->cl->compare;
8428516137dd make comparisons between kv_list and linked_list optimizable
Mike Becker <universe@uap-core.de>
parents: 1350
diff changeset
509
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
510 // reallocate the map to add memory for the list back-reference
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
511 struct cx_kv_list_map_s *kv_map = cxRealloc(allocator, map, sizeof(struct cx_kv_list_map_s));
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
512
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
513 // reallocate the list to add memory for storing the metadata
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
514 cx_kv_list *kv_list = cxRealloc(allocator, list, sizeof(struct cx_kv_list_s));
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
515
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
516 // if any of the reallocations failed, we bail out
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
517 if (kv_map != NULL && kv_list != NULL) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
518 map = (CxMap*) kv_map;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
519 list = (CxList*) kv_list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
520 } else { // LCOV_EXCL_START
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
521 cxListFree(list);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
522 cxMapFree(map);
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
523 return NULL;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
524 } // LCOV_EXCL_STOP
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
525
1371
37dcaeebe5ca kv-list: fix a possible source of UB when allocation fails during list creation
Mike Becker <universe@uap-core.de>
parents: 1370
diff changeset
526 // zero the custom destructor information
37dcaeebe5ca kv-list: fix a possible source of UB when allocation fails during list creation
Mike Becker <universe@uap-core.de>
parents: 1370
diff changeset
527 memset((char*)kv_list + offsetof(cx_kv_list, list_destr), 0, sizeof(void*)*6);
37dcaeebe5ca kv-list: fix a possible source of UB when allocation fails during list creation
Mike Becker <universe@uap-core.de>
parents: 1370
diff changeset
528
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
529 // combine the list and the map aspect
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
530 kv_list->map = kv_map;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
531 kv_map->list = kv_list;
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
532
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
533 // remember the base methods and override them
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
534 kv_list->map_methods = map->cl;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
535 map->cl = &cx_kv_map_class;
1353
5a13b9c1c57b fix that the wrong vtable is patched when CX_STORE_POINTERS is used
Mike Becker <universe@uap-core.de>
parents: 1352
diff changeset
536 if (list->climpl == NULL) {
5a13b9c1c57b fix that the wrong vtable is patched when CX_STORE_POINTERS is used
Mike Becker <universe@uap-core.de>
parents: 1352
diff changeset
537 kv_list->list_methods = list->cl;
5a13b9c1c57b fix that the wrong vtable is patched when CX_STORE_POINTERS is used
Mike Becker <universe@uap-core.de>
parents: 1352
diff changeset
538 list->cl = &cx_kv_list_class;
5a13b9c1c57b fix that the wrong vtable is patched when CX_STORE_POINTERS is used
Mike Becker <universe@uap-core.de>
parents: 1352
diff changeset
539 } else {
5a13b9c1c57b fix that the wrong vtable is patched when CX_STORE_POINTERS is used
Mike Becker <universe@uap-core.de>
parents: 1352
diff changeset
540 kv_list->list_methods = list->climpl;
5a13b9c1c57b fix that the wrong vtable is patched when CX_STORE_POINTERS is used
Mike Becker <universe@uap-core.de>
parents: 1352
diff changeset
541 list->climpl = &cx_kv_list_class;
5a13b9c1c57b fix that the wrong vtable is patched when CX_STORE_POINTERS is used
Mike Becker <universe@uap-core.de>
parents: 1352
diff changeset
542 }
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
543
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
544 return list;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
545 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
546
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
547 CxMap *cxKvListCreateAsMap(
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
548 const CxAllocator *allocator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
549 cx_compare_func comparator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
550 size_t elem_size
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
551 ) {
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
552 CxList *list = cxKvListCreate(allocator, comparator, elem_size);
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
553 return list == NULL ? NULL : cxKvListAsMap(list);
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
554 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
555
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
556 CxList *cxKvListAsList(CxMap *map) {
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
557 return &((struct cx_kv_list_map_s*)map)->list->list.base;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
558 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
559
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
560 CxMap *cxKvListAsMap(CxList *list) {
1350
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
561 return &((cx_kv_list*)list)->map->map_base.base;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
562 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
563
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
564 int cx_kv_list_set_key(CxList *list, size_t index, CxHashKey key) {
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
565 cx_kv_list *kv_list = (cx_kv_list*)list;
1373
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
566 void *node_data = kv_list->list_methods->at(list, index);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
567 if (node_data == NULL) {
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
568 return 1;
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
569 }
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
570 // if the hash has not yet been computed, do it now
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
571 if (key.hash == 0) {
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
572 cx_hash_murmur(&key);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
573 }
1376
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
574
1382
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
575 // check if the key is already assigned
1383
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
576 void *existing = kv_list->map_methods->get(&kv_list->map->map_base.base, key);
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
577 if (existing == node_data) {
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
578 return 0; // nothing to do
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
579 }
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
580 if (existing != NULL) {
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
581 // the key is already assigned to another node, we disallow re-assignment
1382
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
582 return 1;
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
583 }
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
584
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
585 // add the key to the map;
1376
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
586 if (NULL == kv_list->map_methods->put(&kv_list->map->map_base.base, key, node_data)) {
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
587 return 1; // LCOV_EXCL_LINE
1376
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
588 }
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
589
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
590 // write the key to the list's node
1373
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
591 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
592 *loc_key = key;
1367
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
593
6b3d52dd176e change linked_list.c to allow custom data in nodes + implement cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1365
diff changeset
594 return 0;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
595 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
596
1377
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
597 int cxKvListRemoveKey(CxList *list, size_t index) {
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
598 cx_kv_list *kv_list = (cx_kv_list*)list;
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
599 void *node_data = kv_list->list_methods->at(list, index);
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
600 if (node_data == NULL) {
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
601 return 1;
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
602 }
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
603 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data);
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
604 if (loc_key->hash == 0) {
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
605 return 0;
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
606 }
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
607 kv_list->map_methods->remove(&kv_list->map->map_base.base, *loc_key, NULL);
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
608 // also zero the memory in the list node,
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
609 // but don't free the key data (that was done by the map remove)
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
610 memset(loc_key, 0, sizeof(CxHashKey));
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
611 return 0;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
612 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
613
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
614 int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) {
1378
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
615 cx_kv_list *kv_list = (cx_kv_list*)list;
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
616
1381
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
617 // reserve memory in the map
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
618 void **map_data = kv_list->map_methods->put(&kv_list->map->map_base.base, key, NULL);
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
619 if (map_data == NULL) return 1; // LCOV_EXCL_LINE
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
620
1379
9ad4a7011528 improve cx_kv_list_insert() by using low level access to the list method
Mike Becker <universe@uap-core.de>
parents: 1378
diff changeset
621 // insert the node
9ad4a7011528 improve cx_kv_list_insert() by using low level access to the list method
Mike Becker <universe@uap-core.de>
parents: 1378
diff changeset
622 void *node_data = kv_list->list_methods->insert_element(&kv_list->list.base, index,
9ad4a7011528 improve cx_kv_list_insert() by using low level access to the list method
Mike Becker <universe@uap-core.de>
parents: 1378
diff changeset
623 kv_list->list.base.collection.store_pointer ? &value : value);
1381
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
624 if (node_data == NULL) { // LCOV_EXCL_START
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
625 // non-destructively remove the key again
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
626 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data);
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
627 return 1;
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
628 } // LCOV_EXCL_STOP
ee421d6b95ef consider the edge case that either list or map operation fails when adding an element
Mike Becker <universe@uap-core.de>
parents: 1379
diff changeset
629 *map_data = node_data;
1378
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
630
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
631 // write the key to the node
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
632 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data);
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
633 *loc_key = key;
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
634
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
635 return 0;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
636 }

mercurial