1 /*-------------------------------------------------------------------------
2  *
3  * rbtree.c
4  *	  implementation for PostgreSQL generic Red-Black binary tree package
5  *	  Adopted from http://algolist.manual.ru/ds/rbtree.php
6  *
7  * This code comes from Thomas Niemann's "Sorting and Searching Algorithms:
8  * a Cookbook".
9  *
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."
13  *
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.
19  *
20  * Copyright (c) 2009-2018, PostgreSQL Global Development Group
21  *
22  * IDENTIFICATION
23  *	  src/backend/lib/rbtree.c
24  *
25  *-------------------------------------------------------------------------
26  */
27 #include "postgres.h"
28 
29 #include "lib/rbtree.h"
30 
31 
32 /*
33  * Colors of nodes (values of RBTNode.color)
34  */
35 #define RBTBLACK	(0)
36 #define RBTRED		(1)
37 
38 /*
39  * RBTree control structure
40  */
41 struct RBTree
42 {
43 	RBTNode    *root;			/* root node, or RBTNIL if tree is empty */
44 
45 	/* Remaining fields are constant after rbt_create */
46 
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 */
54 	void	   *arg;
55 };
56 
57 /*
58  * all leafs are sentinels, use customized NIL name to prevent
59  * collision with system-wide constant NIL which is actually NULL
60  */
61 #define RBTNIL (&sentinel)
62 
63 static RBTNode sentinel =
64 {
65 	RBTBLACK, RBTNIL, RBTNIL, NULL
66 };
67 
68 
69 /*
70  * rbt_create: create an empty RBTree
71  *
72  * Arguments are:
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
80  *
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
86  * in.
87  *
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
91  * space reclamation.
92  *
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.
95  *
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.
100  */
101 RBTree *
rbt_create(Size node_size,rbt_comparator comparator,rbt_combiner combiner,rbt_allocfunc allocfunc,rbt_freefunc freefunc,void * arg)102 rbt_create(Size node_size,
103 		   rbt_comparator comparator,
104 		   rbt_combiner combiner,
105 		   rbt_allocfunc allocfunc,
106 		   rbt_freefunc freefunc,
107 		   void *arg)
108 {
109 	RBTree	   *tree = (RBTree *) palloc(sizeof(RBTree));
110 
111 	Assert(node_size > sizeof(RBTNode));
112 
113 	tree->root = RBTNIL;
114 	tree->node_size = node_size;
115 	tree->comparator = comparator;
116 	tree->combiner = combiner;
117 	tree->allocfunc = allocfunc;
118 	tree->freefunc = freefunc;
119 
120 	tree->arg = arg;
121 
122 	return tree;
123 }
124 
125 /* Copy the additional data fields from one RBTNode to another */
126 static inline void
rbt_copy_data(RBTree * rbt,RBTNode * dest,const RBTNode * src)127 rbt_copy_data(RBTree *rbt, RBTNode *dest, const RBTNode *src)
128 {
129 	memcpy(dest + 1, src + 1, rbt->node_size - sizeof(RBTNode));
130 }
131 
132 /**********************************************************************
133  *						  Search									  *
134  **********************************************************************/
135 
136 /*
137  * rbt_find: search for a value in an RBTree
138  *
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.
141  *
142  * Returns the matching tree entry, or NULL if no match is found.
143  */
144 RBTNode *
rbt_find(RBTree * rbt,const RBTNode * data)145 rbt_find(RBTree *rbt, const RBTNode *data)
146 {
147 	RBTNode    *node = rbt->root;
148 
149 	while (node != RBTNIL)
150 	{
151 		int			cmp = rbt->comparator(data, node, rbt->arg);
152 
153 		if (cmp == 0)
154 			return node;
155 		else if (cmp < 0)
156 			node = node->left;
157 		else
158 			node = node->right;
159 	}
160 
161 	return NULL;
162 }
163 
164 /*
165  * rbt_leftmost: fetch the leftmost (smallest-valued) tree node.
166  * Returns NULL if tree is empty.
167  *
168  * Note: in the original implementation this included an unlink step, but
169  * that's a bit awkward.  Just call rbt_delete on the result if that's what
170  * you want.
171  */
172 RBTNode *
rbt_leftmost(RBTree * rbt)173 rbt_leftmost(RBTree *rbt)
174 {
175 	RBTNode    *node = rbt->root;
176 	RBTNode    *leftmost = rbt->root;
177 
178 	while (node != RBTNIL)
179 	{
180 		leftmost = node;
181 		node = node->left;
182 	}
183 
184 	if (leftmost != RBTNIL)
185 		return leftmost;
186 
187 	return NULL;
188 }
189 
190 /**********************************************************************
191  *							  Insertion								  *
192  **********************************************************************/
193 
194 /*
195  * Rotate node x to left.
196  *
197  * x's right child takes its place in the tree, and x becomes the left
198  * child of that node.
199  */
200 static void
rbt_rotate_left(RBTree * rbt,RBTNode * x)201 rbt_rotate_left(RBTree *rbt, RBTNode *x)
202 {
203 	RBTNode    *y = x->right;
204 
205 	/* establish x->right link */
206 	x->right = y->left;
207 	if (y->left != RBTNIL)
208 		y->left->parent = x;
209 
210 	/* establish y->parent link */
211 	if (y != RBTNIL)
212 		y->parent = x->parent;
213 	if (x->parent)
214 	{
215 		if (x == x->parent->left)
216 			x->parent->left = y;
217 		else
218 			x->parent->right = y;
219 	}
220 	else
221 	{
222 		rbt->root = y;
223 	}
224 
225 	/* link x and y */
226 	y->left = x;
227 	if (x != RBTNIL)
228 		x->parent = y;
229 }
230 
231 /*
232  * Rotate node x to right.
233  *
234  * x's left right child takes its place in the tree, and x becomes the right
235  * child of that node.
236  */
237 static void
rbt_rotate_right(RBTree * rbt,RBTNode * x)238 rbt_rotate_right(RBTree *rbt, RBTNode *x)
239 {
240 	RBTNode    *y = x->left;
241 
242 	/* establish x->left link */
243 	x->left = y->right;
244 	if (y->right != RBTNIL)
245 		y->right->parent = x;
246 
247 	/* establish y->parent link */
248 	if (y != RBTNIL)
249 		y->parent = x->parent;
250 	if (x->parent)
251 	{
252 		if (x == x->parent->right)
253 			x->parent->right = y;
254 		else
255 			x->parent->left = y;
256 	}
257 	else
258 	{
259 		rbt->root = y;
260 	}
261 
262 	/* link x and y */
263 	y->right = x;
264 	if (x != RBTNIL)
265 		x->parent = y;
266 }
267 
268 /*
269  * Maintain Red-Black tree balance after inserting node x.
270  *
271  * The newly inserted node is always initially marked red.  That may lead to
272  * a situation where a red node has a red child, which is prohibited.  We can
273  * always fix the problem by a series of color changes and/or "rotations",
274  * which move the problem progressively higher up in the tree.  If one of the
275  * two red nodes is the root, we can always fix the problem by changing the
276  * root from red to black.
277  *
278  * (This does not work lower down in the tree because we must also maintain
279  * the invariant that every leaf has equal black-height.)
280  */
281 static void
rbt_insert_fixup(RBTree * rbt,RBTNode * x)282 rbt_insert_fixup(RBTree *rbt, RBTNode *x)
283 {
284 	/*
285 	 * x is always a red node.  Initially, it is the newly inserted node. Each
286 	 * iteration of this loop moves it higher up in the tree.
287 	 */
288 	while (x != rbt->root && x->parent->color == RBTRED)
289 	{
290 		/*
291 		 * x and x->parent are both red.  Fix depends on whether x->parent is
292 		 * a left or right child.  In either case, we define y to be the
293 		 * "uncle" of x, that is, the other child of x's grandparent.
294 		 *
295 		 * If the uncle is red, we flip the grandparent to red and its two
296 		 * children to black.  Then we loop around again to check whether the
297 		 * grandparent still has a problem.
298 		 *
299 		 * If the uncle is black, we will perform one or two "rotations" to
300 		 * balance the tree.  Either x or x->parent will take the
301 		 * grandparent's position in the tree and recolored black, and the
302 		 * original grandparent will be recolored red and become a child of
303 		 * that node. This always leaves us with a valid red-black tree, so
304 		 * the loop will terminate.
305 		 */
306 		if (x->parent == x->parent->parent->left)
307 		{
308 			RBTNode    *y = x->parent->parent->right;
309 
310 			if (y->color == RBTRED)
311 			{
312 				/* uncle is RBTRED */
313 				x->parent->color = RBTBLACK;
314 				y->color = RBTBLACK;
315 				x->parent->parent->color = RBTRED;
316 
317 				x = x->parent->parent;
318 			}
319 			else
320 			{
321 				/* uncle is RBTBLACK */
322 				if (x == x->parent->right)
323 				{
324 					/* make x a left child */
325 					x = x->parent;
326 					rbt_rotate_left(rbt, x);
327 				}
328 
329 				/* recolor and rotate */
330 				x->parent->color = RBTBLACK;
331 				x->parent->parent->color = RBTRED;
332 
333 				rbt_rotate_right(rbt, x->parent->parent);
334 			}
335 		}
336 		else
337 		{
338 			/* mirror image of above code */
339 			RBTNode    *y = x->parent->parent->left;
340 
341 			if (y->color == RBTRED)
342 			{
343 				/* uncle is RBTRED */
344 				x->parent->color = RBTBLACK;
345 				y->color = RBTBLACK;
346 				x->parent->parent->color = RBTRED;
347 
348 				x = x->parent->parent;
349 			}
350 			else
351 			{
352 				/* uncle is RBTBLACK */
353 				if (x == x->parent->left)
354 				{
355 					x = x->parent;
356 					rbt_rotate_right(rbt, x);
357 				}
358 				x->parent->color = RBTBLACK;
359 				x->parent->parent->color = RBTRED;
360 
361 				rbt_rotate_left(rbt, x->parent->parent);
362 			}
363 		}
364 	}
365 
366 	/*
367 	 * The root may already have been black; if not, the black-height of every
368 	 * node in the tree increases by one.
369 	 */
370 	rbt->root->color = RBTBLACK;
371 }
372 
373 /*
374  * rbt_insert: insert a new value into the tree.
375  *
376  * data represents the value to insert.  Its RBTNode fields need not
377  * be valid, it's the extra data in the larger struct that is of interest.
378  *
379  * If the value represented by "data" is not present in the tree, then
380  * we copy "data" into a new tree entry and return that node, setting *isNew
381  * to true.
382  *
383  * If the value represented by "data" is already present, then we call the
384  * combiner function to merge data into the existing node, and return the
385  * existing node, setting *isNew to false.
386  *
387  * "data" is unmodified in either case; it's typically just a local
388  * variable in the caller.
389  */
390 RBTNode *
rbt_insert(RBTree * rbt,const RBTNode * data,bool * isNew)391 rbt_insert(RBTree *rbt, const RBTNode *data, bool *isNew)
392 {
393 	RBTNode    *current,
394 			   *parent,
395 			   *x;
396 	int			cmp;
397 
398 	/* find where node belongs */
399 	current = rbt->root;
400 	parent = NULL;
401 	cmp = 0;					/* just to prevent compiler warning */
402 
403 	while (current != RBTNIL)
404 	{
405 		cmp = rbt->comparator(data, current, rbt->arg);
406 		if (cmp == 0)
407 		{
408 			/*
409 			 * Found node with given key.  Apply combiner.
410 			 */
411 			rbt->combiner(current, data, rbt->arg);
412 			*isNew = false;
413 			return current;
414 		}
415 		parent = current;
416 		current = (cmp < 0) ? current->left : current->right;
417 	}
418 
419 	/*
420 	 * Value is not present, so create a new node containing data.
421 	 */
422 	*isNew = true;
423 
424 	x = rbt->allocfunc(rbt->arg);
425 
426 	x->color = RBTRED;
427 
428 	x->left = RBTNIL;
429 	x->right = RBTNIL;
430 	x->parent = parent;
431 	rbt_copy_data(rbt, x, data);
432 
433 	/* insert node in tree */
434 	if (parent)
435 	{
436 		if (cmp < 0)
437 			parent->left = x;
438 		else
439 			parent->right = x;
440 	}
441 	else
442 	{
443 		rbt->root = x;
444 	}
445 
446 	rbt_insert_fixup(rbt, x);
447 
448 	return x;
449 }
450 
451 /**********************************************************************
452  *							Deletion								  *
453  **********************************************************************/
454 
455 /*
456  * Maintain Red-Black tree balance after deleting a black node.
457  */
458 static void
rbt_delete_fixup(RBTree * rbt,RBTNode * x)459 rbt_delete_fixup(RBTree *rbt, RBTNode *x)
460 {
461 	/*
462 	 * x is always a black node.  Initially, it is the former child of the
463 	 * deleted node.  Each iteration of this loop moves it higher up in the
464 	 * tree.
465 	 */
466 	while (x != rbt->root && x->color == RBTBLACK)
467 	{
468 		/*
469 		 * Left and right cases are symmetric.  Any nodes that are children of
470 		 * x have a black-height one less than the remainder of the nodes in
471 		 * the tree.  We rotate and recolor nodes to move the problem up the
472 		 * tree: at some stage we'll either fix the problem, or reach the root
473 		 * (where the black-height is allowed to decrease).
474 		 */
475 		if (x == x->parent->left)
476 		{
477 			RBTNode    *w = x->parent->right;
478 
479 			if (w->color == RBTRED)
480 			{
481 				w->color = RBTBLACK;
482 				x->parent->color = RBTRED;
483 
484 				rbt_rotate_left(rbt, x->parent);
485 				w = x->parent->right;
486 			}
487 
488 			if (w->left->color == RBTBLACK && w->right->color == RBTBLACK)
489 			{
490 				w->color = RBTRED;
491 
492 				x = x->parent;
493 			}
494 			else
495 			{
496 				if (w->right->color == RBTBLACK)
497 				{
498 					w->left->color = RBTBLACK;
499 					w->color = RBTRED;
500 
501 					rbt_rotate_right(rbt, w);
502 					w = x->parent->right;
503 				}
504 				w->color = x->parent->color;
505 				x->parent->color = RBTBLACK;
506 				w->right->color = RBTBLACK;
507 
508 				rbt_rotate_left(rbt, x->parent);
509 				x = rbt->root;	/* Arrange for loop to terminate. */
510 			}
511 		}
512 		else
513 		{
514 			RBTNode    *w = x->parent->left;
515 
516 			if (w->color == RBTRED)
517 			{
518 				w->color = RBTBLACK;
519 				x->parent->color = RBTRED;
520 
521 				rbt_rotate_right(rbt, x->parent);
522 				w = x->parent->left;
523 			}
524 
525 			if (w->right->color == RBTBLACK && w->left->color == RBTBLACK)
526 			{
527 				w->color = RBTRED;
528 
529 				x = x->parent;
530 			}
531 			else
532 			{
533 				if (w->left->color == RBTBLACK)
534 				{
535 					w->right->color = RBTBLACK;
536 					w->color = RBTRED;
537 
538 					rbt_rotate_left(rbt, w);
539 					w = x->parent->left;
540 				}
541 				w->color = x->parent->color;
542 				x->parent->color = RBTBLACK;
543 				w->left->color = RBTBLACK;
544 
545 				rbt_rotate_right(rbt, x->parent);
546 				x = rbt->root;	/* Arrange for loop to terminate. */
547 			}
548 		}
549 	}
550 	x->color = RBTBLACK;
551 }
552 
553 /*
554  * Delete node z from tree.
555  */
556 static void
rbt_delete_node(RBTree * rbt,RBTNode * z)557 rbt_delete_node(RBTree *rbt, RBTNode *z)
558 {
559 	RBTNode    *x,
560 			   *y;
561 
562 	/* This is just paranoia: we should only get called on a valid node */
563 	if (!z || z == RBTNIL)
564 		return;
565 
566 	/*
567 	 * y is the node that will actually be removed from the tree.  This will
568 	 * be z if z has fewer than two children, or the tree successor of z
569 	 * otherwise.
570 	 */
571 	if (z->left == RBTNIL || z->right == RBTNIL)
572 	{
573 		/* y has a RBTNIL node as a child */
574 		y = z;
575 	}
576 	else
577 	{
578 		/* find tree successor */
579 		y = z->right;
580 		while (y->left != RBTNIL)
581 			y = y->left;
582 	}
583 
584 	/* x is y's only child */
585 	if (y->left != RBTNIL)
586 		x = y->left;
587 	else
588 		x = y->right;
589 
590 	/* Remove y from the tree. */
591 	x->parent = y->parent;
592 	if (y->parent)
593 	{
594 		if (y == y->parent->left)
595 			y->parent->left = x;
596 		else
597 			y->parent->right = x;
598 	}
599 	else
600 	{
601 		rbt->root = x;
602 	}
603 
604 	/*
605 	 * If we removed the tree successor of z rather than z itself, then move
606 	 * the data for the removed node to the one we were supposed to remove.
607 	 */
608 	if (y != z)
609 		rbt_copy_data(rbt, z, y);
610 
611 	/*
612 	 * Removing a black node might make some paths from root to leaf contain
613 	 * fewer black nodes than others, or it might make two red nodes adjacent.
614 	 */
615 	if (y->color == RBTBLACK)
616 		rbt_delete_fixup(rbt, x);
617 
618 	/* Now we can recycle the y node */
619 	if (rbt->freefunc)
620 		rbt->freefunc(y, rbt->arg);
621 }
622 
623 /*
624  * rbt_delete: remove the given tree entry
625  *
626  * "node" must have previously been found via rbt_find or rbt_leftmost.
627  * It is caller's responsibility to free any subsidiary data attached
628  * to the node before calling rbt_delete.  (Do *not* try to push that
629  * responsibility off to the freefunc, as some other physical node
630  * may be the one actually freed!)
631  */
632 void
rbt_delete(RBTree * rbt,RBTNode * node)633 rbt_delete(RBTree *rbt, RBTNode *node)
634 {
635 	rbt_delete_node(rbt, node);
636 }
637 
638 /**********************************************************************
639  *						  Traverse									  *
640  **********************************************************************/
641 
642 static RBTNode *
rbt_left_right_iterator(RBTreeIterator * iter)643 rbt_left_right_iterator(RBTreeIterator *iter)
644 {
645 	if (iter->last_visited == NULL)
646 	{
647 		iter->last_visited = iter->rbt->root;
648 		while (iter->last_visited->left != RBTNIL)
649 			iter->last_visited = iter->last_visited->left;
650 
651 		return iter->last_visited;
652 	}
653 
654 	if (iter->last_visited->right != RBTNIL)
655 	{
656 		iter->last_visited = iter->last_visited->right;
657 		while (iter->last_visited->left != RBTNIL)
658 			iter->last_visited = iter->last_visited->left;
659 
660 		return iter->last_visited;
661 	}
662 
663 	for (;;)
664 	{
665 		RBTNode    *came_from = iter->last_visited;
666 
667 		iter->last_visited = iter->last_visited->parent;
668 		if (iter->last_visited == NULL)
669 		{
670 			iter->is_over = true;
671 			break;
672 		}
673 
674 		if (iter->last_visited->left == came_from)
675 			break;				/* came from left sub-tree, return current
676 								 * node */
677 
678 		/* else - came from right sub-tree, continue to move up */
679 	}
680 
681 	return iter->last_visited;
682 }
683 
684 static RBTNode *
rbt_right_left_iterator(RBTreeIterator * iter)685 rbt_right_left_iterator(RBTreeIterator *iter)
686 {
687 	if (iter->last_visited == NULL)
688 	{
689 		iter->last_visited = iter->rbt->root;
690 		while (iter->last_visited->right != RBTNIL)
691 			iter->last_visited = iter->last_visited->right;
692 
693 		return iter->last_visited;
694 	}
695 
696 	if (iter->last_visited->left != RBTNIL)
697 	{
698 		iter->last_visited = iter->last_visited->left;
699 		while (iter->last_visited->right != RBTNIL)
700 			iter->last_visited = iter->last_visited->right;
701 
702 		return iter->last_visited;
703 	}
704 
705 	for (;;)
706 	{
707 		RBTNode    *came_from = iter->last_visited;
708 
709 		iter->last_visited = iter->last_visited->parent;
710 		if (iter->last_visited == NULL)
711 		{
712 			iter->is_over = true;
713 			break;
714 		}
715 
716 		if (iter->last_visited->right == came_from)
717 			break;				/* came from right sub-tree, return current
718 								 * node */
719 
720 		/* else - came from left sub-tree, continue to move up */
721 	}
722 
723 	return iter->last_visited;
724 }
725 
726 /*
727  * rbt_begin_iterate: prepare to traverse the tree in any of several orders
728  *
729  * After calling rbt_begin_iterate, call rbt_iterate repeatedly until it
730  * returns NULL or the traversal stops being of interest.
731  *
732  * If the tree is changed during traversal, results of further calls to
733  * rbt_iterate are unspecified.  Multiple concurrent iterators on the same
734  * tree are allowed.
735  *
736  * The iterator state is stored in the 'iter' struct.  The caller should
737  * treat it as an opaque struct.
738  */
739 void
rbt_begin_iterate(RBTree * rbt,RBTOrderControl ctrl,RBTreeIterator * iter)740 rbt_begin_iterate(RBTree *rbt, RBTOrderControl ctrl, RBTreeIterator *iter)
741 {
742 	/* Common initialization for all traversal orders */
743 	iter->rbt = rbt;
744 	iter->last_visited = NULL;
745 	iter->is_over = (rbt->root == RBTNIL);
746 
747 	switch (ctrl)
748 	{
749 		case LeftRightWalk:		/* visit left, then self, then right */
750 			iter->iterate = rbt_left_right_iterator;
751 			break;
752 		case RightLeftWalk:		/* visit right, then self, then left */
753 			iter->iterate = rbt_right_left_iterator;
754 			break;
755 		default:
756 			elog(ERROR, "unrecognized rbtree iteration order: %d", ctrl);
757 	}
758 }
759 
760 /*
761  * rbt_iterate: return the next node in traversal order, or NULL if no more
762  */
763 RBTNode *
rbt_iterate(RBTreeIterator * iter)764 rbt_iterate(RBTreeIterator *iter)
765 {
766 	if (iter->is_over)
767 		return NULL;
768 
769 	return iter->iterate(iter);
770 }
771