=pod

=head1 NAME

OSSL_RBT_PROTOTYPE, OSSL_RBT_GENERATE, OSSL_RBT_ENTRY, OSSL_RBT_HEAD,
OSSL_RBT_INITIALIZER, OSSL_RBT_ROOT, OSSL_RBT_EMPTY, OSSL_RBT_NEXT,
OSSL_RBT_PREV, OSSL_RBT_MIN, OSSL_RBT_MAX, OSSL_RBT_FIND, OSSL_RBT_NFIND,
OSSL_RBT_LEFT, OSSL_RBT_RIGHT, OSSL_RBT_PARENT, OSSL_RBT_SET_LEFT,
OSSL_RBT_SET_RIGHT, OSSL_RBT_SET_PARENT, OSSL_RBT_FOREACH,
OSSL_RBT_FOREACH_SAFE, OSSL_RBT_FOREACH_REVERSE, OSSL_RBT_FOREACH_REVERSE_SAFE,
OSSL_RBT_INIT, OSSL_RBT_INSERT, OSSL_RBT_REMOVE,
ossl_rbtree - implementation of red-black tree

=head1 SYNOPSIS

 #include "internal/ossl_rbtree.h"

 /* int (*CMP)(const NODE_TYPE *, const NODE_TYPE *); */

 OSSL_RBT_PROTOTYPE(NAME, NODE_TYPE, FIELD, CMP)

 OSSL_RBT_GENERATE(NAME, NODE_TYPE, FIELD, CMP);

 OSSL_RBT_ENTRY(NODE_TYPE)

 OSSL_RBT_HEAD(HEADNAME, NODE_TYPE)

 OSSL_RBT_INITIALIZER(OSSL_RBT_HEAD *head);

 struct NODE_TYPE * OSSL_RBT_ROOT(NAME, OSSL_RBT_HEAD *head);

 int OSSL_RBT_EMPTY(NAME, OSSL_RBT_HEAD *head);

 struct NODE_TYPE * OSSL_RBT_NEXT(NAME, struct NODE_TYPE *elm);

 struct NODE_TYPE * OSSL_RBT_PREV(NAME, struct NODE_TYPE *elm);

 struct NODE_TYPE * OSSL_RBT_MIN(NAME, OSSL_RBT_HEAD *head);

 struct NODE_TYPE * OSSL_RBT_MAX(NAME, OSSL_RBT_HEAD *head);

 struct NODE_TYPE * OSSL_RBT_FIND(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm);

 struct NODE_TYPE * OSSL_RBT_NFIND(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm);

 struct NODE_TYPE * OSSL_RBT_LEFT(NAME, struct NODE_TYPE *elm);

 struct NODE_TYPE * OSSL_RBT_RIGHT(NAME, struct NODE_TYPE *elm);

 struct NODE_TYPE * OSSL_RBT_PARENT(NAME, struct NODE_TYPE *elm);

 void OSSL_RBT_SET_LEFT(NAME, struct NODE_TYPE *elm, struct NODE_TYPE *left);

 void OSSL_RBT_SET_RIGHT(NAME, struct NODE_TYPE *elm, struct NODE_TYPE *right);

 void OSSL_RBT_SET_PARENT(NAME, struct NODE_TYPE *elm, struct NODE_TYPE *parent);

 OSSL_RBT_FOREACH(VARNAME, NAME, OSSL_RBT_HEAD *head);

 OSSL_RBT_FOREACH_SAFE(VARNAME, NAME, OSSL_RBT_HEAD *head, TEMP_VARNAME);

 OSSL_RBT_FOREACH_REVERSE(VARNAME, NAME, OSSL_RBT_HEAD *head);

 OSSL_RBT_FOREACH_REVERSE_SAFE(VARNAME, NAME, OSSL_RBT_HEAD *head, TEMP_VARNAME);

 void OSSL_RBT_INIT(NAME, OSSL_RBT_HEAD *head);

 struct NODE_TYPE * OSSL_RBT_INSERT(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm);

 struct NODE_TYPE * OSSL_RBT_REMOVE(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm);

=head1 DESCRIPTION

