/* The sentinel node, the null node. */
struct interval_node itree_null;
+static inline bool
+null_is_sane (void)
+{
+ /* The sentinel node has most of its fields read-only, except for `parent`,
+ `left`, `right` which are write only. */
+ return itree_null.red == false
+ && itree_null.otick == 0
+ && itree_null.offset == 0
+ && itree_null.begin == PTRDIFF_MIN
+ && itree_null.end == PTRDIFF_MIN
+ && itree_null.limit == PTRDIFF_MIN;
+}
+
/* +------------------------------------------------------------------------------------+ */
typedef uintptr_t nodeptr_and_flag;
static void
itree_init (void)
{
- itree_null.parent = itree_null.left = itree_null.right = ITREE_NULL;
+ struct interval_node *null = ITREE_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->red = false;
iter = interval_generator_create (NULL);
}
else if (end != node->end)
{
node->end = max (node->begin, end);
+ eassert (node != ITREE_NULL);
interval_tree_propagate_limit (node);
}
}
void
interval_tree_clear (struct interval_tree *tree)
{
- /* FIXME: Why is this done? */
- struct interval_node *null = ITREE_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->red = false;
-
- tree->root = null;
+ tree->root = ITREE_NULL;
tree->otick = 1;
tree->size = 0;
}
if (!node->red)
broken = subst;
interval_tree_transplant (tree, subst, node);
- interval_tree_propagate_limit (subst);
+ interval_tree_propagate_limit
+ /* FIXME: null->parent is supposed to be write only! */
+ (subst == ITREE_NULL ? ITREE_NULL->parent : subst);
}
else
{
broken = min->right;
eassert (min != ITREE_NULL);
if (min->parent == node)
- min_right->parent = min; /* set parent, if min_right = null */
+ {
+ if (min_right == ITREE_NULL)
+ ITREE_NULL->parent = min; /* set parent, if min_right = null */
+ else
+ eassert (min_right->parent == min);
+ }
else
{
interval_tree_transplant (tree, min->right, min);
min->left = node->left;
min->left->parent = min;
min->red = node->red;
- interval_tree_propagate_limit (min_right);
+ interval_tree_propagate_limit
+ /* FIXME: null->parent is supposed to be write only! */
+ (min_right == ITREE_NULL ? ITREE_NULL->parent : min_right);
interval_tree_propagate_limit (min);
}
enum interval_tree_order order,
const char* file, int line)
{
+ eassert (null_is_sane ());
/* struct interval_generator *iter = tree->iter; */
if (iter->running)
{
if (node->end > pos || (node->end == pos && node->rear_advance))
{
node->end += length;
+ eassert (node != ITREE_NULL);
interval_tree_propagate_limit (node);
}
}
if (node->end > pos)
{
node->end = max (pos , node->end - length);
+ eassert (node != ITREE_NULL);
interval_tree_propagate_limit (node);
}
}
static void
interval_tree_propagate_limit (struct interval_node *node)
{
- if (node == ITREE_NULL)
- node = node->parent;
if (node == ITREE_NULL)
return;