aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2022-10-05 23:48:47 -0400
committerStefan Monnier2022-10-05 23:48:47 -0400
commita1f1fdd291a708684262c2494eae5bba32857cd7 (patch)
treeb22588a17d1f2b875e1e1ed4f71f96fbff8d399f /src
parent1f31534f510fdd9ed3166f761d736c0dda322db5 (diff)
downloademacs-a1f1fdd291a708684262c2494eae5bba32857cd7.tar.gz
emacs-a1f1fdd291a708684262c2494eae5bba32857cd7.zip
* src/itree.c (interval_tree_remove_fix): Move before first use
Diffstat (limited to 'src')
-rw-r--r--src/itree.c173
1 files changed, 86 insertions, 87 deletions
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 *);
106static void interval_tree_rotate_left (struct interval_tree *, struct interval_node *); 106static void interval_tree_rotate_left (struct interval_tree *, struct interval_node *);
107static void interval_tree_rotate_right (struct interval_tree *, struct interval_node *); 107static void interval_tree_rotate_right (struct interval_tree *, struct interval_node *);
108static void interval_tree_insert_fix (struct interval_tree *, struct interval_node *); 108static void interval_tree_insert_fix (struct interval_tree *, struct interval_node *);
109static void interval_tree_remove_fix (struct interval_tree *, struct interval_node *);
110static void interval_tree_transplant (struct interval_tree *, struct interval_node *, struct interval_node *); 109static void interval_tree_transplant (struct interval_tree *, struct interval_node *, struct interval_node *);
111static struct interval_generator* interval_generator_create (struct interval_tree *); 110static struct interval_generator* interval_generator_create (struct interval_tree *);
112 111
@@ -495,6 +494,92 @@ interval_tree_subtree_min (uintmax_t otick, struct interval_node *node)
495 return node; 494 return node;
496} 495}
497 496
497/* Repair the tree after a deletion.
498 The black-depth of NODE is one less than that of its sibling,
499 so re-balance the parents to re-establish the RB invariants. */
500
501static void
502interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node)
503{
504 /* BEWARE: null->parent is usually write-only, *BUT*
505 NODE here can be the NULL node, in which case its `parent` field
506 has to be properly set to point to the intended "parent" node. */
507 while (node != tree->root && !node->red)
508 {
509 if (node == node->parent->left)
510 {
511 struct interval_node *other = node->parent->right;
512
513 if (other->red) /* case 1.a */
514 {
515 other->red = false;
516 node->parent->red = true;
517 interval_tree_rotate_left (tree, node->parent);
518 other = node->parent->right;
519 }
520
521 if (!other->left->red /* 2.a */
522 && !other->right->red)
523 {
524 other->red = true;
525 node = node->parent;
526 }
527 else
528 {
529 if (!other->right->red) /* 3.a */
530 {
531 other->left->red = false;
532 other->red = true;
533 interval_tree_rotate_right (tree, other);
534 other = node->parent->right;
535 }
536 other->red = node->parent->red; /* 4.a */
537 node->parent->red = false;
538 other->right->red = false;
539 interval_tree_rotate_left (tree, node->parent);
540 node = tree->root;
541 }
542 }
543 else
544 {
545 struct interval_node *other = node->parent->left;
546
547 if (other->red) /* 1.b */
548 {
549 other->red = false;
550 node->parent->red = true;
551 interval_tree_rotate_right (tree, node->parent);
552 other = node->parent->left;
553 }
554
555 if (!other->right->red /* 2.b */
556 && !other->left->red)
557 {
558 other->red = true;
559 node = node->parent;
560 }
561 else
562 {
563 if (!other->left->red) /* 3.b */
564 {
565 other->right->red = false;
566 other->red = true;
567 interval_tree_rotate_left (tree, other);
568 other = node->parent->left;
569 }
570
571 other->red = node->parent->red; /* 4.b */
572 node->parent->red = false;
573 other->left->red = false;
574 interval_tree_rotate_right (tree, node->parent);
575 node = tree->root;
576 }
577 }
578 }
579
580 node->red = false;
581}
582
498/* Remove NODE from TREE and return it. NODE must exist in TREE. */ 583/* Remove NODE from TREE and return it. NODE must exist in TREE. */
499 584
500struct interval_node* 585struct interval_node*
@@ -1130,92 +1215,6 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node
1130 tree->root->red = false; 1215 tree->root->red = false;
1131} 1216}
1132 1217
1133/* Repair the tree after a deletion.
1134 The black-depth of NODE is one less than that of its sibling,
1135 so re-balance the parents to re-establish the RB invariants. */
1136
1137static void
1138interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node)
1139{
1140 /* BEWARE: null->parent is usually write-only, *BUT*
1141 NODE here can be the NULL node, in which case its `parent` field
1142 has to be properly set to point to the intended "parent" node. */
1143 while (node != tree->root && !node->red)
1144 {
1145 if (node == node->parent->left)
1146 {
1147 struct interval_node *other = node->parent->right;
1148
1149 if (other->red) /* case 1.a */
1150 {
1151 other->red = false;
1152 node->parent->red = true;
1153 interval_tree_rotate_left (tree, node->parent);
1154 other = node->parent->right;
1155 }
1156
1157 if (!other->left->red /* 2.a */
1158 && !other->right->red)
1159 {
1160 other->red = true;
1161 node = node->parent;
1162 }
1163 else
1164 {
1165 if (!other->right->red) /* 3.a */
1166 {
1167 other->left->red = false;
1168 other->red = true;
1169 interval_tree_rotate_right (tree, other);
1170 other = node->parent->right;
1171 }
1172 other->red = node->parent->red; /* 4.a */
1173 node->parent->red = false;
1174 other->right->red = false;
1175 interval_tree_rotate_left (tree, node->parent);
1176 node = tree->root;
1177 }
1178 }
1179 else
1180 {
1181 struct interval_node *other = node->parent->left;
1182
1183 if (other->red) /* 1.b */
1184 {
1185 other->red = false;
1186 node->parent->red = true;
1187 interval_tree_rotate_right (tree, node->parent);
1188 other = node->parent->left;
1189 }
1190
1191 if (!other->right->red /* 2.b */
1192 && !other->left->red)
1193 {
1194 other->red = true;
1195 node = node->parent;
1196 }
1197 else
1198 {
1199 if (!other->left->red) /* 3.b */
1200 {
1201 other->right->red = false;
1202 other->red = true;
1203 interval_tree_rotate_left (tree, other);
1204 other = node->parent->left;
1205 }
1206
1207 other->red = node->parent->red; /* 4.b */
1208 node->parent->red = false;
1209 other->left->red = false;
1210 interval_tree_rotate_right (tree, node->parent);
1211 node = tree->root;
1212 }
1213 }
1214 }
1215
1216 node->red = false;
1217}
1218
1219/* Return accumulated offsets of NODE's parents. */ 1218/* Return accumulated offsets of NODE's parents. */
1220static ptrdiff_t 1219static ptrdiff_t
1221itree_total_offset (struct interval_node *node) 1220itree_total_offset (struct interval_node *node)