src/kv_list.c

changeset 1587
7156d6699410
parent 1546
c8dd35f3ea53
equal deleted inserted replaced
1586:7f1cadc3ebc1 1587:7156d6699410
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 }

mercurial