src/kv_list.c

changeset 1360
8b29d732f97b
parent 1358
dda9c330e3e5
equal deleted inserted replaced
1359:fd7bbda93c7f 1360:8b29d732f97b
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);

mercurial