1 /*-------------------------------------------------------------------------
4 * implementation for PostgreSQL generic Red-Black binary tree package
5 * Adopted from http://algolist.manual.ru/ds/rbtree.php
7 * This code comes from Thomas Niemann's "Sorting and Searching Algorithms:
10 * See http://www.cs.auckland.ac.nz/software/AlgAnim/niemann/s_man.htm for
11 * license terms: "Source code, when part of a software project, may be used
12 * freely without reference to the author."
14 * Red-black trees are a type of balanced binary tree wherein (1) any child of
15 * a red node is always black, and (2) every path from root to leaf traverses
16 * an equal number of black nodes. From these properties, it follows that the
17 * longest path from root to leaf is only about twice as long as the shortest,
18 * so lookups are guaranteed to run in O(lg n) time.
20 * Copyright (c) 2009-2025, PostgreSQL Global Development Group
23 * src/backend/lib/rbtree.c
25 *-------------------------------------------------------------------------
29 #include "lib/rbtree.h"
33 * Colors of nodes (values of RBTNode.color)
39 * RBTree control structure
43 RBTNode
*root
; /* root node, or RBTNIL if tree is empty */
45 /* Remaining fields are constant after rbt_create */
47 Size node_size
; /* actual size of tree nodes */
48 /* The caller-supplied manipulation functions */
49 rbt_comparator comparator
;
50 rbt_combiner combiner
;
51 rbt_allocfunc allocfunc
;
52 rbt_freefunc freefunc
;
53 /* Passthrough arg passed to all manipulation functions */
58 * all leafs are sentinels, use customized NIL name to prevent
59 * collision with system-wide constant NIL which is actually NULL
61 #define RBTNIL (&sentinel)
63 static RBTNode sentinel
=
65 .color
= RBTBLACK
,.left
= RBTNIL
,.right
= RBTNIL
,.parent
= NULL
70 * rbt_create: create an empty RBTree
73 * node_size: actual size of tree nodes (> sizeof(RBTNode))
74 * The manipulation functions:
75 * comparator: compare two RBTNodes for less/equal/greater
76 * combiner: merge an existing tree entry with a new one
77 * allocfunc: allocate a new RBTNode
78 * freefunc: free an old RBTNode
79 * arg: passthrough pointer that will be passed to the manipulation functions
81 * Note that the combiner's righthand argument will be a "proposed" tree node,
82 * ie the input to rbt_insert, in which the RBTNode fields themselves aren't
83 * valid. Similarly, either input to the comparator may be a "proposed" node.
84 * This shouldn't matter since the functions aren't supposed to look at the
85 * RBTNode fields, only the extra fields of the struct the RBTNode is embedded
88 * The freefunc should just be pfree or equivalent; it should NOT attempt
89 * to free any subsidiary data, because the node passed to it may not contain
90 * valid data! freefunc can be NULL if caller doesn't require retail
93 * The RBTree node is palloc'd in the caller's memory context. Note that
94 * all contents of the tree are actually allocated by the caller, not here.
96 * Since tree contents are managed by the caller, there is currently not
97 * an explicit "destroy" operation; typically a tree would be freed by
98 * resetting or deleting the memory context it's stored in. You can pfree
99 * the RBTree node if you feel the urge.
102 rbt_create(Size node_size
,
103 rbt_comparator comparator
,
104 rbt_combiner combiner
,
105 rbt_allocfunc allocfunc
,
106 rbt_freefunc freefunc
,
109 RBTree
*tree
= (RBTree
*) palloc(sizeof(RBTree
));
111 Assert(node_size
> sizeof(RBTNode
));
114 tree
->node_size
= node_size
;
115 tree
->comparator
= comparator
;
116 tree
->combiner
= combiner
;
117 tree
->allocfunc
= allocfunc
;
118 tree
->freefunc
= freefunc
;
125 /* Copy the additional data fields from one RBTNode to another */
127 rbt_copy_data(RBTree
*rbt
, RBTNode
*dest
, const RBTNode
*src
)
129 memcpy(dest
+ 1, src
+ 1, rbt
->node_size
- sizeof(RBTNode
));
132 /**********************************************************************
134 **********************************************************************/
137 * rbt_find: search for a value in an RBTree
139 * data represents the value to try to find. Its RBTNode fields need not
140 * be valid, it's the extra data in the larger struct that is of interest.
142 * Returns the matching tree entry, or NULL if no match is found.
145 rbt_find(RBTree
*rbt
, const RBTNode
*data
)
147 RBTNode
*node
= rbt
->root
;
149 while (node
!= RBTNIL
)
151 int cmp
= rbt
->comparator(data
, node
, rbt
->arg
);
165 * rbt_find_great: search for a greater value in an RBTree
167 * If equal_match is true, this will be a great or equal search.
169 * Returns the matching tree entry, or NULL if no match is found.
172 rbt_find_great(RBTree
*rbt
, const RBTNode
*data
, bool equal_match
)
174 RBTNode
*node
= rbt
->root
;
175 RBTNode
*greater
= NULL
;
177 while (node
!= RBTNIL
)
179 int cmp
= rbt
->comparator(data
, node
, rbt
->arg
);
181 if (equal_match
&& cmp
== 0)
196 * rbt_find_less: search for a lesser value in an RBTree
198 * If equal_match is true, this will be a less or equal search.
200 * Returns the matching tree entry, or NULL if no match is found.
203 rbt_find_less(RBTree
*rbt
, const RBTNode
*data
, bool equal_match
)
205 RBTNode
*node
= rbt
->root
;
206 RBTNode
*lesser
= NULL
;
208 while (node
!= RBTNIL
)
210 int cmp
= rbt
->comparator(data
, node
, rbt
->arg
);
212 if (equal_match
&& cmp
== 0)
227 * rbt_leftmost: fetch the leftmost (smallest-valued) tree node.
228 * Returns NULL if tree is empty.
230 * Note: in the original implementation this included an unlink step, but
231 * that's a bit awkward. Just call rbt_delete on the result if that's what
235 rbt_leftmost(RBTree
*rbt
)
237 RBTNode
*node
= rbt
->root
;
238 RBTNode
*leftmost
= rbt
->root
;
240 while (node
!= RBTNIL
)
246 if (leftmost
!= RBTNIL
)
252 /**********************************************************************
254 **********************************************************************/
257 * Rotate node x to left.
259 * x's right child takes its place in the tree, and x becomes the left
260 * child of that node.
263 rbt_rotate_left(RBTree
*rbt
, RBTNode
*x
)
265 RBTNode
*y
= x
->right
;
267 /* establish x->right link */
269 if (y
->left
!= RBTNIL
)
272 /* establish y->parent link */
274 y
->parent
= x
->parent
;
277 if (x
== x
->parent
->left
)
280 x
->parent
->right
= y
;
294 * Rotate node x to right.
296 * x's left right child takes its place in the tree, and x becomes the right
297 * child of that node.
300 rbt_rotate_right(RBTree
*rbt
, RBTNode
*x
)
302 RBTNode
*y
= x
->left
;
304 /* establish x->left link */
306 if (y
->right
!= RBTNIL
)
307 y
->right
->parent
= x
;
309 /* establish y->parent link */
311 y
->parent
= x
->parent
;
314 if (x
== x
->parent
->right
)
315 x
->parent
->right
= y
;
331 * Maintain Red-Black tree balance after inserting node x.
333 * The newly inserted node is always initially marked red. That may lead to
334 * a situation where a red node has a red child, which is prohibited. We can
335 * always fix the problem by a series of color changes and/or "rotations",
336 * which move the problem progressively higher up in the tree. If one of the
337 * two red nodes is the root, we can always fix the problem by changing the
338 * root from red to black.
340 * (This does not work lower down in the tree because we must also maintain
341 * the invariant that every leaf has equal black-height.)
344 rbt_insert_fixup(RBTree
*rbt
, RBTNode
*x
)
347 * x is always a red node. Initially, it is the newly inserted node. Each
348 * iteration of this loop moves it higher up in the tree.
350 while (x
!= rbt
->root
&& x
->parent
->color
== RBTRED
)
353 * x and x->parent are both red. Fix depends on whether x->parent is
354 * a left or right child. In either case, we define y to be the
355 * "uncle" of x, that is, the other child of x's grandparent.
357 * If the uncle is red, we flip the grandparent to red and its two
358 * children to black. Then we loop around again to check whether the
359 * grandparent still has a problem.
361 * If the uncle is black, we will perform one or two "rotations" to
362 * balance the tree. Either x or x->parent will take the
363 * grandparent's position in the tree and recolored black, and the
364 * original grandparent will be recolored red and become a child of
365 * that node. This always leaves us with a valid red-black tree, so
366 * the loop will terminate.
368 if (x
->parent
== x
->parent
->parent
->left
)
370 RBTNode
*y
= x
->parent
->parent
->right
;
372 if (y
->color
== RBTRED
)
374 /* uncle is RBTRED */
375 x
->parent
->color
= RBTBLACK
;
377 x
->parent
->parent
->color
= RBTRED
;
379 x
= x
->parent
->parent
;
383 /* uncle is RBTBLACK */
384 if (x
== x
->parent
->right
)
386 /* make x a left child */
388 rbt_rotate_left(rbt
, x
);
391 /* recolor and rotate */
392 x
->parent
->color
= RBTBLACK
;
393 x
->parent
->parent
->color
= RBTRED
;
395 rbt_rotate_right(rbt
, x
->parent
->parent
);
400 /* mirror image of above code */
401 RBTNode
*y
= x
->parent
->parent
->left
;
403 if (y
->color
== RBTRED
)
405 /* uncle is RBTRED */
406 x
->parent
->color
= RBTBLACK
;
408 x
->parent
->parent
->color
= RBTRED
;
410 x
= x
->parent
->parent
;
414 /* uncle is RBTBLACK */
415 if (x
== x
->parent
->left
)
418 rbt_rotate_right(rbt
, x
);
420 x
->parent
->color
= RBTBLACK
;
421 x
->parent
->parent
->color
= RBTRED
;
423 rbt_rotate_left(rbt
, x
->parent
->parent
);
429 * The root may already have been black; if not, the black-height of every
430 * node in the tree increases by one.
432 rbt
->root
->color
= RBTBLACK
;
436 * rbt_insert: insert a new value into the tree.
438 * data represents the value to insert. Its RBTNode fields need not
439 * be valid, it's the extra data in the larger struct that is of interest.
441 * If the value represented by "data" is not present in the tree, then
442 * we copy "data" into a new tree entry and return that node, setting *isNew
445 * If the value represented by "data" is already present, then we call the
446 * combiner function to merge data into the existing node, and return the
447 * existing node, setting *isNew to false.
449 * "data" is unmodified in either case; it's typically just a local
450 * variable in the caller.
453 rbt_insert(RBTree
*rbt
, const RBTNode
*data
, bool *isNew
)
460 /* find where node belongs */
463 cmp
= 0; /* just to prevent compiler warning */
465 while (current
!= RBTNIL
)
467 cmp
= rbt
->comparator(data
, current
, rbt
->arg
);
471 * Found node with given key. Apply combiner.
473 rbt
->combiner(current
, data
, rbt
->arg
);
478 current
= (cmp
< 0) ? current
->left
: current
->right
;
482 * Value is not present, so create a new node containing data.
486 x
= rbt
->allocfunc(rbt
->arg
);
493 rbt_copy_data(rbt
, x
, data
);
495 /* insert node in tree */
508 rbt_insert_fixup(rbt
, x
);
513 /**********************************************************************
515 **********************************************************************/
518 * Maintain Red-Black tree balance after deleting a black node.
521 rbt_delete_fixup(RBTree
*rbt
, RBTNode
*x
)
524 * x is always a black node. Initially, it is the former child of the
525 * deleted node. Each iteration of this loop moves it higher up in the
528 while (x
!= rbt
->root
&& x
->color
== RBTBLACK
)
531 * Left and right cases are symmetric. Any nodes that are children of
532 * x have a black-height one less than the remainder of the nodes in
533 * the tree. We rotate and recolor nodes to move the problem up the
534 * tree: at some stage we'll either fix the problem, or reach the root
535 * (where the black-height is allowed to decrease).
537 if (x
== x
->parent
->left
)
539 RBTNode
*w
= x
->parent
->right
;
541 if (w
->color
== RBTRED
)
544 x
->parent
->color
= RBTRED
;
546 rbt_rotate_left(rbt
, x
->parent
);
547 w
= x
->parent
->right
;
550 if (w
->left
->color
== RBTBLACK
&& w
->right
->color
== RBTBLACK
)
558 if (w
->right
->color
== RBTBLACK
)
560 w
->left
->color
= RBTBLACK
;
563 rbt_rotate_right(rbt
, w
);
564 w
= x
->parent
->right
;
566 w
->color
= x
->parent
->color
;
567 x
->parent
->color
= RBTBLACK
;
568 w
->right
->color
= RBTBLACK
;
570 rbt_rotate_left(rbt
, x
->parent
);
571 x
= rbt
->root
; /* Arrange for loop to terminate. */
576 RBTNode
*w
= x
->parent
->left
;
578 if (w
->color
== RBTRED
)
581 x
->parent
->color
= RBTRED
;
583 rbt_rotate_right(rbt
, x
->parent
);
587 if (w
->right
->color
== RBTBLACK
&& w
->left
->color
== RBTBLACK
)
595 if (w
->left
->color
== RBTBLACK
)
597 w
->right
->color
= RBTBLACK
;
600 rbt_rotate_left(rbt
, w
);
603 w
->color
= x
->parent
->color
;
604 x
->parent
->color
= RBTBLACK
;
605 w
->left
->color
= RBTBLACK
;
607 rbt_rotate_right(rbt
, x
->parent
);
608 x
= rbt
->root
; /* Arrange for loop to terminate. */
616 * Delete node z from tree.
619 rbt_delete_node(RBTree
*rbt
, RBTNode
*z
)
624 /* This is just paranoia: we should only get called on a valid node */
625 if (!z
|| z
== RBTNIL
)
629 * y is the node that will actually be removed from the tree. This will
630 * be z if z has fewer than two children, or the tree successor of z
633 if (z
->left
== RBTNIL
|| z
->right
== RBTNIL
)
635 /* y has a RBTNIL node as a child */
640 /* find tree successor */
642 while (y
->left
!= RBTNIL
)
646 /* x is y's only child */
647 if (y
->left
!= RBTNIL
)
652 /* Remove y from the tree. */
653 x
->parent
= y
->parent
;
656 if (y
== y
->parent
->left
)
659 y
->parent
->right
= x
;
667 * If we removed the tree successor of z rather than z itself, then move
668 * the data for the removed node to the one we were supposed to remove.
671 rbt_copy_data(rbt
, z
, y
);
674 * Removing a black node might make some paths from root to leaf contain
675 * fewer black nodes than others, or it might make two red nodes adjacent.
677 if (y
->color
== RBTBLACK
)
678 rbt_delete_fixup(rbt
, x
);
680 /* Now we can recycle the y node */
682 rbt
->freefunc(y
, rbt
->arg
);
686 * rbt_delete: remove the given tree entry
688 * "node" must have previously been found via rbt_find or rbt_leftmost.
689 * It is caller's responsibility to free any subsidiary data attached
690 * to the node before calling rbt_delete. (Do *not* try to push that
691 * responsibility off to the freefunc, as some other physical node
692 * may be the one actually freed!)
695 rbt_delete(RBTree
*rbt
, RBTNode
*node
)
697 rbt_delete_node(rbt
, node
);
700 /**********************************************************************
702 **********************************************************************/
705 rbt_left_right_iterator(RBTreeIterator
*iter
)
707 if (iter
->last_visited
== NULL
)
709 iter
->last_visited
= iter
->rbt
->root
;
710 while (iter
->last_visited
->left
!= RBTNIL
)
711 iter
->last_visited
= iter
->last_visited
->left
;
713 return iter
->last_visited
;
716 if (iter
->last_visited
->right
!= RBTNIL
)
718 iter
->last_visited
= iter
->last_visited
->right
;
719 while (iter
->last_visited
->left
!= RBTNIL
)
720 iter
->last_visited
= iter
->last_visited
->left
;
722 return iter
->last_visited
;
727 RBTNode
*came_from
= iter
->last_visited
;
729 iter
->last_visited
= iter
->last_visited
->parent
;
730 if (iter
->last_visited
== NULL
)
732 iter
->is_over
= true;
736 if (iter
->last_visited
->left
== came_from
)
737 break; /* came from left sub-tree, return current
740 /* else - came from right sub-tree, continue to move up */
743 return iter
->last_visited
;
747 rbt_right_left_iterator(RBTreeIterator
*iter
)
749 if (iter
->last_visited
== NULL
)
751 iter
->last_visited
= iter
->rbt
->root
;
752 while (iter
->last_visited
->right
!= RBTNIL
)
753 iter
->last_visited
= iter
->last_visited
->right
;
755 return iter
->last_visited
;
758 if (iter
->last_visited
->left
!= RBTNIL
)
760 iter
->last_visited
= iter
->last_visited
->left
;
761 while (iter
->last_visited
->right
!= RBTNIL
)
762 iter
->last_visited
= iter
->last_visited
->right
;
764 return iter
->last_visited
;
769 RBTNode
*came_from
= iter
->last_visited
;
771 iter
->last_visited
= iter
->last_visited
->parent
;
772 if (iter
->last_visited
== NULL
)
774 iter
->is_over
= true;
778 if (iter
->last_visited
->right
== came_from
)
779 break; /* came from right sub-tree, return current
782 /* else - came from left sub-tree, continue to move up */
785 return iter
->last_visited
;
789 * rbt_begin_iterate: prepare to traverse the tree in any of several orders
791 * After calling rbt_begin_iterate, call rbt_iterate repeatedly until it
792 * returns NULL or the traversal stops being of interest.
794 * If the tree is changed during traversal, results of further calls to
795 * rbt_iterate are unspecified. Multiple concurrent iterators on the same
798 * The iterator state is stored in the 'iter' struct. The caller should
799 * treat it as an opaque struct.
802 rbt_begin_iterate(RBTree
*rbt
, RBTOrderControl ctrl
, RBTreeIterator
*iter
)
804 /* Common initialization for all traversal orders */
806 iter
->last_visited
= NULL
;
807 iter
->is_over
= (rbt
->root
== RBTNIL
);
811 case LeftRightWalk
: /* visit left, then self, then right */
812 iter
->iterate
= rbt_left_right_iterator
;
814 case RightLeftWalk
: /* visit right, then self, then left */
815 iter
->iterate
= rbt_right_left_iterator
;
818 elog(ERROR
, "unrecognized rbtree iteration order: %d", ctrl
);
823 * rbt_iterate: return the next node in traversal order, or NULL if no more
826 rbt_iterate(RBTreeIterator
*iter
)
831 return iter
->iterate(iter
);