These macros define data structures for a red-black tree.
Every operation on a red-black tree is bounded as O(lg n).  The maximum
height of a red-black tree is 2lg (n+1).

In the macro definitions, B<NODE_TYPE> is the name tag of a user defined
structure that must contain a field named B<FIELD>, of type B<OSSL_RBT_ENTRY>.
The argument B<HEADNAME> is the name tag of a user defined
structure that must be declared using the macro OSSL_RBT_HEAD().
The argument B<NAME> has to be a unique name prefix for every
tree that is defined.

The function prototypes are declared with B<OSSL_RBT_PROTOTYPE>,
B<OSSL_RBT_GENERATE>.  See the examples below for further
explanation of how these macros are used.

A red-black tree is a binary search tree with the node color as an extra
attribute.  It fulfills a set of conditions:

=over 4

=item 1.
every search path from the root to a leaf consists of the same
number of black nodes,

=item 2.
each red node (except for the root) has a black parent,

=item 3.
each leaf node is black.

=back

A red-black tree is headed by a structure defined by the OSSL_RBT_HEAD macro.
An OSSL_RBT_HEAD structure is declared as follows:

 OSSL_RBT_HEAD(HEADNAME, NODE_TYPE) head;

where B<HEADNAME> is the name of the structure to be defined, and B<struct
NODE_TYPE> is the type of the elements to be inserted into the tree.

The OSSL_RBT_ENTRY macro declares a structure that allows elements to be
connected in the tree.

In order to use the functions that manipulate the tree structure, their
prototypes need to be declared with the OSSL_RBT_PROTOTYPE() macro,
where B<NAME> is a unique identifier for this
particular tree.  The B<NODE_TYPE> argument is the type of the structure that is
being managed by the tree.  The B<FIELD> argument is the name of the element
defined by OSSL_RBT_ENTRY().

The function bodies are generated with the OSSL_RBT_GENERATE() macro.
These macros take the same arguments as the
OSSL_RBT_PROTOTYPE() macro, but should be used only once.

Finally, the B<CMP> argument is the name of a function used to compare
trees' nodes with each other.  The function takes two arguments of type
B<const struct NODE_TYPE *>.  If the first argument is smaller than the second,
the function returns a value smaller than zero.  If they are equal, the
function returns zero.  Otherwise, it should return a value greater than
zero.  The compare function defines the order of the tree elements.

The OSSL_RBT_INIT() macro initializes the tree referenced by B<head>.

The red-black tree can also be initialized statically by using the
OSSL_RBT_INITIALIZER() macro like this:

 OSSL_RBT_HEAD(HEADNAME, NODE_TYPE) head = OSSL_RBT_INITIALIZER(&head);

The OSSL_RBT_INSERT() macro inserts the new element B<elm> into the tree pointed by B<head>.
Upon success, NULL is returned.  If a matching element already exists in the
tree, the insertion is aborted, and a pointer to the existing element is
returned.

The OSSL_RBT_REMOVE() macro removes the element B<elm> from the tree pointed by
B<head>.  OSSL_RBT_REMOVE() returns B<elm>.

The OSSL_RBT_LEFT() macro returns a pointer to the left child element of B<elm>
in a red-black tree of type B<NAME>.

The OSSL_RBT_RIGHT() macro returns a pointer to the right child element
of B<elm> in a red-black tree of type B<NAME>.

The OSSL_RBT_PARENT() macro returns a pointer to the parent element of B<elm>
in a red-black tree of type B<NAME>.

The OSSL_RBT_SET_LEFT() macro sets the left child pointer of element B<elm>
to B<left> in a red-black tree of type B<NAME>.

The OSSL_RBT_SET_RIGHT() macro sets the right child pointer of element B<elm>
to B<right> in a red-black tree of type B<NAME>.

The OSSL_RBT_SET_PARENT() macro sets the parent pointer of element B<elm>
to B<parent> in a red-black tree of type B<NAME>.

The OSSL_RBT_FIND() and OSSL_RBT_NFIND() macros can be used to find a particular
element in the tree.  OSSL_RBT_FIND() finds the node with the same key as B<elm>.
OSSL_RBT_NFIND() finds the first node greater than or equal to the search key.

 struct NODE_TYPE find, *res;
 find.key = 30;
 res = OSSL_RBT_FIND(NAME, &head, &find);

