| 346 cxFree(kv_list->list.base.collection.allocator, node_ptr); |
346 cxFree(kv_list->list.base.collection.allocator, node_ptr); |
| 347 |
347 |
| 348 return 0; |
348 return 0; |
| 349 } |
349 } |
| 350 |
350 |
| 351 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { |
351 static CxMapEntry cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { |
| 352 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
352 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
| 353 // if the hash has not yet been computed, do it now |
353 // if the hash has not yet been computed, do it now |
| 354 if (key.hash == 0) { |
354 if (key.hash == 0) { |
| 355 cx_hash_murmur(&key); |
355 cx_hash_murmur(&key); |
| 356 } |
356 } |
| 357 |
357 |
| 358 // remove any existing element first |
358 // remove any existing element first |
| 359 cx_kvl_map_remove(map, key, NULL); |
359 cx_kvl_map_remove(map, key, NULL); |
| 360 |
360 |
| 361 // now reserve new memory in the map |
361 // now reserve new memory in the map |
| 362 void **map_data = kv_list->map_methods->put(map, key, NULL); |
362 CxMapEntry map_entry = kv_list->map_methods->put(map, key, NULL); |
| 363 if (map_data == NULL) return NULL; // LCOV_EXCL_LINE |
363 if (map_entry.key == NULL) return (CxMapEntry){NULL, NULL}; // LCOV_EXCL_LINE |
| 364 |
364 |
| 365 // insert the data into the list (which most likely destroys the sorted property) |
365 // insert the data into the list (which most likely destroys the sorted property) |
| 366 kv_list->list.base.collection.sorted = false; |
366 kv_list->list.base.collection.sorted = false; |
| 367 void *node_data = kv_list->list_methods->insert_element( |
367 void *node_data = kv_list->list_methods->insert_element( |
| 368 &kv_list->list.base, kv_list->list.base.collection.size, |
368 &kv_list->list.base, kv_list->list.base.collection.size, |
| 369 kv_list->list.base.collection.store_pointer ? &value : value); |
369 kv_list->list.base.collection.store_pointer ? &value : value); |
| 370 if (node_data == NULL) { // LCOV_EXCL_START |
370 if (node_data == NULL) { // LCOV_EXCL_START |
| 371 // non-destructively remove the key again |
371 // non-destructively remove the key again |
| 372 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data); |
372 void *dummy; |
| 373 return NULL; |
373 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &dummy); |
| |
374 return (CxMapEntry){NULL, NULL}; |
| 374 } // LCOV_EXCL_STOP |
375 } // LCOV_EXCL_STOP |
| 375 |
376 |
| 376 // write the node pointer to the map entry |
377 // write the node pointer to the map entry |
| 377 *map_data = node_data; |
378 *(void**)map_entry.value = node_data; |
| 378 |
379 |
| 379 // copy the key to the node data |
380 // copy the key to the node data |
| 380 CxHashKey *key_ptr = cx_kv_list_loc_key(kv_list, node_data); |
381 CxHashKey *key_ptr = cx_kv_list_loc_key(kv_list, node_data); |
| 381 *key_ptr = key; |
382 *key_ptr = *map_entry.key; |
| 382 |
383 |
| 383 // we must return node_data here and not map_data, |
384 return map_entry; |
| 384 // because the node_data is the actual element of this collection |
|
| 385 return node_data; |
|
| 386 } |
385 } |
| 387 |
386 |
| 388 static void *cx_kvl_iter_current_entry(const void *it) { |
387 static void *cx_kvl_iter_current_entry(const void *it) { |
| 389 const CxMapIterator *iter = it; |
388 const CxMapIterator *iter = it; |
| 390 return (void*)&iter->entry; |
389 return (void*)&iter->entry; |
| 647 if (existing != NULL) { |
646 if (existing != NULL) { |
| 648 // the key is already assigned to another node, we disallow re-assignment |
647 // the key is already assigned to another node, we disallow re-assignment |
| 649 return 1; |
648 return 1; |
| 650 } |
649 } |
| 651 |
650 |
| 652 // add the key to the map; |
651 // add the key to the map |
| 653 if (NULL == kv_list->map_methods->put(&kv_list->map->map_base.base, key, node_data)) { |
652 const CxMapEntry entry = kv_list->map_methods->put( |
| 654 return 1; // LCOV_EXCL_LINE |
653 &kv_list->map->map_base.base, key, node_data); |
| 655 } |
654 if (entry.key == NULL) return 1; // LCOV_EXCL_LINE |
| 656 |
655 |
| 657 // write the key to the list's node |
656 // write the key to the list's node |
| 658 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); |
657 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); |
| 659 *loc_key = key; |
658 *loc_key = *entry.key; |
| 660 |
659 |
| 661 return 0; |
660 return 0; |
| 662 } |
661 } |
| 663 |
662 |
| 664 int cxKvListRemoveKey(CxList *list, size_t index) { |
663 int cxKvListRemoveKey(CxList *list, size_t index) { |
| 696 list->collection.sorted = false; |
695 list->collection.sorted = false; |
| 697 |
696 |
| 698 cx_kv_list *kv_list = (cx_kv_list*)list; |
697 cx_kv_list *kv_list = (cx_kv_list*)list; |
| 699 |
698 |
| 700 // reserve memory in the map |
699 // reserve memory in the map |
| 701 void **map_data = kv_list->map_methods->put(&kv_list->map->map_base.base, key, NULL); |
700 CxMapEntry map_entry = kv_list->map_methods->put(&kv_list->map->map_base.base, key, NULL); |
| 702 if (map_data == NULL) return 1; // LCOV_EXCL_LINE |
701 if (map_entry.key == NULL) return 1; // LCOV_EXCL_LINE |
| 703 |
702 |
| 704 // insert the node |
703 // insert the node |
| 705 void *node_data = kv_list->list_methods->insert_element(&kv_list->list.base, index, |
704 void *node_data = kv_list->list_methods->insert_element(&kv_list->list.base, index, |
| 706 kv_list->list.base.collection.store_pointer ? &value : value); |
705 kv_list->list.base.collection.store_pointer ? &value : value); |
| 707 if (node_data == NULL) { // LCOV_EXCL_START |
706 if (node_data == NULL) { // LCOV_EXCL_START |
| 708 // non-destructively remove the key again |
707 // non-destructively remove the key again |
| 709 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &map_data); |
708 void *dummy; |
| |
709 kv_list->map_methods->remove(&kv_list->map->map_base.base, key, &dummy); |
| 710 return 1; |
710 return 1; |
| 711 } // LCOV_EXCL_STOP |
711 } // LCOV_EXCL_STOP |
| 712 *map_data = node_data; |
712 *(void**)map_entry.value = node_data; |
| 713 |
713 |
| 714 // write the key to the node |
714 // write the key to the node |
| 715 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); |
715 CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); |
| 716 *loc_key = key; |
716 *loc_key = *map_entry.key; |
| 717 |
717 |
| 718 return 0; |
718 return 0; |
| 719 } |
719 } |