src/kv_list.c

Sun, 23 Nov 2025 13:15:19 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 23 Nov 2025 13:15:19 +0100
changeset 1508
dfc0ddd9571e
parent 1482
6769cb72521b
permissions
-rw-r--r--

optimize sorted insertion by using the infimum instead of the supremum

The reason is that the supremum returns the equal element with the smallest index, and we want the largest.
Therefore, we use the infimum, which already gives us the largest index when there are equal elements, and increase the index by one. The infimum is also guaranteed to exist in that case.

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
1419
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
141 static size_t cx_kvl_insert_unique(
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
142 struct cx_list_s *list,
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
143 const void *sorted_data,
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
144 size_t n
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
145 ) {
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
146 cx_kv_list *kv_list = (cx_kv_list*)list;
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
147 return kv_list->list_methods->insert_unique(list, sorted_data, n);
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
148 }
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
149
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
150 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
151 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
152 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
153 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
154 ) {
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1419
diff changeset
155 cx_kv_list *kv_list = iter->src_handle;
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
156 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
157 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
158
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
159 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
160 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
161 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
162 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
163 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
164 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
165 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
166 // 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
167 // 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
168 // 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
169 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
170 // 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
171 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
172 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
173 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
174 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
175 // 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
176 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
177 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
178 }
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
179 cxIteratorNext(iter);
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
180 }
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
181 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
182 }
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 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
185 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
186 // 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
187 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
188 // 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
189 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
190 // 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
191 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
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 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
195 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 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
197 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
198 ) {
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 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
200 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
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
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 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
204 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
205 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
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 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
208 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
209 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
210
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
211 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
212 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
213 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
214 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
215 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
216 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
217 // we do not use the original list methods,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
218 // because that would need two passes for removal
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
219 // (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
220 if (list->collection.size == 0) return 0;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
221
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
222 size_t index;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
223 cx_linked_list *ll = &kv_list->list;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
224 char *node = cx_linked_list_find(
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
225 ll->begin,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
226 ll->loc_next, ll->loc_data,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
227 list->collection.cmpfunc, elem,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
228 &index
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
229 );
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
230 if (node == NULL) {
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
231 return list->collection.size;
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 if (remove) {
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
234 cx_kv_list_update_destructors(kv_list);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
235 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
236 cx_linked_list_remove(&ll->begin, &ll->end,
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
237 ll->loc_prev, ll->loc_next, node);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
238 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
239 if (key->hash != 0) {
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
240 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
241 }
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
242 list->collection.size--;
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
243 cxFree(list->collection.allocator, node);
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
244 }
e0ba5e20e77a implement cx_kvl_find_remove()
Mike Becker <universe@uap-core.de>
parents: 1373
diff changeset
245 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
246 }
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 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
249 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
250 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
251 }
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
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 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
254 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
255 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
256 }
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
1386
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
258 static void cx_kvl_list_iter_next(void *it) {
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
259 struct cx_iterator_s *iter = it;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
260 if (iter->base.remove) {
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
261 // remove the assigned key from the map before calling the actual function
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1419
diff changeset
262 cx_kv_list *kv_list = iter->src_handle;
1386
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
263 cx_kv_list_update_destructors(kv_list);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
264 char *node = iter->elem_handle;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
265 CxHashKey *key = cx_kv_list_loc_key(kv_list, node + kv_list->list.loc_data);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
266 if (key->hash != 0) {
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
267 kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
268 }
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
269 }
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1419
diff changeset
270 // note that we do not clear the remove flag, because the next_impl will do that
1386
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
271 iter->base.next_impl(it);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
272 }
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
273
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
274 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
275 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
276 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
277 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
278 ) {
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
279 const cx_kv_list *kv_list = (const cx_kv_list*)list;
1386
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
280 struct cx_iterator_s iter = kv_list->list_methods->iterator(list, index, backward);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
281 iter.base.next_impl = iter.base.next;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
282 iter.base.next = cx_kvl_list_iter_next;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
283 return iter;
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
284 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
285
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
286 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
287 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
288 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
289 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
290 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
291
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
292 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
293 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
294 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
295 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
296 kv_list->map_methods->clear(map);
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
297 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
298
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
299 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
300 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
301 // 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
302 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
303 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
304 }
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
305
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
306 // 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
307 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
308 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
309
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
310 // 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
311 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
312 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
313 &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
314 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
315 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
316 // 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
317 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
318 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
319 } // 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
320
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
321 // 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
322 *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
323
1373
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
324 // 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
325 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
326 *key_ptr = key;
1397
a5c7d63b064d fix cx_kvl_map_put() returning the wrong pointer
Mike Becker <universe@uap-core.de>
parents: 1394
diff changeset
327
a5c7d63b064d fix cx_kvl_map_put() returning the wrong pointer
Mike Becker <universe@uap-core.de>
parents: 1394
diff changeset
328 // we must return node_data here and not map_data,
a5c7d63b064d fix cx_kvl_map_put() returning the wrong pointer
Mike Becker <universe@uap-core.de>
parents: 1394
diff changeset
329 // because the node_data is the actual element of this collection
a5c7d63b064d fix cx_kvl_map_put() returning the wrong pointer
Mike Becker <universe@uap-core.de>
parents: 1394
diff changeset
330 return node_data;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
331 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
332
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
333 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
334 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
335 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
336 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
337 // 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
338 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
339 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
340
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
341 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
342 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
343
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
344 void *node_data;
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
345 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
346 return 1;
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 // 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
349 // 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
350 // can have the node ptr directly instead)
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
351 // therefore, we re-implement the logic ourselves
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
352
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
353 // 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
354 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
355 // 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
356 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
357 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
358 } else {
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
359 // 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
360 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
361 }
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
362
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
363 // 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
364 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
365
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
366 // unlink the node
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
367 cx_linked_list_remove(
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
368 &kv_list->list.begin,
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
369 &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
370 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
371 kv_list->list.loc_next,
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
372 node_ptr
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
373 );
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
374
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
375 // 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
376 kv_list->list.base.collection.size--;
1360
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
377
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
378 // 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
379 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
380
8b29d732f97b implement cx_kvl_map_remove()
Mike Becker <universe@uap-core.de>
parents: 1358
diff changeset
381 return 0;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
382 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
383
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
384 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
385 const CxMapIterator *iter = it;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
386 return (void*)&iter->entry;
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 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
390 const CxMapEntry *entry = cx_kvl_iter_current_entry(it);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
391 return (void*)entry->key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
392 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
393
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
394 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
395 const CxMapEntry *entry = cx_kvl_iter_current_entry(it);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
396 return entry->value;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
397 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
398
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
399 static void cx_kvl_iter_next(void *it) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
400 CxMapIterator *iter = it;
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1419
diff changeset
401 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)iter->map)->list;
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
402
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
403 // 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
404 CxHashKey *key = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
405 char *next = iter->elem;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
406 while (true) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
407 next = *(char**)(next + kv_list->list.loc_next);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
408 if (next == NULL) break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
409 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
410 if (key->hash != 0) break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
411 }
1386
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
412
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
413 // remove previous element if requested
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
414 if (iter->base.remove) {
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
415 iter->base.remove = false;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
416 cx_kv_list_update_destructors(kv_list);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
417 char *elem = iter->elem;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
418 char *elem_data = elem + kv_list->list.loc_data;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
419 CxHashKey *elem_key = cx_kv_list_loc_key(kv_list, elem_data);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
420 // key is guaranteed to exist because iterator only iterates over elems with a key
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
421 kv_list->map_methods->remove(&kv_list->map->map_base.base, *elem_key, NULL);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
422 cx_invoke_advanced_destructor(&kv_list->list.base, elem_data);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
423 cx_linked_list_remove(
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
424 &kv_list->list.begin,
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
425 &kv_list->list.end,
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
426 kv_list->list.loc_prev,
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
427 kv_list->list.loc_next,
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
428 elem
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
429 );
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
430 cxFree(kv_list->list.base.collection.allocator, elem);
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
431 kv_list->list.base.collection.size--;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
432 iter->index--;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
433 iter->elem_count--;
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
434 }
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
435
748d0d40881e kv-list: implement mutating iterator support
Mike Becker <universe@uap-core.de>
parents: 1384
diff changeset
436 // advance to the next element, if any
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
437 if (next == NULL) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
438 iter->index = kv_list->list.base.collection.size;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
439 iter->elem = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
440 iter->entry = (CxMapEntry){NULL, NULL};
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
441 return;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
442 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
443 iter->index++;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
444 iter->elem = next;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
445 iter->entry.key = key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
446 if (kv_list->list.base.collection.store_pointer) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
447 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
448 } else {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
449 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
450 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
451 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
452
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
453 static bool cx_kvl_iter_valid(const void *it) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
454 const CxMapIterator *iter = it;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
455 return iter->elem != NULL;
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
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
458 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) {
1405
0f6515875a09 fix using empty initializer, which is a C23 extension
Mike Becker <universe@uap-core.de>
parents: 1397
diff changeset
459 CxMapIterator iter = {0};
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
460
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
461 iter.type = type;
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1419
diff changeset
462 iter.map = (CxMap*)map;
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
463 // 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
464 iter.elem_count = map->collection.size;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
465
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
466 switch (type) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
467 case CX_MAP_ITERATOR_PAIRS:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
468 iter.elem_size = sizeof(CxMapEntry);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
469 iter.base.current = cx_kvl_iter_current_entry;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
470 break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
471 case CX_MAP_ITERATOR_KEYS:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
472 iter.elem_size = sizeof(CxHashKey);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
473 iter.base.current = cx_kvl_iter_current_key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
474 break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
475 case CX_MAP_ITERATOR_VALUES:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
476 iter.elem_size = map->collection.elem_size;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
477 iter.base.current = cx_kvl_iter_current_value;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
478 break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
479 default:
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
480 assert(false); // LCOV_EXCL_LINE
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
481 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
482
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1419
diff changeset
483 iter.base.allow_remove = true;
1384
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
484 iter.base.next = cx_kvl_iter_next;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
485 iter.base.valid = cx_kvl_iter_valid;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
486
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
487 // 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
488 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
489 CxHashKey *key = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
490 char *next = kv_list->list.begin;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
491 while (next != NULL) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
492 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
493 if (key->hash != 0) break;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
494 next = *(char**)(next + kv_list->list.loc_next);
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
495 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
496 if (next == NULL) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
497 iter.elem = NULL;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
498 iter.entry = (CxMapEntry){NULL, NULL};
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
499 } else {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
500 iter.elem = next;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
501 iter.entry.key = key;
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
502 if (kv_list->list.base.collection.store_pointer) {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
503 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
504 } else {
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
505 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
506 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
507 }
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
508
a2cfbff39e5d implement non-mutating iterator
Mike Becker <universe@uap-core.de>
parents: 1383
diff changeset
509 return iter;
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
510 }
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
511
1482
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
512 static int cx_kvl_change_capacity(struct cx_list_s *list,
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
513 cx_attr_unused size_t cap) {
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
514 // since our backing list is a linked list, we don't need to do much here,
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
515 // but rehashing the map is quite useful
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
516 cx_kv_list *kv_list = (cx_kv_list*)list;
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
517 cxMapRehash(&kv_list->map->map_base.base);
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
518 return 0;
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
519 }
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
520
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
521 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
522 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
523 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
524 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
525 cx_kvl_insert_sorted,
1419
e46406fd1b3c add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents: 1405
diff changeset
526 cx_kvl_insert_unique,
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
527 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
528 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
529 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
530 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
531 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
532 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
533 cx_kvl_sort,
1352
8428516137dd make comparisons between kv_list and linked_list optimizable
Mike Becker <universe@uap-core.de>
parents: 1350
diff changeset
534 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
535 cx_kvl_reverse,
1482
6769cb72521b implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents: 1429
diff changeset
536 cx_kvl_change_capacity,
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
537 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
538 };
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
539
1358
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
540 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
541 cx_kvl_map_deallocate,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
542 cx_kvl_map_clear,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
543 cx_kvl_map_put,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
544 cx_kvl_map_get,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
545 cx_kvl_map_remove,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
546 cx_kvl_map_iterator,
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
547 };
dda9c330e3e5 make test_kv_list_map_put() pass
Mike Becker <universe@uap-core.de>
parents: 1353
diff changeset
548
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
549 CxList *cxKvListCreate(
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
550 const CxAllocator *allocator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
551 cx_compare_func comparator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
552 size_t elem_size
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
553 ) {
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
554 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
555 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
556 }
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
557
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
558 // 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
559 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
560 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
561 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
562 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
563 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
564 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
565 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
566 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
567 } // 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
568
1352
8428516137dd make comparisons between kv_list and linked_list optimizable
Mike Becker <universe@uap-core.de>
parents: 1350
diff changeset
569 // 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
570 // 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
571 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
572
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
573 // 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
574 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
575
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
576 // 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
577 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
578
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
579 // 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
580 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
581 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
582 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
583 } 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
584 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
585 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
586 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
587 } // 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
588
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
589 // 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
590 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
591
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
592 // 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
593 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
594 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
595
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
596 // 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
597 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
598 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
599 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
600 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
601 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
602 } 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
603 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
604 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
605 }
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
606
189756516eaa implement kv-list to a point where it correctly behaves like a list
Mike Becker <universe@uap-core.de>
parents: 1348
diff changeset
607 return list;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
608 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
609
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
610 CxMap *cxKvListCreateAsMap(
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
611 const CxAllocator *allocator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
612 cx_compare_func comparator,
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
613 size_t elem_size
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
614 ) {
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
615 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
616 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
617 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
618
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
619 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
620 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
621 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
622
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
623 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
624 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
625 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
626
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
627 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
628 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
629 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
630 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
631 return 1;
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
632 }
a6aaa77b6809 make cx_kvl_remove() also remove the keys from the map
Mike Becker <universe@uap-core.de>
parents: 1372
diff changeset
633 // 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
634 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
635 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
636 }
1376
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
637
1382
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
638 // 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
639 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
640 if (existing == node_data) {
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
641 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
642 }
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
643 if (existing != NULL) {
3db28cb1e5ec allow setting the key again on the same node
Mike Becker <universe@uap-core.de>
parents: 1382
diff changeset
644 // 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
645 return 1;
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
646 }
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
647
f61119884dcd disallow setting a key that already exists
Mike Becker <universe@uap-core.de>
parents: 1381
diff changeset
648 // 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
649 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
650 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
651 }
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
652
0698e573936f add error handling to cx_kv_list_set_key()
Mike Becker <universe@uap-core.de>
parents: 1375
diff changeset
653 // 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
654 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
655 *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
656
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
657 return 0;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
658 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
659
1377
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
660 int cxKvListRemoveKey(CxList *list, size_t index) {
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
661 cx_kv_list *kv_list = (cx_kv_list*)list;
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
662 void *node_data = kv_list->list_methods->at(list, index);
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
663 if (node_data == NULL) {
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
664 return 1;
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
665 }
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
666 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
667 if (loc_key->hash == 0) {
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
668 return 0;
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
669 }
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
670 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
671 // also zero the memory in the list node,
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
672 // 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
673 memset(loc_key, 0, sizeof(CxHashKey));
1562bdf948da implement cxKvListRemoveKey()
Mike Becker <universe@uap-core.de>
parents: 1376
diff changeset
674 return 0;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
675 }
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
676
1394
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
677 const CxHashKey *cxKvListGetKey(CxList *list, size_t index) {
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
678 cx_kv_list *kv_list = (cx_kv_list*)list;
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
679 void *node_data = kv_list->list_methods->at(list, index);
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
680 if (node_data == NULL) {
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
681 return NULL;
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
682 }
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
683 CxHashKey *key = cx_kv_list_loc_key(kv_list, node_data);
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
684 if (key->hash == 0) {
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
685 return NULL;
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
686 }
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
687 return key;
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
688 }
7b23c6db9500 add cxKvListGetKey()
Mike Becker <universe@uap-core.de>
parents: 1393
diff changeset
689
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
690 int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) {
1393
461d256e32c6 fix that cxKvListInsert() did not lose the sorted property
Mike Becker <universe@uap-core.de>
parents: 1386
diff changeset
691 // assume we are losing the sorted property
461d256e32c6 fix that cxKvListInsert() did not lose the sorted property
Mike Becker <universe@uap-core.de>
parents: 1386
diff changeset
692 list->collection.sorted = false;
461d256e32c6 fix that cxKvListInsert() did not lose the sorted property
Mike Becker <universe@uap-core.de>
parents: 1386
diff changeset
693
1378
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
694 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
695
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
696 // 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
697 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
698 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
699
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
700 // 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
701 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
702 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
703 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
704 // 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
705 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
706 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
707 } // 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
708 *map_data = node_data;
1378
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
709
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
710 // write the key to the node
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
711 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
712 *loc_key = key;
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
713
1b4fa55f7caa implement cx_kv_list_insert()
Mike Becker <universe@uap-core.de>
parents: 1377
diff changeset
714 return 0;
1348
a1da355ed3b8 roll out the function stubs for the kv-list
Mike Becker <universe@uap-core.de>
parents:
diff changeset
715 }

mercurial