unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Matt Armstrong <matt@rfc20.org>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: emacs-devel@gnu.org
Subject: Re: noverlay branch
Date: Wed, 12 Oct 2022 15:26:58 -0700	[thread overview]
Message-ID: <87ilkollu5.fsf@rfc20.org> (raw)
In-Reply-To: <jwvr0zdkjt1.fsf-monnier+emacs@gnu.org>

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> --- a/src/itree.c
>> +++ b/src/itree.c
>> @@ -307,6 +307,7 @@ check_tree (struct interval_tree *tree,
>>    if (tree->root == ITREE_NULL)
>>      return true;
>>    eassert (tree->root->parent == ITREE_NULL);
>> +  eassert (!check_red_black_invariants || !tree->root->red);
>>
>>    struct interval_node *node = tree->root;
>>    struct check_subtree_result result
>
> Does any part of the code care about that?  I can't see anything that
> would break if this invariant is not satisfied (both in terms of
> correct behavior and in terms of performance).  IOW it seems more like
> an accident than something important would should check.

That is a can of subtle worms.

As a practical matter, `interval_tree_insert_fix` asserts it, and that
was failing for me.  I wanted it to fail earlier.

TLDR: That the root be black isn't an essential proeprty of Red-Black
trees.  We could relax it, but that is uncommon practice and would
slightly complicate `interval_tree_insert_fix`.

Corman et. al. doesn't list it as one of the four "red-black
properties", but read on.

Harper, Sen and Tarjan's Rank Balanced Trees paper
(http://sidsen.azurewebsites.net/papers/rb-trees-talg.pdf) reformulates
Red-Black trees in terms of rank differences of a node and its parent.
In their formulation, there is an equivalence between Red-Black "color"
and the rank difference between a node and its parent.  Since the root
has no parent, they say the root has no color.  So I think you could
prove that the root's color doesn't matter -- it is inexpressible in an
equivalent formulation of the same class of trees.

But then you get to the implementation, where Corman et. al., subtly
placed deep in their description of their "RB-Insert" function (at least
in my old copy), says this:

  > We have made the important assumption that the root of the tree is
  > black -- a property we guarante in line 18 [...]

Why, because, in my copy, they do this:

  if p[x] = left[p[p[x]]]

which is ill defined if p[x] is a red root -- there is no p[p[x]].  They
want a guarantee that p[p[x]] exists.  They've already checked that p[x]
is red, so they just say root can't be red to save a check that p[x] is
not the root.

(Let me chime in here that I *dislike* it when textbook authors do this
kind of thing, especially in books aimed at undergrads.  They
prominently list four essential Red-Black tree properties, and promptly
write code that relies on additional invariants they toss in to make
their pseudo-code look nicer.  I actually remember looking at this
p[p[x]] and struggling to figure out how the four "red-black properties"
made that safe, then finding that little note burried at the end of a
paragraph in their voluminous text, and getting angry.  It is almost as
if they had no appreciation for their poor young readers minds being
completely full just understanding the very basics.  That was nearly
three decades ago!  A formative memory in the folly of being too
clever.)

Our code is the same in `interval_tree_inherit_offset`:

     if (node->parent == node->parent->parent->left)
	{

If node->parent is a red root that'll crash even with sentinel nodes
(after my change to give even them a truly NULL parent).

At long last, I think we could change this in `interval_tree_insert_fix`:

  while (null_safe_is_red (node->parent))
    {

to this:

  while (null_safe_is_red (node->parent) && node->parent != tree->root)
    {

...and then we could allow red roots.

I'm inclined to keep it the way it is, if only for reasons of inertia.
Most future maintainers coming to Red-Black tree code will have the
"Corman et. al." mindset.



  reply	other threads:[~2022-10-12 22:26 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-25 22:38 noverlay branch Stefan Monnier
2022-09-25 22:50 ` Lars Ingebrigtsen
2022-09-25 22:56   ` Stefan Monnier
2022-09-26  2:52 ` Ihor Radchenko
2022-09-26  3:17   ` Stefan Monnier
2022-09-26  6:11   ` Eli Zaretskii
2022-09-26 13:08     ` Ihor Radchenko
2022-09-26 15:59       ` Eli Zaretskii
     [not found]         ` <87v8ovdosz.fsf@localhost>
2022-10-08  6:57           ` Eli Zaretskii
2022-10-09  3:25             ` Matt Armstrong
2022-10-09  4:30               ` Eli Zaretskii
2022-10-09  3:23           ` Matt Armstrong
2022-10-09  3:47           ` Stefan Monnier
2022-10-13 12:09             ` Ihor Radchenko
2022-09-29 18:12       ` Stefan Monnier
2022-09-27  5:12 ` Matt Armstrong
2022-09-27  6:53   ` Eli Zaretskii
2022-09-27 17:31     ` Matt Armstrong
2022-09-27 18:45       ` Stefan Monnier
2022-09-28 23:09   ` Stefan Monnier
2022-09-29 14:54     ` Gerd Möllmann
2022-09-29 21:36       ` Stefan Monnier
2022-09-30  5:20         ` Gerd Möllmann
2022-10-06  4:47         ` Matt Armstrong
2022-10-06  5:43           ` Gerd Möllmann
2022-10-07  4:11             ` Matt Armstrong
2022-10-07  4:34               ` Gerd Möllmann
2022-10-07 13:33                 ` Stefan Monnier
2022-10-07 14:29                   ` Gerd Möllmann
2022-10-07 14:51                     ` Stefan Monnier
2022-10-07 15:12                       ` Gerd Möllmann
2022-10-07 17:12                         ` Stefan Monnier
2022-10-07 14:56                   ` Stefan Monnier
2022-10-07 15:59                   ` Matt Armstrong
2022-10-07 15:34                 ` Matt Armstrong
2022-10-06 12:08           ` Stefan Monnier
2022-09-27  8:39 ` Gerd Möllmann
2022-09-27  9:38   ` Eli Zaretskii
2022-10-06 20:41 ` Matt Armstrong
2022-10-07 16:51 ` Matt Armstrong
2022-10-07 18:28   ` Stefan Monnier
2022-10-08 23:33     ` Matt Armstrong
2022-10-09  3:44       ` Matt Armstrong
2022-10-09  4:12       ` Stefan Monnier
2022-10-09 15:34         ` Stefan Monnier
2022-10-10  2:57           ` Matt Armstrong
2022-10-10  6:24             ` Eli Zaretskii
2022-10-10 16:26               ` Matt Armstrong
2022-10-10 14:44             ` Stefan Monnier
2022-10-11  3:46               ` Matt Armstrong
2022-10-11  4:09                 ` Stefan Monnier
2022-10-11 18:02                   ` Matt Armstrong
2022-10-11 18:59                     ` Stefan Monnier
2022-10-12  5:18                       ` Matt Armstrong
2022-10-12 18:02                         ` Stefan Monnier
2022-10-12 22:26                           ` Matt Armstrong [this message]
2022-10-13  4:03                             ` Stefan Monnier
2022-10-09 23:47       ` Stefan Monnier
2022-10-10  0:05         ` Emanuel Berg
2022-10-10 16:27           ` Matt Armstrong
2022-10-10 16:33         ` Matt Armstrong
2022-10-10 18:32           ` Matt Armstrong
2022-10-11 16:06             ` Stefan Monnier
2022-10-12 17:33               ` Matt Armstrong
2022-10-13  3:59                 ` Stefan Monnier
2022-10-16 21:53                   ` Matt Armstrong
2022-10-23  4:49 ` Matt Armstrong
2022-10-24  9:14   ` Stefan Kangas
2022-10-24 16:21     ` Matt Armstrong
2022-10-24 12:51   ` Eli Zaretskii
2022-10-25 20:57     ` Dmitry Gutov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ilkollu5.fsf@rfc20.org \
    --to=matt@rfc20.org \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).