diff options
| author | Stefan Monnier | 2022-10-05 23:48:47 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2022-10-05 23:48:47 -0400 |
| commit | a1f1fdd291a708684262c2494eae5bba32857cd7 (patch) | |
| tree | b22588a17d1f2b875e1e1ed4f71f96fbff8d399f /src | |
| parent | 1f31534f510fdd9ed3166f761d736c0dda322db5 (diff) | |
| download | emacs-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.c | 173 |
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 *); | |||
| 106 | static void interval_tree_rotate_left (struct interval_tree *, struct interval_node *); | 106 | static void interval_tree_rotate_left (struct interval_tree *, struct interval_node *); |
| 107 | static void interval_tree_rotate_right (struct interval_tree *, struct interval_node *); | 107 | static void interval_tree_rotate_right (struct interval_tree *, struct interval_node *); |
| 108 | static void interval_tree_insert_fix (struct interval_tree *, struct interval_node *); | 108 | static void interval_tree_insert_fix (struct interval_tree *, struct interval_node *); |
| 109 | static void interval_tree_remove_fix (struct interval_tree *, struct interval_node *); | ||
| 110 | static void interval_tree_transplant (struct interval_tree *, struct interval_node *, struct interval_node *); | 109 | static void interval_tree_transplant (struct interval_tree *, struct interval_node *, struct interval_node *); |
| 111 | static struct interval_generator* interval_generator_create (struct interval_tree *); | 110 | static 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 | |||
| 501 | static void | ||
| 502 | interval_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 | ||
| 500 | struct interval_node* | 585 | struct 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 | |||
| 1137 | static void | ||
| 1138 | interval_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. */ |
| 1220 | static ptrdiff_t | 1219 | static ptrdiff_t |
| 1221 | itree_total_offset (struct interval_node *node) | 1220 | itree_total_offset (struct interval_node *node) |