The OSSL_RBT_ROOT(), OSSL_RBT_MIN(), OSSL_RBT_MAX(), OSSL_RBT_NEXT(), and
OSSL_RBT_PREV() macros can be used to traverse the tree:

 for (np = OSSL_RBT_MIN(NAME, &head); np != NULL; np = OSSL_RBT_NEXT(NAME, &head, np))

Or, for simplicity, one can use the OSSL_RBT_FOREACH() or OSSL_RBT_FOREACH_REVERSE()
macros:

 OSSL_RBT_FOREACH(np, NAME, &head)

The macros OSSL_RBT_FOREACH_SAFE() and OSSL_RBT_FOREACH_REVERSE_SAFE() traverse the
tree referenced by head in a forward or reverse direction respectively,
assigning each element in turn to B<VARNAME>.  However, unlike their unsafe
counterparts, they permit both the removal of B<VARNAME> as well as freeing it
from within the loop safely without interfering with the traversal.

The OSSL_RBT_EMPTY() macro should be used to check whether a red-black tree is
empty.

=head1 EXAMPLES

The following example demonstrates how to declare a red-black tree
holding integers.  Values are inserted into it and the contents of the
tree are printed in order.  Lastly, the internal structure of the tree
is printed.

  #include <err.h>
  #include <stdio.h>
  #include <stdlib.h>

  #include "internal/nelem.h"
  #include "internal/ossl_rbtree.h"

  struct node {
      OSSL_RBT_ENTRY(node) entry;
      int i;
  };

  static int intcmp(const struct node *, const struct node *);

  OSSL_RBT_HEAD(inttree, node) head = OSSL_RBT_INITIALIZER(&head);
  OSSL_RBT_PROTOTYPE(inttree, node, entry, intcmp)
  OSSL_RBT_GENERATE(inttree, node, entry, intcmp);

  static const int testdata[] = {
      20, 16, 17, 13,  3,  6,  1,  8,  2,  4,
      10, 19,  5,  9, 12, 15, 18,  7, 11, 14
  };

  static int intcmp(const struct node *e1, const struct node *e2)
  {
      return e1->i < e2->i ? -1 : e1->i > e2->i;
  }

  static void print_tree(struct node *n)
  {
      struct node *left, *right;

      if (n == NULL) {
          printf("nil");
          return;
      }

      left = OSSL_RBT_LEFT(inttree, n);
      right = OSSL_RBT_RIGHT(inttree, n);

      if (left == NULL && right == NULL) {
          printf("%d", n->i);
      } else {
          printf("%d(", n->i);
          print_tree(left);
          printf(",");
          print_tree(right);
          printf(")");
      }
  }

  int main(void)
  {
      size_t i;
      struct node *n;

      for (i = 0; i < OSSL_NELEM(testdata); i++) {
          if ((n = OPENSSL_malloc(sizeof(struct node))) == NULL)
              err(1, NULL);
          n->i = testdata[i];
          OSSL_RBT_INSERT(inttree, &head, n);
      }

      OSSL_RBT_FOREACH (n, inttree, &head) {
          printf("%d\n", n->i);
      }

      print_tree(OSSL_RBT_ROOT(inttree, &head));
      printf("\n");

      return 0;
  }

=head1 HISTORY

The red-black tree implementation comes from David Gwynne.  It can be found
here: L<https://github.com/dgwynne/data-structures>.  OpenSSL project
obtained a permission from David Gwynne to license his work under
Apache License 2.0

Apart from B<OSSL_RBT_> prefix, the API is compatible with implementation
done by Neils Provos for OpenBSD.

The text in this manual page comes from C<tree(3)> in OpenBSD, the text was
authored by Neils Provos (according to the commit history)

The red-black tree implementation was added in OpenSSL 4.1.

=head1 COPYRIGHT

Copyright 2002 Niels Provos <provos@citi.umich.edu>
All rights reserved.

Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.


Licensed under the Apache License 2.0 (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
