aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2022-10-09 00:56:24 -0400
committerStefan Monnier2022-10-09 00:56:24 -0400
commit4f3f7aebc957732f4fbe5c799da5367f46607680 (patch)
tree34e0a0a63b6a6d18f8732a5644e94cfc41616057 /src
parentfe14454101cfd9951b76549773645b2ffeed66bd (diff)
downloademacs-4f3f7aebc957732f4fbe5c799da5367f46607680.tar.gz
emacs-4f3f7aebc957732f4fbe5c799da5367f46607680.zip
itree.c: Use `interval_tree_inherit_offset`
The insertion code tried to manipulate the offset in its own way, and apparently there was a bug in it. Replace that with a call to `interval_tree_inherit_offset`, making the whole logic a bit simpler, and fixing a bug along the way (not sure where the bug was, to be honest). * src/itree.c (interval_tree_insert): Use `interval_tree_inherit_offset`. Check the tree before insert_fix. (recurse_check_tree): Don't check RB invariants. (itree_limits_are_stable): Delete function (subsumed by `check_tree`).
Diffstat (limited to 'src')
-rw-r--r--src/itree.c32
1 files changed, 11 insertions, 21 deletions
diff --git a/src/itree.c b/src/itree.c
index 4ad47b2e3fa..b57c3cc656f 100644
--- a/src/itree.c
+++ b/src/itree.c
@@ -220,9 +220,12 @@ recurse_check_tree (struct interval_node *node, uintmax_t tree_otick,
220 eassert (node->left == ITREE_NULL || node->left->parent == node); 220 eassert (node->left == ITREE_NULL || node->left->parent == node);
221 eassert (node->right == ITREE_NULL || node->right->parent == node); 221 eassert (node->right == ITREE_NULL || node->right->parent == node);
222 222
223 /* We don't check the RB invariants here (neither the absence of
224 red+red nor the equal-black-depth), so that we can use this check
225 even while the tree is temporarily breaking some of those invarints. */
223 /* Red nodes cannot have red parents. */ 226 /* Red nodes cannot have red parents. */
224 eassert (node->parent == ITREE_NULL 227 /* eassert (node->parent == ITREE_NULL
225 || !(node->red && node->parent->red)); 228 || !(node->red && node->parent->red)); */
226 229
227 eassert (node->offset == 0 || node->otick < tree_otick); 230 eassert (node->offset == 0 || node->otick < tree_otick);
228 231
@@ -493,15 +496,16 @@ interval_tree_insert (struct interval_tree *tree, struct interval_node *node)
493 496
494 struct interval_node *parent = ITREE_NULL; 497 struct interval_node *parent = ITREE_NULL;
495 struct interval_node *child = tree->root; 498 struct interval_node *child = tree->root;
496 ptrdiff_t offset = 0; 499 uintmax_t otick = tree->otick;
497 500
498 /* Find the insertion point, accumulate node's offset and update 501 /* Find the insertion point, accumulate node's offset and update
499 ancestors limit values. */ 502 ancestors limit values. */
500 while (child != ITREE_NULL) 503 while (child != ITREE_NULL)
501 { 504 {
505 interval_tree_inherit_offset (otick, child);
502 parent = child; 506 parent = child;
503 offset += child->offset; 507 eassert (child->offset == 0);
504 child->limit = max (child->limit, node->end - offset); 508 child->limit = max (child->limit, node->end);
505 /* This suggests that nodes in the right subtree are strictly 509 /* This suggests that nodes in the right subtree are strictly
506 greater. But this is not true due to later rotations. */ 510 greater. But this is not true due to later rotations. */
507 child = node->begin <= child->begin ? child->left : child->right; 511 child = node->begin <= child->begin ? child->left : child->right;
@@ -521,15 +525,13 @@ interval_tree_insert (struct interval_tree *tree, struct interval_node *node)
521 node->right = ITREE_NULL; 525 node->right = ITREE_NULL;
522 node->red = true; 526 node->red = true;
523 node->offset = 0; 527 node->offset = 0;
524 node->begin -= offset;
525 node->end -= offset;
526 node->limit = node->end; 528 node->limit = node->end;
527 node->otick = tree->otick - 1; 529 node->otick = otick;
528 530
529 /* Fix/update the tree */ 531 /* Fix/update the tree */
530 ++tree->size; 532 ++tree->size;
531 interval_tree_insert_fix (tree, node);
532 eassert (check_tree (tree)); 533 eassert (check_tree (tree));
534 interval_tree_insert_fix (tree, node);
533} 535}
534 536
535/* Return true, if NODE is a member of TREE. */ 537/* Return true, if NODE is a member of TREE. */
@@ -567,16 +569,6 @@ itree_limit_is_stable (struct interval_node *node)
567 return (newlimit == node->limit); 569 return (newlimit == node->limit);
568} 570}
569 571
570static inline bool
571itree_limits_are_stable (struct interval_node *node)
572{
573 if (node == ITREE_NULL)
574 return true;
575 return itree_limit_is_stable (node)
576 && itree_limits_are_stable (node->right)
577 && itree_limits_are_stable (node->left);
578}
579
580static struct interval_node* 572static struct interval_node*
581interval_tree_subtree_min (uintmax_t otick, struct interval_node *node) 573interval_tree_subtree_min (uintmax_t otick, struct interval_node *node)
582{ 574{
@@ -692,7 +684,6 @@ interval_tree_remove_fix (struct interval_tree *tree,
692struct interval_node* 684struct interval_node*
693interval_tree_remove (struct interval_tree *tree, struct interval_node *node) 685interval_tree_remove (struct interval_tree *tree, struct interval_node *node)
694{ 686{
695 /* eassert (itree_limits_are_stable (tree->root)); */
696 eassert (interval_tree_contains (tree, node)); 687 eassert (interval_tree_contains (tree, node));
697 eassert (check_tree (tree)); 688 eassert (check_tree (tree));
698 689
@@ -770,7 +761,6 @@ interval_tree_remove (struct interval_tree *tree, struct interval_node *node)
770 --tree->size; 761 --tree->size;
771 762
772 eassert ((tree->size == 0) == (tree->root == ITREE_NULL)); 763 eassert ((tree->size == 0) == (tree->root == ITREE_NULL));
773 /* eassert (itree_limits_are_stable (tree->root)); */
774 eassert (check_tree (tree)); 764 eassert (check_tree (tree));
775 765
776 return node; 766 return node;