/* This file implements an efficient interval data-structure.
-Copyright (C) 2017 Andreas Politz (politza@hochschule-trier.de)
+Copyright (C) 2017-2022 Free Software Foundation, Inc.
-This file is not part of GNU Emacs.
+This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
void
interval_tree_clear (struct interval_tree *tree)
{
- struct interval_node *nil = &tree->nil;
- nil->left = nil->right = nil->parent = nil;
- nil->offset = nil->otick = 0;
- nil->begin = PTRDIFF_MIN;
- nil->end = PTRDIFF_MIN;
- nil->limit = PTRDIFF_MIN; /* => max(x, nil.limit) = x */
- nil->color = ITREE_BLACK;
- tree->root = nil;
+ struct interval_node *null = &tree->null;
+ null->left = null->right = null->parent = null;
+ null->offset = null->otick = 0;
+ null->begin = PTRDIFF_MIN;
+ null->end = PTRDIFF_MIN;
+ null->limit = PTRDIFF_MIN; /* => max(x, null.limit) = x */
+ null->color = ITREE_BLACK;
+ tree->root = null;
tree->otick = 1;
tree->size = 0;
tree->iter_running = 0;
void
interval_tree_insert (struct interval_tree *tree, struct interval_node *node)
{
- eassert (node && node->begin <= node->end && node != &tree->nil);
+ eassert (node && node->begin <= node->end && node != &tree->null);
- struct interval_node *parent = &tree->nil;
- struct interval_node *child = tree->root;
+ struct interval_node *parent = &tree->null;
+ struct interval_node *child = &tree->null;
ptrdiff_t offset = 0;
/* Find the insertion point, accumulate node's offset and update
ancestors limit values. */
- while (child != &tree->nil)
+ while (child != &tree->null)
{
parent = child;
offset += child->offset;
}
/* Insert the node */
- if (parent == &tree->nil)
+ if (parent == &tree->null)
tree->root = node;
else if (node->begin <= parent->begin)
parent->left = node;
/* Init the node */
node->parent = parent;
- node->left = &tree->nil;
- node->right = &tree->nil;
+ node->left = &tree->null;
+ node->right = &tree->null;
node->color = ITREE_RED;
node->offset = 0;
node->begin -= offset;
struct interval_node *broken = NULL;
interval_tree_inherit_offset (tree, node);
- if (node->left == &tree->nil || node->right == &tree->nil)
+ if (node->left == &tree->null || node->right == &tree->null)
{
struct interval_node *subst =
- (node->right == &tree->nil) ? node->left : node->right;
+ (node->right == &tree->null) ? node->left : node->right;
if (node->color == ITREE_BLACK)
broken = subst;
interval_tree_transplant (tree, subst, node);
if (min->color == ITREE_BLACK)
broken = min->right;
if (min->parent == node)
- min_right->parent = min; /* set parent, if min_right = nil */
+ min_right->parent = min; /* set parent, if min_right = null */
else
{
interval_tree_transplant (tree, min->right, min);
node->right = node->left = node->parent = NULL;
--tree->size;
- eassert (tree->size == 0 || (tree->size > 0 && tree->root != &tree->nil));
+ eassert (tree->size == 0 || (tree->size > 0 && tree->root != &tree->null));
return node;
}
interval_tree_validate (struct interval_tree *tree, struct interval_node *node)
{
- if (tree->otick == node->otick || node == &tree->nil)
+ if (tree->otick == node->otick || node == &tree->null)
return node;
if (node != tree->root)
interval_tree_validate (tree, node->parent);
{
/* Process in pre-order. */
interval_tree_inherit_offset (tree, node);
- if (node->right != &tree->nil)
+ if (node->right != &tree->null)
{
if (node->begin > pos)
{
else
interval_stack_push (stack, node->right);
}
- if (node->left != &tree->nil
+ if (node->left != &tree->null
&& pos <= node->left->limit + node->left->offset)
interval_stack_push (stack, node->left);
while ((node = interval_stack_pop (stack)))
{
interval_tree_inherit_offset (tree, node);
- if (node->right != &tree->nil)
+ if (node->right != &tree->null)
{
if (node->begin > pos + length)
{
else
interval_stack_push (stack, node->right);
}
- if (node->left != &tree->nil
+ if (node->left != &tree->null
&& pos <= node->left->limit + node->left->offset)
interval_stack_push (stack, node->left);
{
if (! g) return NULL;
- struct interval_node * const nil = &g->tree->nil;
+ struct interval_node * const null = &g->tree->null;
struct interval_node *node;
do {
switch (g->order)
{
case ITREE_ASCENDING:
- if (right != nil && node->begin <= g->end)
+ if (right != null && node->begin <= g->end)
interval_stack_push_flagged (g->stack, right, false);
if (interval_node_intersects (node, g->begin, g->end))
interval_stack_push_flagged (g->stack, node, true);
/* Node's children may still be off-set and we need to add it. */
- if (left != nil && g->begin <= left->limit + left->offset)
+ if (left != null && g->begin <= left->limit + left->offset)
interval_stack_push_flagged (g->stack, left, false);
break;
case ITREE_DESCENDING:
- if (left != nil && g->begin <= left->limit + left->offset)
+ if (left != null && g->begin <= left->limit + left->offset)
interval_stack_push_flagged (g->stack, left, false);
if (interval_node_intersects (node, g->begin, g->end))
interval_stack_push_flagged (g->stack, node, true);
- if (right != nil && node->begin <= g->end)
+ if (right != null && node->begin <= g->end)
interval_stack_push_flagged (g->stack, right, false);
break;
case ITREE_PRE_ORDER:
- if (right != nil && node->begin <= g->end)
+ if (right != null && node->begin <= g->end)
interval_stack_push_flagged (g->stack, right, false);
- if (left != nil && g->begin <= left->limit + left->offset)
+ if (left != null && g->begin <= left->limit + left->offset)
interval_stack_push_flagged (g->stack, left, false);
if (interval_node_intersects (node, g->begin, g->end))
interval_stack_push_flagged (g->stack, node, true);
interval_tree_update_limit (const struct interval_tree *tree,
struct interval_node *node)
{
- if (node == &tree->nil)
+ if (node == &tree->null)
return;
node->limit = max (node->end, max (node->left->limit + node->left->offset,
node->begin += node->offset;
node->end += node->offset;
node->limit += node->offset;
- if (node->left != &tree->nil)
+ if (node->left != &tree->null)
node->left->offset += node->offset;
- if (node->right != &tree->nil)
+ if (node->right != &tree->null)
node->right->offset += node->offset;
node->offset = 0;
if (node == tree->root || node->parent->otick == tree->otick)
/* Update limit of NODE and its ancestors. Stop when it becomes
stable, i.e. new_limit = old_limit.
- NODE may also be the nil node, in which case its parent is
+ NODE may also be the null node, in which case its parent is
used. (This feature is due to the RB algorithm.)
*/
interval_tree_propagate_limit (const struct interval_tree *tree,
struct interval_node *node)
{
- if (node == &tree->nil)
+ if (node == &tree->null)
node = node->parent;
- if (node == &tree->nil)
+ if (node == &tree->null)
return;
while (1) {
static void
interval_tree_rotate_left (struct interval_tree *tree, struct interval_node *node)
{
- eassert (node->right != &tree->nil);
+ eassert (node->right != &tree->null);
struct interval_node *right = node->right;
/* Turn right's left subtree into node's right subtree. */
node->right = right->left;
- if (right->left != &tree->nil)
+ if (right->left != &tree->null)
right->left->parent = node;
/* right's parent was node's parent. */
- if (right != &tree->nil)
+ if (right != &tree->null)
right->parent = node->parent;
/* Get the parent to point to right instead of node. */
/* Put node on right's left. */
right->left = node;
- if (node != &tree->nil)
+ if (node != &tree->null)
node->parent = right;
/* Order matters here. */
static void
interval_tree_rotate_right (struct interval_tree *tree, struct interval_node *node)
{
- eassert (tree && node && node->left != &tree->nil);
+ eassert (tree && node && node->left != &tree->null);
struct interval_node *left = node->left;
interval_tree_inherit_offset (tree, left);
node->left = left->right;
- if (left->right != &tree->nil)
+ if (left->right != &tree->null)
left->right->parent = node;
- if (left != &tree->nil)
+ if (left != &tree->null)
left->parent = node->parent;
if (node != tree->root)
{
tree->root = left;
left->right = node;
- if (node != &tree->nil)
+ if (node != &tree->null)
node->parent = left;
interval_tree_update_limit (tree, left);
interval_tree_transplant (struct interval_tree *tree, struct interval_node *source,
struct interval_node *dest)
{
- eassert (tree && source && dest && dest != &tree->nil);
+ eassert (tree && source && dest && dest != &tree->null);
if (dest == tree->root)
tree->root = source;
static struct interval_node*
interval_tree_subtree_min (const struct interval_tree *tree, struct interval_node *node)
{
- if (node == &tree->nil)
+ if (node == &tree->null)
return node;
- while (node->left != &tree->nil)
+ while (node->left != &tree->null)
node = node->left;
return node;
}