src/kv_list.c

changeset 1375
e0ba5e20e77a
parent 1373
a6aaa77b6809
equal deleted inserted replaced
1374:4dceda670b05 1375:e0ba5e20e77a
52 cx_destructor_func map_destr; 52 cx_destructor_func map_destr;
53 cx_destructor_func2 map_destr2; 53 cx_destructor_func2 map_destr2;
54 void *map_destr_data; 54 void *map_destr_data;
55 }; 55 };
56 56
57 static void cx_kv_list_destructor_wrapper_list(void *list_ptr, void *elem) { 57 static void cx_kv_list_destructor_wrapper(void *list_ptr, void *elem) {
58 const cx_kv_list *kv_list = list_ptr; 58 const cx_kv_list *kv_list = list_ptr;
59 // list destructor is already called with proper deref of the elem 59 // list destructor is already called with proper deref of the elem
60 if (kv_list->list_destr) { 60 if (kv_list->list_destr) {
61 kv_list->list_destr(elem); 61 kv_list->list_destr(elem);
62 } 62 }
76 // an own destructor function which invokes all these 76 // an own destructor function which invokes all these
77 if (list->list.base.collection.simple_destructor != NULL) { 77 if (list->list.base.collection.simple_destructor != NULL) {
78 list->list_destr = list->list.base.collection.simple_destructor; 78 list->list_destr = list->list.base.collection.simple_destructor;
79 list->list.base.collection.simple_destructor = NULL; 79 list->list.base.collection.simple_destructor = NULL;
80 } 80 }
81 if (list->list.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper_list) { 81 if (list->list.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper) {
82 list->list_destr2 = list->list.base.collection.advanced_destructor; 82 list->list_destr2 = list->list.base.collection.advanced_destructor;
83 list->list_destr_data = list->list.base.collection.destructor_data; 83 list->list_destr_data = list->list.base.collection.destructor_data;
84 list->list.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper_list; 84 list->list.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper;
85 list->list.base.collection.destructor_data = list; 85 list->list.base.collection.destructor_data = list;
86 } 86 }
87 if (list->map->map_base.base.collection.simple_destructor != NULL) { 87 if (list->map->map_base.base.collection.simple_destructor != NULL) {
88 list->map_destr = list->map->map_base.base.collection.simple_destructor; 88 list->map_destr = list->map->map_base.base.collection.simple_destructor;
89 list->map->map_base.base.collection.simple_destructor = NULL; 89 list->map->map_base.base.collection.simple_destructor = NULL;
202 struct cx_list_s *list, 202 struct cx_list_s *list,
203 const void *elem, 203 const void *elem,
204 bool remove 204 bool remove
205 ) { 205 ) {
206 cx_kv_list *kv_list = (cx_kv_list*)list; 206 cx_kv_list *kv_list = (cx_kv_list*)list;
207 cx_kv_list_update_destructors(kv_list); 207 // we do not use the original list methods,
208 // TODO: implement removal of the key in the map 208 // because that would need two passes for removal
209 return kv_list->list_methods->find_remove(list, elem, remove); 209 // (the first to find the index, the second to get a pointer)
210 if (list->collection.size == 0) return 0;
211
212 size_t index;
213 cx_linked_list *ll = &kv_list->list;
214 char *node = cx_linked_list_find(
215 ll->begin,
216 ll->loc_next, ll->loc_data,
217 list->collection.cmpfunc, elem,
218 &index
219 );
220 if (node == NULL) {
221 return list->collection.size;
222 }
223 if (remove) {
224 cx_kv_list_update_destructors(kv_list);
225 cx_invoke_advanced_destructor(list, node + ll->loc_data);
226 cx_linked_list_remove(&ll->begin, &ll->end,
227 ll->loc_prev, ll->loc_next, node);
228 CxHashKey *key = cx_kv_list_loc_key(kv_list, node + ll->loc_data);
229 if (key->hash != 0) {
230 kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL);
231 }
232 list->collection.size--;
233 cxFree(list->collection.allocator, node);
234 }
235 return index;
210 } 236 }
211 237
212 static void cx_kvl_sort(struct cx_list_s *list) { 238 static void cx_kvl_sort(struct cx_list_s *list) {
213 cx_kv_list *kv_list = (cx_kv_list*)list; 239 cx_kv_list *kv_list = (cx_kv_list*)list;
214 kv_list->list_methods->sort(list); 240 kv_list->list_methods->sort(list);

mercurial