diff options
| author | Stefan Monnier | 2022-10-05 12:12:01 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2022-10-05 12:12:01 -0400 |
| commit | aa5a32ca2c07691f3f10b7ec0c423ade11479220 (patch) | |
| tree | 2852c532076b86fb544e07ad0dedf5fe834246c6 /src/itree.c | |
| parent | 4f4327c0b0db7f908ae7153e5ddc802b9808dc2e (diff) | |
| download | emacs-aa5a32ca2c07691f3f10b7ec0c423ade11479220.tar.gz emacs-aa5a32ca2c07691f3f10b7ec0c423ade11479220.zip | |
itree.c: Clarify how the sentinel is used
* src/itree.c (null_is_sane): New function.
(interval_tree_iter_start): Use it to make sure we haven't garbled null.
(itree_init): Fully initialize `itree_null` here...
(interval_tree_clear): ...instead of here.
(interval_tree_propagate_limit): Remove special code that read NULL->parent.
(interval_tree_remove): Do it explicitly before the call in those two
places where it can happen.
Diffstat (limited to 'src/itree.c')
| -rw-r--r-- | src/itree.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/src/itree.c b/src/itree.c index 58456fbc6ee..dcad848c216 100644 --- a/src/itree.c +++ b/src/itree.c | |||
| @@ -114,6 +114,19 @@ static struct interval_generator* interval_generator_create (struct interval_tre | |||
| 114 | /* The sentinel node, the null node. */ | 114 | /* The sentinel node, the null node. */ |
| 115 | struct interval_node itree_null; | 115 | struct interval_node itree_null; |
| 116 | 116 | ||
| 117 | static inline bool | ||
| 118 | null_is_sane (void) | ||
| 119 | { | ||
| 120 | /* The sentinel node has most of its fields read-only, except for `parent`, | ||
| 121 | `left`, `right` which are write only. */ | ||
| 122 | return itree_null.red == false | ||
| 123 | && itree_null.otick == 0 | ||
| 124 | && itree_null.offset == 0 | ||
| 125 | && itree_null.begin == PTRDIFF_MIN | ||
| 126 | && itree_null.end == PTRDIFF_MIN | ||
| 127 | && itree_null.limit == PTRDIFF_MIN; | ||
| 128 | } | ||
| 129 | |||
| 117 | /* +------------------------------------------------------------------------------------+ */ | 130 | /* +------------------------------------------------------------------------------------+ */ |
| 118 | 131 | ||
| 119 | typedef uintptr_t nodeptr_and_flag; | 132 | typedef uintptr_t nodeptr_and_flag; |
| @@ -149,7 +162,13 @@ static struct interval_generator *iter; | |||
| 149 | static void | 162 | static void |
| 150 | itree_init (void) | 163 | itree_init (void) |
| 151 | { | 164 | { |
| 152 | itree_null.parent = itree_null.left = itree_null.right = ITREE_NULL; | 165 | struct interval_node *null = ITREE_NULL; |
| 166 | null->left = null->right = null->parent = null; | ||
| 167 | null->offset = null->otick = 0; | ||
| 168 | null->begin = PTRDIFF_MIN; | ||
| 169 | null->end = PTRDIFF_MIN; | ||
| 170 | null->limit = PTRDIFF_MIN; /* => max(x, null.limit) = x */ | ||
| 171 | null->red = false; | ||
| 153 | iter = interval_generator_create (NULL); | 172 | iter = interval_generator_create (NULL); |
| 154 | } | 173 | } |
| 155 | 174 | ||
| @@ -310,6 +329,7 @@ interval_node_set_region (struct interval_tree *tree, | |||
| 310 | else if (end != node->end) | 329 | else if (end != node->end) |
| 311 | { | 330 | { |
| 312 | node->end = max (node->begin, end); | 331 | node->end = max (node->begin, end); |
| 332 | eassert (node != ITREE_NULL); | ||
| 313 | interval_tree_propagate_limit (node); | 333 | interval_tree_propagate_limit (node); |
| 314 | } | 334 | } |
| 315 | } | 335 | } |
| @@ -334,16 +354,7 @@ interval_tree_create (void) | |||
| 334 | void | 354 | void |
| 335 | interval_tree_clear (struct interval_tree *tree) | 355 | interval_tree_clear (struct interval_tree *tree) |
| 336 | { | 356 | { |
| 337 | /* FIXME: Why is this done? */ | 357 | tree->root = ITREE_NULL; |
| 338 | struct interval_node *null = ITREE_NULL; | ||
| 339 | null->left = null->right = null->parent = null; | ||
| 340 | null->offset = null->otick = 0; | ||
| 341 | null->begin = PTRDIFF_MIN; | ||
| 342 | null->end = PTRDIFF_MIN; | ||
| 343 | null->limit = PTRDIFF_MIN; /* => max(x, null.limit) = x */ | ||
| 344 | null->red = false; | ||
| 345 | |||
| 346 | tree->root = null; | ||
| 347 | tree->otick = 1; | 358 | tree->otick = 1; |
| 348 | tree->size = 0; | 359 | tree->size = 0; |
| 349 | } | 360 | } |
| @@ -461,7 +472,9 @@ interval_tree_remove (struct interval_tree *tree, struct interval_node *node) | |||
| 461 | if (!node->red) | 472 | if (!node->red) |
| 462 | broken = subst; | 473 | broken = subst; |
| 463 | interval_tree_transplant (tree, subst, node); | 474 | interval_tree_transplant (tree, subst, node); |
| 464 | interval_tree_propagate_limit (subst); | 475 | interval_tree_propagate_limit |
| 476 | /* FIXME: null->parent is supposed to be write only! */ | ||
| 477 | (subst == ITREE_NULL ? ITREE_NULL->parent : subst); | ||
| 465 | } | 478 | } |
| 466 | else | 479 | else |
| 467 | { | 480 | { |
| @@ -472,7 +485,12 @@ interval_tree_remove (struct interval_tree *tree, struct interval_node *node) | |||
| 472 | broken = min->right; | 485 | broken = min->right; |
| 473 | eassert (min != ITREE_NULL); | 486 | eassert (min != ITREE_NULL); |
| 474 | if (min->parent == node) | 487 | if (min->parent == node) |
| 475 | min_right->parent = min; /* set parent, if min_right = null */ | 488 | { |
| 489 | if (min_right == ITREE_NULL) | ||
| 490 | ITREE_NULL->parent = min; /* set parent, if min_right = null */ | ||
| 491 | else | ||
| 492 | eassert (min_right->parent == min); | ||
| 493 | } | ||
| 476 | else | 494 | else |
| 477 | { | 495 | { |
| 478 | interval_tree_transplant (tree, min->right, min); | 496 | interval_tree_transplant (tree, min->right, min); |
| @@ -484,7 +502,9 @@ interval_tree_remove (struct interval_tree *tree, struct interval_node *node) | |||
| 484 | min->left = node->left; | 502 | min->left = node->left; |
| 485 | min->left->parent = min; | 503 | min->left->parent = min; |
| 486 | min->red = node->red; | 504 | min->red = node->red; |
| 487 | interval_tree_propagate_limit (min_right); | 505 | interval_tree_propagate_limit |
| 506 | /* FIXME: null->parent is supposed to be write only! */ | ||
| 507 | (min_right == ITREE_NULL ? ITREE_NULL->parent : min_right); | ||
| 488 | interval_tree_propagate_limit (min); | 508 | interval_tree_propagate_limit (min); |
| 489 | } | 509 | } |
| 490 | 510 | ||
| @@ -523,6 +543,7 @@ interval_tree_iter_start (struct interval_tree *tree, | |||
| 523 | enum interval_tree_order order, | 543 | enum interval_tree_order order, |
| 524 | const char* file, int line) | 544 | const char* file, int line) |
| 525 | { | 545 | { |
| 546 | eassert (null_is_sane ()); | ||
| 526 | /* struct interval_generator *iter = tree->iter; */ | 547 | /* struct interval_generator *iter = tree->iter; */ |
| 527 | if (iter->running) | 548 | if (iter->running) |
| 528 | { | 549 | { |
| @@ -625,6 +646,7 @@ interval_tree_insert_gap (struct interval_tree *tree, ptrdiff_t pos, ptrdiff_t l | |||
| 625 | if (node->end > pos || (node->end == pos && node->rear_advance)) | 646 | if (node->end > pos || (node->end == pos && node->rear_advance)) |
| 626 | { | 647 | { |
| 627 | node->end += length; | 648 | node->end += length; |
| 649 | eassert (node != ITREE_NULL); | ||
| 628 | interval_tree_propagate_limit (node); | 650 | interval_tree_propagate_limit (node); |
| 629 | } | 651 | } |
| 630 | } | 652 | } |
| @@ -689,6 +711,7 @@ interval_tree_delete_gap (struct interval_tree *tree, ptrdiff_t pos, ptrdiff_t l | |||
| 689 | if (node->end > pos) | 711 | if (node->end > pos) |
| 690 | { | 712 | { |
| 691 | node->end = max (pos , node->end - length); | 713 | node->end = max (pos , node->end - length); |
| 714 | eassert (node != ITREE_NULL); | ||
| 692 | interval_tree_propagate_limit (node); | 715 | interval_tree_propagate_limit (node); |
| 693 | } | 716 | } |
| 694 | } | 717 | } |
| @@ -876,8 +899,6 @@ static void | |||
| 876 | interval_tree_propagate_limit (struct interval_node *node) | 899 | interval_tree_propagate_limit (struct interval_node *node) |
| 877 | { | 900 | { |
| 878 | if (node == ITREE_NULL) | 901 | if (node == ITREE_NULL) |
| 879 | node = node->parent; | ||
| 880 | if (node == ITREE_NULL) | ||
| 881 | return; | 902 | return; |
| 882 | 903 | ||
| 883 | while (1) { | 904 | while (1) { |