From: Stefan Monnier Date: Thu, 6 Oct 2022 03:48:47 +0000 (-0400) Subject: * src/itree.c (interval_tree_remove_fix): Move before first use X-Git-Tag: emacs-29.0.90~1616^2~406^2~36 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a1f1fdd291a708684262c2494eae5bba32857cd7;p=emacs.git * src/itree.c (interval_tree_remove_fix): Move before first use --- diff --git a/src/itree.c b/src/itree.c index 545eb55b0d3..a0c3d6ab5e0 100644 --- a/src/itree.c +++ b/src/itree.c @@ -106,7 +106,6 @@ static void interval_tree_propagate_limit (struct interval_node *); static void interval_tree_rotate_left (struct interval_tree *, struct interval_node *); static void interval_tree_rotate_right (struct interval_tree *, struct interval_node *); static void interval_tree_insert_fix (struct interval_tree *, struct interval_node *); -static void interval_tree_remove_fix (struct interval_tree *, struct interval_node *); static void interval_tree_transplant (struct interval_tree *, struct interval_node *, struct interval_node *); static struct interval_generator* interval_generator_create (struct interval_tree *); @@ -495,6 +494,92 @@ interval_tree_subtree_min (uintmax_t otick, struct interval_node *node) return node; } +/* Repair the tree after a deletion. + The black-depth of NODE is one less than that of its sibling, + so re-balance the parents to re-establish the RB invariants. */ + +static void +interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node) +{ + /* BEWARE: null->parent is usually write-only, *BUT* + NODE here can be the NULL node, in which case its `parent` field + has to be properly set to point to the intended "parent" node. */ + while (node != tree->root && !node->red) + { + if (node == node->parent->left) + { + struct interval_node *other = node->parent->right; + + if (other->red) /* case 1.a */ + { + other->red = false; + node->parent->red = true; + interval_tree_rotate_left (tree, node->parent); + other = node->parent->right; + } + + if (!other->left->red /* 2.a */ + && !other->right->red) + { + other->red = true; + node = node->parent; + } + else + { + if (!other->right->red) /* 3.a */ + { + other->left->red = false; + other->red = true; + interval_tree_rotate_right (tree, other); + other = node->parent->right; + } + other->red = node->parent->red; /* 4.a */ + node->parent->red = false; + other->right->red = false; + interval_tree_rotate_left (tree, node->parent); + node = tree->root; + } + } + else + { + struct interval_node *other = node->parent->left; + + if (other->red) /* 1.b */ + { + other->red = false; + node->parent->red = true; + interval_tree_rotate_right (tree, node->parent); + other = node->parent->left; + } + + if (!other->right->red /* 2.b */ + && !other->left->red) + { + other->red = true; + node = node->parent; + } + else + { + if (!other->left->red) /* 3.b */ + { + other->right->red = false; + other->red = true; + interval_tree_rotate_left (tree, other); + other = node->parent->left; + } + + other->red = node->parent->red; /* 4.b */ + node->parent->red = false; + other->left->red = false; + interval_tree_rotate_right (tree, node->parent); + node = tree->root; + } + } + } + + node->red = false; +} + /* Remove NODE from TREE and return it. NODE must exist in TREE. */ struct interval_node* @@ -1130,92 +1215,6 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node tree->root->red = false; } -/* Repair the tree after a deletion. - The black-depth of NODE is one less than that of its sibling, - so re-balance the parents to re-establish the RB invariants. */ - -static void -interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node) -{ - /* BEWARE: null->parent is usually write-only, *BUT* - NODE here can be the NULL node, in which case its `parent` field - has to be properly set to point to the intended "parent" node. */ - while (node != tree->root && !node->red) - { - if (node == node->parent->left) - { - struct interval_node *other = node->parent->right; - - if (other->red) /* case 1.a */ - { - other->red = false; - node->parent->red = true; - interval_tree_rotate_left (tree, node->parent); - other = node->parent->right; - } - - if (!other->left->red /* 2.a */ - && !other->right->red) - { - other->red = true; - node = node->parent; - } - else - { - if (!other->right->red) /* 3.a */ - { - other->left->red = false; - other->red = true; - interval_tree_rotate_right (tree, other); - other = node->parent->right; - } - other->red = node->parent->red; /* 4.a */ - node->parent->red = false; - other->right->red = false; - interval_tree_rotate_left (tree, node->parent); - node = tree->root; - } - } - else - { - struct interval_node *other = node->parent->left; - - if (other->red) /* 1.b */ - { - other->red = false; - node->parent->red = true; - interval_tree_rotate_right (tree, node->parent); - other = node->parent->left; - } - - if (!other->right->red /* 2.b */ - && !other->left->red) - { - other->red = true; - node = node->parent; - } - else - { - if (!other->left->red) /* 3.b */ - { - other->right->red = false; - other->red = true; - interval_tree_rotate_left (tree, other); - other = node->parent->left; - } - - other->red = node->parent->red; /* 4.b */ - node->parent->red = false; - other->left->red = false; - interval_tree_rotate_right (tree, node->parent); - node = tree->root; - } - } - } - - node->red = false; -} - /* Return accumulated offsets of NODE's parents. */ static ptrdiff_t itree_total_offset (struct interval_node *node)