268 kv_list->map_methods->clear(map); |
268 kv_list->map_methods->clear(map); |
269 } |
269 } |
270 |
270 |
271 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { |
271 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { |
272 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
272 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
273 // insert the data into the list first (assume that insertion destroys the sorted property) |
273 // if the hash has not yet been computed, do it now |
|
274 if (key.hash == 0) { |
|
275 cx_hash_murmur(&key); |
|
276 } |
|
277 |
|
278 // reserve memory in the map first |
|
279 void **map_data = kv_list->map_methods->put(map, key, NULL); |
|
280 if (map_data == NULL) return NULL; // LCOV_EXCL_LINE |
|
281 |
|
282 // insert the data into the list (which most likely destroys the sorted property) |
274 kv_list->list.base.collection.sorted = false; |
283 kv_list->list.base.collection.sorted = false; |
275 void *node_data = kv_list->list_methods->insert_element( |
284 void *node_data = kv_list->list_methods->insert_element( |
276 &kv_list->list.base, kv_list->list.base.collection.size, |
285 &kv_list->list.base, kv_list->list.base.collection.size, |
277 kv_list->list.base.collection.store_pointer ? &value : value); |
286 kv_list->list.base.collection.store_pointer ? &value : value); |
278 if (node_data == NULL) return NULL; // LCOV_EXCL_LINE |
287 if (node_data == NULL) { // LCOV_EXCL_START |
279 // if the hash has not yet been computed, do it now |
288 // non-destructively remove the key again |
280 if (key.hash == 0) { |
289 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data); |
281 cx_hash_murmur(&key); |
290 return NULL; |
282 } |
291 } // LCOV_EXCL_STOP |
|
292 |
|
293 // write the node pointer to the map entry |
|
294 *map_data = node_data; |
|
295 |
283 // copy the key to the node data |
296 // copy the key to the node data |
284 CxHashKey *key_ptr = cx_kv_list_loc_key(kv_list, node_data); |
297 CxHashKey *key_ptr = cx_kv_list_loc_key(kv_list, node_data); |
285 *key_ptr = key; |
298 *key_ptr = key; |
286 // then insert the key into the map, referring to the node data |
299 return map_data; |
287 return kv_list->map_methods->put(map, key, node_data); |
|
288 } |
300 } |
289 |
301 |
290 void *cx_kvl_map_get(const CxMap *map, CxHashKey key) { |
302 void *cx_kvl_map_get(const CxMap *map, CxHashKey key) { |
291 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
303 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
292 void *node_data = kv_list->map_methods->get(map, key); |
304 void *node_data = kv_list->map_methods->get(map, key); |
489 } |
501 } |
490 |
502 |
491 int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) { |
503 int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) { |
492 cx_kv_list *kv_list = (cx_kv_list*)list; |
504 cx_kv_list *kv_list = (cx_kv_list*)list; |
493 |
505 |
|
506 // reserve memory in the map |
|
507 void **map_data = kv_list->map_methods->put(&kv_list->map->map_base.base, key, NULL); |
|
508 if (map_data == NULL) return 1; // LCOV_EXCL_LINE |
|
509 |
494 // insert the node |
510 // insert the node |
495 void *node_data = kv_list->list_methods->insert_element(&kv_list->list.base, index, |
511 void *node_data = kv_list->list_methods->insert_element(&kv_list->list.base, index, |
496 kv_list->list.base.collection.store_pointer ? &value : value); |
512 kv_list->list.base.collection.store_pointer ? &value : value); |
497 if (node_data == NULL) return -1; // LCOV_EXCL_LINE |
513 if (node_data == NULL) { // LCOV_EXCL_START |
498 |
514 // non-destructively remove the key again |
499 // add the key to the map |
515 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data); |
500 kv_list->map_methods->put(&kv_list->map->map_base.base, key, node_data); |
516 return 1; |
501 // TODO: get rid of the node again, when adding the entry to the map failed |
517 } // LCOV_EXCL_STOP |
|
518 *map_data = node_data; |
502 |
519 |
503 // write the key to the node |
520 // write the key to the node |
504 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); |
521 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); |
505 *loc_key = key; |
522 *loc_key = key; |
506 |
523 |