28 |
28 |
29 #include "cx/kv_list.h" |
29 #include "cx/kv_list.h" |
30 #include "cx/hash_map.h" |
30 #include "cx/hash_map.h" |
31 #include "cx/linked_list.h" |
31 #include "cx/linked_list.h" |
32 |
32 |
|
33 #include <string.h> |
|
34 |
33 typedef struct cx_kv_list_s cx_kv_list; |
35 typedef struct cx_kv_list_s cx_kv_list; |
34 |
36 |
35 struct cx_kv_list_map_s { |
37 struct cx_kv_list_map_s { |
36 struct cx_hash_map_s map_base; |
38 struct cx_hash_map_s map_base; |
37 /** Back-reference to the list. */ |
39 /** Back-reference to the list. */ |
198 return kv_list->map_methods->get(map, key); |
200 return kv_list->map_methods->get(map, key); |
199 } |
201 } |
200 |
202 |
201 int cx_kvl_map_remove(CxMap *map, CxHashKey key, void *targetbuf) { |
203 int cx_kvl_map_remove(CxMap *map, CxHashKey key, void *targetbuf) { |
202 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
204 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
203 // TODO: also remove the item from the list |
205 void *node_data; |
204 return kv_list->map_methods->remove(map, key, targetbuf); |
206 if (kv_list->map_methods->remove(map, key, &node_data)) { |
|
207 return 1; |
|
208 } |
|
209 // we cannot just call a list method (because we don't have the index) |
|
210 // and tbh. we also don't want to (because it's not performant when we |
|
211 // can have the node ptr directly instead) |
|
212 // therefore, we re-implement the logic ourselves |
|
213 |
|
214 // check if the outside caller want's us to return or to destroy the element |
|
215 if (targetbuf == NULL) { |
|
216 // destroy the element |
|
217 cx_invoke_destructor(&kv_list->list.list_base, node_data); |
|
218 } else { |
|
219 // copy the element to the target buffer |
|
220 memcpy(targetbuf, node_data, kv_list->list.list_base.collection.elem_size); |
|
221 } |
|
222 |
|
223 // calculate the address of the node |
|
224 void *node_ptr = (char*)node_data - 2*sizeof(void*); |
|
225 |
|
226 // unlink the node |
|
227 cx_linked_list_remove( |
|
228 &kv_list->list.begin, |
|
229 &kv_list->list.end, |
|
230 0, |
|
231 sizeof(void*), |
|
232 node_ptr |
|
233 ); |
|
234 |
|
235 // decrement the list's size |
|
236 kv_list->list.list_base.collection.size--; |
|
237 |
|
238 // deallocate the node |
|
239 cxFree(kv_list->list.list_base.collection.allocator, node_ptr); |
|
240 |
|
241 return 0; |
205 } |
242 } |
206 |
243 |
207 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) { |
244 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) { |
208 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
245 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
209 return kv_list->map_methods->iterator(map, type); |
246 return kv_list->map_methods->iterator(map, type); |