src/tree.c

branch
feature/tree_add
changeset 867
471c714d5b6f
parent 866
1f636de4a63f
child 868
56a908924510
equal deleted inserted replaced
866:1f636de4a63f 867:471c714d5b6f
443 iter.base.current = cx_tree_visitor_current; 443 iter.base.current = cx_tree_visitor_current;
444 444
445 return iter; 445 return iter;
446 } 446 }
447 447
448 static void cx_tree_add_link_duplicate(
449 void **root, void *original, void *duplicate,
450 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
451 ptrdiff_t loc_prev, ptrdiff_t loc_next
452 ) {
453 cx_tree_zero_pointers(duplicate, cx_tree_ptr_locations);
454 void *shared_parent = tree_parent(original);
455 if (shared_parent == NULL) {
456 cx_tree_link(duplicate, original, cx_tree_ptr_locations);
457 *root = duplicate;
458 } else {
459 cx_tree_link(shared_parent, duplicate, cx_tree_ptr_locations);
460 }
461 }
462
448 void *cx_tree_add( 463 void *cx_tree_add(
449 void const *src, 464 void const *src,
450 cx_tree_search_func sfunc, 465 cx_tree_search_func sfunc,
451 cx_tree_node_create_func cfunc, 466 cx_tree_node_create_func cfunc,
452 void *cdata, 467 void *cdata,
481 node = cfunc(src, NULL, cdata); 496 node = cfunc(src, NULL, cdata);
482 if (node == NULL) return NULL; 497 if (node == NULL) return NULL;
483 cx_tree_zero_pointers(node, cx_tree_ptr_locations); 498 cx_tree_zero_pointers(node, cx_tree_ptr_locations);
484 cx_tree_link(node, *root, cx_tree_ptr_locations); 499 cx_tree_link(node, *root, cx_tree_ptr_locations);
485 *root = node; 500 *root = node;
486 return node;
487 } else if (result == 0) { 501 } else if (result == 0) {
488 // data already found in the tree, let cfunc decide 502 // data already found in the tree, let cfunc decide
489 node = cfunc(src, match, cdata); 503 node = cfunc(src, match, cdata);
490 if (node == NULL) return NULL; 504 if (node == NULL) return NULL;
491 if (node != match) { 505 if (node != match) {
492 cx_tree_zero_pointers(node, cx_tree_ptr_locations); 506 cx_tree_add_link_duplicate(
493 cx_tree_link(match, node, cx_tree_ptr_locations); 507 root, match, node, cx_tree_ptr_locations);
494 } 508 }
495 } else { 509 } else {
496 // closest match found, add new node as child 510 // closest match found, add new node as child
497 node = cfunc(src, NULL, cdata); 511 node = cfunc(src, NULL, cdata);
498 if (node == NULL) return NULL; 512 if (node == NULL) return NULL;
578 } else if (result == 0) { 592 } else if (result == 0) {
579 // data already found in the tree, let cfunc decide 593 // data already found in the tree, let cfunc decide
580 node = cfunc(elem, match, cdata); 594 node = cfunc(elem, match, cdata);
581 if (node == NULL) return processed; 595 if (node == NULL) return processed;
582 if (node != match) { 596 if (node != match) {
583 cx_tree_zero_pointers(node, cx_tree_ptr_locations); 597 cx_tree_add_link_duplicate(
584 cx_tree_link(match, node, cx_tree_ptr_locations); 598 root, match, node, cx_tree_ptr_locations);
585 } 599 }
586 current_node = node; 600 current_node = node;
587 } else { 601 } else {
588 // closest match found, add new node as child 602 // closest match found, add new node as child
589 node = cfunc(elem, NULL, cdata); 603 node = cfunc(elem, NULL, cdata);

mercurial