xref: /freebsd/share/man/man3/tree.3 (revision 7728586800bd5bb4655cff6d661133ed10cc2ff7)
1.\"	$OpenBSD: tree.3,v 1.7 2002/06/12 01:09:20 provos Exp $
2.\"
3.\" Copyright 2002 Niels Provos <provos@citi.umich.edu>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\"    notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice, this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\"    must display the following acknowledgement:
16.\"      This product includes software developed by Niels Provos.
17.\" 4. The name of the author may not be used to endorse or promote products
18.\"    derived from this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.\"
31.Dd August 2, 2024
32.Dt TREE 3
33.Os
34.Sh NAME
35.Nm SPLAY_PROTOTYPE ,
36.Nm SPLAY_GENERATE ,
37.Nm SPLAY_ENTRY ,
38.Nm SPLAY_HEAD ,
39.Nm SPLAY_INITIALIZER ,
40.Nm SPLAY_ROOT ,
41.Nm SPLAY_EMPTY ,
42.Nm SPLAY_NEXT ,
43.Nm SPLAY_MIN ,
44.Nm SPLAY_MAX ,
45.Nm SPLAY_FIND ,
46.Nm SPLAY_LEFT ,
47.Nm SPLAY_RIGHT ,
48.Nm SPLAY_FOREACH ,
49.Nm SPLAY_INIT ,
50.Nm SPLAY_INSERT ,
51.Nm SPLAY_REMOVE ,
52.Nm RB_PROTOTYPE ,
53.Nm RB_PROTOTYPE_STATIC ,
54.Nm RB_PROTOTYPE_INSERT ,
55.Nm RB_PROTOTYPE_INSERT_COLOR ,
56.Nm RB_PROTOTYPE_REMOVE ,
57.Nm RB_PROTOTYPE_REMOVE_COLOR ,
58.Nm RB_PROTOTYPE_FIND ,
59.Nm RB_PROTOTYPE_NFIND ,
60.Nm RB_PROTOTYPE_NEXT ,
61.Nm RB_PROTOTYPE_PREV ,
62.Nm RB_PROTOTYPE_MINMAX ,
63.Nm RB_PROTOTYPE_REINSERT ,
64.Nm RB_GENERATE ,
65.Nm RB_GENERATE_STATIC ,
66.Nm RB_GENERATE_INSERT ,
67.Nm RB_GENERATE_INSERT_COLOR ,
68.Nm RB_GENERATE_REMOVE ,
69.Nm RB_GENERATE_REMOVE_COLOR ,
70.Nm RB_GENERATE_FIND ,
71.Nm RB_GENERATE_NFIND ,
72.Nm RB_GENERATE_NEXT ,
73.Nm RB_GENERATE_PREV ,
74.Nm RB_GENERATE_MINMAX ,
75.Nm RB_GENERATE_REINSERT ,
76.Nm RB_ENTRY ,
77.Nm RB_HEAD ,
78.Nm RB_INITIALIZER ,
79.Nm RB_ROOT ,
80.Nm RB_EMPTY ,
81.Nm RB_NEXT ,
82.Nm RB_PREV ,
83.Nm RB_MIN ,
84.Nm RB_MAX ,
85.Nm RB_FIND ,
86.Nm RB_NFIND ,
87.Nm RB_LEFT ,
88.Nm RB_RIGHT ,
89.Nm RB_PARENT ,
90.Nm RB_FOREACH ,
91.Nm RB_FOREACH_FROM ,
92.Nm RB_FOREACH_SAFE ,
93.Nm RB_FOREACH_REVERSE ,
94.Nm RB_FOREACH_REVERSE_FROM ,
95.Nm RB_FOREACH_REVERSE_SAFE ,
96.Nm RB_INIT ,
97.Nm RB_INSERT ,
98.Nm RB_INSERT_NEXT ,
99.Nm RB_INSERT_PREV ,
100.Nm RB_REMOVE ,
101.Nm RB_REINSERT ,
102.Nm RB_AUGMENT
103.Nm RB_AUGMENT_CHECK,
104.Nm RB_UPDATE_AUGMENT
105.Nd "implementations of splay and rank-balanced (wavl) trees"
106.Sh SYNOPSIS
107.In sys/tree.h
108.Fn SPLAY_PROTOTYPE NAME TYPE FIELD CMP
109.Fn SPLAY_GENERATE NAME TYPE FIELD CMP
110.Fn SPLAY_ENTRY TYPE
111.Fn SPLAY_HEAD HEADNAME TYPE
112.Ft "struct TYPE *"
113.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
114.Fn SPLAY_ROOT "SPLAY_HEAD *head"
115.Ft bool
116.Fn SPLAY_EMPTY "SPLAY_HEAD *head"
117.Ft "struct TYPE *"
118.Fn SPLAY_NEXT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
119.Ft "struct TYPE *"
120.Fn SPLAY_MIN NAME "SPLAY_HEAD *head"
121.Ft "struct TYPE *"
122.Fn SPLAY_MAX NAME "SPLAY_HEAD *head"
123.Ft "struct TYPE *"
124.Fn SPLAY_FIND NAME "SPLAY_HEAD *head" "struct TYPE *elm"
125.Ft "struct TYPE *"
126.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
127.Ft "struct TYPE *"
128.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
129.Fn SPLAY_FOREACH VARNAME NAME "SPLAY_HEAD *head"
130.Ft void
131.Fn SPLAY_INIT "SPLAY_HEAD *head"
132.Ft "struct TYPE *"
133.Fn SPLAY_INSERT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
134.Ft "struct TYPE *"
135.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm"
136.Fn RB_PROTOTYPE NAME TYPE FIELD CMP
137.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP
138.Fn RB_PROTOTYPE_INSERT NAME TYPE ATTR
139.Fn RB_PROTOTYPE_INSERT_COLOR NAME TYPE ATTR
140.Fn RB_PROTOTYPE_REMOVE NAME TYPE ATTR
141.Fn RB_PROTOTYPE_REMOVE_COLOR NAME TYPE ATTR
142.Fn RB_PROTOTYPE_FIND NAME TYPE ATTR
143.Fn RB_PROTOTYPE_NFIND NAME TYPE ATTR
144.Fn RB_PROTOTYPE_NEXT NAME TYPE ATTR
145.Fn RB_PROTOTYPE_PREV NAME TYPE ATTR
146.Fn RB_PROTOTYPE_MINMAX NAME TYPE ATTR
147.Fn RB_PROTOTYPE_REINSERT NAME TYPE ATTR
148.Fn RB_GENERATE NAME TYPE FIELD CMP
149.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP
150.Fn RB_GENERATE_INSERT NAME TYPE FIELD CMP ATTR
151.Fn RB_GENERATE_INSERT_COLOR NAME TYPE FIELD ATTR
152.Fn RB_GENERATE_REMOVE NAME TYPE FIELD ATTR
153.Fn RB_GENERATE_REMOVE_COLOR NAME TYPE FIELD ATTR
154.Fn RB_GENERATE_FIND NAME TYPE FIELD CMP ATTR
155.Fn RB_GENERATE_NFIND NAME TYPE FIELD CMP ATTR
156.Fn RB_GENERATE_NEXT NAME TYPE FIELD ATTR
157.Fn RB_GENERATE_PREV NAME TYPE FIELD ATTR
158.Fn RB_GENERATE_MINMAX NAME TYPE FIELD ATTR
159.Fn RB_GENERATE_REINSERT NAME TYPE FIELD CMP ATTR
160.Fn RB_ENTRY TYPE
161.Fn RB_HEAD HEADNAME TYPE
162.Fn RB_INITIALIZER "RB_HEAD *head"
163.Ft "struct TYPE *"
164.Fn RB_ROOT "RB_HEAD *head"
165.Ft "bool"
166.Fn RB_EMPTY "RB_HEAD *head"
167.Ft "struct TYPE *"
168.Fn RB_NEXT NAME "RB_HEAD *head" "struct TYPE *elm"
169.Ft "struct TYPE *"
170.Fn RB_PREV NAME "RB_HEAD *head" "struct TYPE *elm"
171.Ft "struct TYPE *"
172.Fn RB_MIN NAME "RB_HEAD *head"
173.Ft "struct TYPE *"
174.Fn RB_MAX NAME "RB_HEAD *head"
175.Ft "struct TYPE *"
176.Fn RB_FIND NAME "RB_HEAD *head" "struct TYPE *elm"
177.Ft "struct TYPE *"
178.Fn RB_NFIND NAME "RB_HEAD *head" "struct TYPE *elm"
179.Ft "struct TYPE *"
180.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
181.Ft "struct TYPE *"
182.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
183.Ft "struct TYPE *"
184.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
185.Fn RB_FOREACH VARNAME NAME "RB_HEAD *head"
186.Fn RB_FOREACH_FROM "VARNAME" "NAME" "POS_VARNAME"
187.Fn RB_FOREACH_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
188.Fn RB_FOREACH_REVERSE VARNAME NAME "RB_HEAD *head"
189.Fn RB_FOREACH_REVERSE_FROM "VARNAME" "NAME" "POS_VARNAME"
190.Fn RB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
191.Ft void
192.Fn RB_INIT "RB_HEAD *head"
193.Ft "struct TYPE *"
194.Fn RB_INSERT NAME "RB_HEAD *head" "struct TYPE *elm"
195.Ft "struct TYPE *"
196.Fn RB_INSERT_NEXT NAME "RB_HEAD *head" "struct TYPE *elm" "struct TYPE *next"
197.Ft "struct TYPE *"
198.Fn RB_INSERT_PREV NAME "RB_HEAD *head" "struct TYPE *elm" "struct TYPE *prev"
199.Ft "struct TYPE *"
200.Fn RB_REMOVE NAME "RB_HEAD *head" "struct TYPE *elm"
201.Ft "struct TYPE *"
202.Fn RB_REINSERT NAME "RB_HEAD *head" "struct TYPE *elm"
203.Ft "void"
204.Fn RB_AUGMENT NAME "struct TYPE *elm"
205.Ft "bool"
206.Fn RB_AUGMENT_CHECK NAME "struct TYPE *elm"
207.Ft "void"
208.Fn RB_UPDATE_AUGMENT NAME "struct TYPE *elm"
209.Sh DESCRIPTION
210These macros define data structures for different types of trees:
211splay trees and rank-balanced (wavl) trees.
212.Pp
213In the macro definitions,
214.Fa TYPE
215is the name tag of a user defined structure that must contain a field of type
216.Vt SPLAY_ENTRY ,
217or
218.Vt RB_ENTRY ,
219named
220.Fa ENTRYNAME .
221The argument
222.Fa HEADNAME
223is the name tag of a user defined structure that must be declared
224using the macros
225.Fn SPLAY_HEAD ,
226or
227.Fn RB_HEAD .
228The argument
229.Fa NAME
230has to be a unique name prefix for every tree that is defined.
231.Pp
232The function prototypes are declared with
233.Fn SPLAY_PROTOTYPE ,
234.Fn RB_PROTOTYPE ,
235or
236.Fn RB_PROTOTYPE_STATIC .
237The function bodies are generated with
238.Fn SPLAY_GENERATE ,
239.Fn RB_GENERATE ,
240or
241.Fn RB_GENERATE_STATIC .
242See the examples below for further explanation of how these macros are used.
243.Sh SPLAY TREES
244A splay tree is a self-organizing data structure.
245Every operation on the tree causes a splay to happen.
246The splay moves the requested
247node to the root of the tree and partly rebalances it.
248.Pp
249This has the benefit that request locality causes faster lookups as
250the requested nodes move to the top of the tree.
251On the other hand, every lookup causes memory writes.
252.Pp
253The Balance Theorem bounds the total access time for
254.Ar m
255operations and
256.Ar n
257inserts on an initially empty tree as
258.Fn O "\*[lp]m + n\*[rp]lg n" .
259The
260amortized cost for a sequence of
261.Ar m
262accesses to a splay tree is
263.Fn O "lg n" .
264.Pp
265A splay tree is headed by a structure defined by the
266.Fn SPLAY_HEAD
267macro.
268A
269structure is declared as follows:
270.Bd -ragged -offset indent
271.Fn SPLAY_HEAD HEADNAME TYPE
272.Va head ;
273.Ed
274.Pp
275where
276.Fa HEADNAME
277is the name of the structure to be defined, and struct
278.Fa TYPE
279is the type of the elements to be inserted into the tree.
280.Pp
281The
282.Fn SPLAY_ENTRY
283macro declares a structure that allows elements to be connected in the tree.
284.Pp
285In order to use the functions that manipulate the tree structure,
286their prototypes need to be declared with the
287.Fn SPLAY_PROTOTYPE
288macro,
289where
290.Fa NAME
291is a unique identifier for this particular tree.
292The
293.Fa TYPE
294argument is the type of the structure that is being managed
295by the tree.
296The
297.Fa FIELD
298argument is the name of the element defined by
299.Fn SPLAY_ENTRY .
300.Pp
301The function bodies are generated with the
302.Fn SPLAY_GENERATE
303macro.
304It takes the same arguments as the
305.Fn SPLAY_PROTOTYPE
306macro, but should be used only once.
307.Pp
308Finally,
309the
310.Fa CMP
311argument is the name of a function used to compare tree nodes
312with each other.
313The function takes two arguments of type
314.Vt "struct TYPE *" .
315If the first argument is smaller than the second, the function returns a
316value smaller than zero.
317If they are equal, the function returns zero.
318Otherwise, it should return a value greater than zero.
319The compare
320function defines the order of the tree elements.
321.Pp
322The
323.Fn SPLAY_INIT
324macro initializes the tree referenced by
325.Fa head .
326.Pp
327The splay tree can also be initialized statically by using the
328.Fn SPLAY_INITIALIZER
329macro like this:
330.Bd -ragged -offset indent
331.Fn SPLAY_HEAD HEADNAME TYPE
332.Va head
333=
334.Fn SPLAY_INITIALIZER &head ;
335.Ed
336.Pp
337The
338.Fn SPLAY_INSERT
339macro inserts the new element
340.Fa elm
341into the tree.
342.Pp
343The
344.Fn SPLAY_REMOVE
345macro removes the element
346.Fa elm
347from the tree pointed by
348.Fa head .
349.Pp
350The
351.Fn SPLAY_FIND
352macro can be used to find a particular element in the tree.
353.Bd -literal -offset indent
354struct TYPE find, *res;
355find.key = 30;
356res = SPLAY_FIND(NAME, head, &find);
357.Ed
358.Pp
359The
360.Fn SPLAY_ROOT ,
361.Fn SPLAY_MIN ,
362.Fn SPLAY_MAX ,
363and
364.Fn SPLAY_NEXT
365macros can be used to traverse the tree:
366.Bd -literal -offset indent
367for (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
368.Ed
369.Pp
370Or, for simplicity, one can use the
371.Fn SPLAY_FOREACH
372macro:
373.Bd -ragged -offset indent
374.Fn SPLAY_FOREACH np NAME head
375.Ed
376.Pp
377The
378.Fn SPLAY_EMPTY
379macro should be used to check whether a splay tree is empty.
380.Sh RANK-BALANCED TREES
381Rank-balanced (RB) trees are a framework for defining height-balanced
382binary search trees, including AVL and red-black trees.
383Each tree node has an associated rank.
384Balance conditions are expressed by conditions on the differences in
385rank between any node and its children.
386Rank differences are stored in each tree node.
387.Pp
388The balance conditions implemented by the RB macros lead to weak AVL
389(wavl) trees, which combine the best aspects of AVL and red-black
390trees.
391Wavl trees rebalance after an insertion in the same way AVL trees do,
392with the same worst-case time as red-black trees offer, and with
393better balance in the resulting tree.
394Wavl trees rebalance after a removal in a way that requires less
395restructuring, in the worst case, than either AVL or red-black trees
396do.
397Removals can lead to a tree almost as unbalanced as a red-black
398tree; insertions lead to a tree becoming as balanced as an AVL tree.
399.Pp
400A rank-balanced tree is headed by a structure defined by the
401.Fn RB_HEAD
402macro.
403A
404structure is declared as follows:
405.Bd -ragged -offset indent
406.Fn RB_HEAD HEADNAME TYPE
407.Va head ;
408.Ed
409.Pp
410where
411.Fa HEADNAME
412is the name of the structure to be defined, and struct
413.Fa TYPE
414is the type of the elements to be inserted into the tree.
415.Pp
416The
417.Fn RB_ENTRY
418macro declares a structure that allows elements to be connected in the tree.
419.Pp
420In order to use the functions that manipulate the tree structure,
421their prototypes need to be declared with the
422.Fn RB_PROTOTYPE
423or
424.Fn RB_PROTOTYPE_STATIC
425macro,
426where
427.Fa NAME
428is a unique identifier for this particular tree.
429The
430.Fa TYPE
431argument is the type of the structure that is being managed
432by the tree.
433The
434.Fa FIELD
435argument is the name of the element defined by
436.Fn RB_ENTRY .
437Individual prototypes can be declared with
438.Fn RB_PROTOTYPE_INSERT ,
439.Fn RB_PROTOTYPE_INSERT_COLOR ,
440.Fn RB_PROTOTYPE_REMOVE ,
441.Fn RB_PROTOTYPE_REMOVE_COLOR ,
442.Fn RB_PROTOTYPE_FIND ,
443.Fn RB_PROTOTYPE_NFIND ,
444.Fn RB_PROTOTYPE_NEXT ,
445.Fn RB_PROTOTYPE_PREV ,
446.Fn RB_PROTOTYPE_MINMAX ,
447and
448.Fn RB_PROTOTYPE_REINSERT
449in case not all functions are required.
450The individual prototype macros expect
451.Fa NAME ,
452.Fa TYPE ,
453and
454.Fa ATTR
455arguments.
456The
457.Fa ATTR
458argument must be empty for global functions or
459.Fa static
460for static functions.
461.Pp
462The function bodies are generated with the
463.Fn RB_GENERATE
464or
465.Fn RB_GENERATE_STATIC
466macro.
467These macros take the same arguments as the
468.Fn RB_PROTOTYPE
469and
470.Fn RB_PROTOTYPE_STATIC
471macros, but should be used only once.
472As an alternative individual function bodies are generated with the
473.Fn RB_GENERATE_INSERT ,
474.Fn RB_GENERATE_INSERT_COLOR ,
475.Fn RB_GENERATE_REMOVE ,
476.Fn RB_GENERATE_REMOVE_COLOR ,
477.Fn RB_GENERATE_FIND ,
478.Fn RB_GENERATE_NFIND ,
479.Fn RB_GENERATE_NEXT ,
480.Fn RB_GENERATE_PREV ,
481.Fn RB_GENERATE_MINMAX ,
482and
483.Fn RB_GENERATE_REINSERT
484macros.
485.Pp
486Finally,
487the
488.Fa CMP
489argument is the name of a function used to compare tree nodes
490with each other.
491The function takes two arguments of type
492.Vt "struct TYPE *" .
493If the first argument is smaller than the second, the function returns a
494value smaller than zero.
495If they are equal, the function returns zero.
496Otherwise, it should return a value greater than zero.
497The compare
498function defines the order of the tree elements.
499.Pp
500The
501.Fn RB_INIT
502macro initializes the tree referenced by
503.Fa head .
504.Pp
505The rank-balanced tree can also be initialized statically by using the
506.Fn RB_INITIALIZER
507macro like this:
508.Bd -ragged -offset indent
509.Fn RB_HEAD HEADNAME TYPE
510.Va head
511=
512.Fn RB_INITIALIZER &head ;
513.Ed
514.Pp
515The
516.Fn RB_INSERT
517macro inserts the new element
518.Fa elm
519into the tree.
520.Pp
521The
522.Fn RB_INSERT_NEXT
523macro inserts the new element
524.Fa elm
525into the tree immediately after a given element.
526.Pp
527The
528.Fn RB_INSERT_PREV
529macro inserts the new element
530.Fa elm
531into the tree immediately before a given element.
532.Pp
533The
534.Fn RB_REMOVE
535macro removes the element
536.Fa elm
537from the tree pointed by
538.Fa head .
539.Pp
540The
541.Fn RB_FIND
542and
543.Fn RB_NFIND
544macros can be used to find a particular element in the tree.
545.Pp
546The
547.Fn RB_FIND
548macro returns the element in the tree equal to the provided
549key, or
550.Dv NULL
551if there is no such element.
552.Pp
553The
554.Fn RB_NFIND
555macro returns the least element greater than or equal to the provided
556key, or
557.Dv NULL
558if there is no such element.
559.Bd -literal -offset indent
560struct TYPE find, *res, *resn;
561find.key = 30;
562res = RB_FIND(NAME, head, &find);
563resn = RB_NFIND(NAME, head, &find);
564.Ed
565.Pp
566The
567.Fn RB_ROOT ,
568.Fn RB_MIN ,
569.Fn RB_MAX ,
570.Fn RB_NEXT ,
571and
572.Fn RB_PREV
573macros can be used to traverse the tree:
574.Pp
575.Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))"
576.Pp
577Or, for simplicity, one can use the
578.Fn RB_FOREACH
579or
580.Fn RB_FOREACH_REVERSE
581macro:
582.Bd -ragged -offset indent
583.Fn RB_FOREACH np NAME head
584.Ed
585.Pp
586The macros
587.Fn RB_FOREACH_SAFE
588and
589.Fn RB_FOREACH_REVERSE_SAFE
590traverse the tree referenced by head
591in a forward or reverse direction respectively,
592assigning each element in turn to np.
593However, unlike their unsafe counterparts,
594they permit both the removal of np
595as well as freeing it from within the loop safely
596without interfering with the traversal.
597.Pp
598Both
599.Fn RB_FOREACH_FROM
600and
601.Fn RB_FOREACH_REVERSE_FROM
602may be used to continue an interrupted traversal
603in a forward or reverse direction respectively.
604The head pointer is not required.
605The pointer to the node from where to resume the traversal
606should be passed as their last argument,
607and will be overwritten to provide safe traversal.
608.Pp
609The
610.Fn RB_EMPTY
611macro should be used to check whether a rank-balanced tree is empty.
612.Pp
613The
614.Fn RB_REINSERT
615macro updates the position of the element
616.Fa elm
617in the tree.
618This must be called if a member of a
619.Nm tree
620is modified in a way that affects comparison, such as by modifying
621a node's key.
622This is a lower overhead alternative to removing the element
623and reinserting it again.
624.Pp
625The
626.Fn RB_AUGMENT
627macro updates augmentation data of the element
628.Fa elm
629in the tree.
630By default, it has no effect.
631It is not meant to be invoked by the RB user.
632If
633.Fn RB_AUGMENT
634is defined by the RB user, then when an element is inserted or removed
635from the tree, it is invoked for every element in the tree that is the
636root of an altered subtree, working from the bottom of the tree up to
637the top.
638It is typically used to maintain some associative accumulation of tree
639elements, such as sums, minima, maxima, and the like.
640.Pp
641The
642.Fn RB_AUGMENT_CHECK
643macro updates augmentation data of the element
644.Fa elm
645in the tree.
646By default, it does nothing and returns false.
647If
648.Fn RB_AUGMENT_CHECK
649is defined, then when an element is inserted or removed from the tree,
650it is invoked for every element in the tree that is the root of an
651altered subtree, working from the bottom of the tree up toward the
652top, until it returns false to indicate that it did not change the
653element and so working further up the tree would change nothing.
654It is typically used to maintain some associative accumulation of tree
655elements, such as sums, minima, maxima, and the like.
656.Pp
657The
658.Fn RB_UPDATE_AUGMENT
659macro updates augmentation data of the element
660.Fa elm
661and its ancestors in the tree.
662If
663.Fn RB_AUGMENT
664is defined by the RB user, then when an element in the
665tree is changed, without changing the order of items in the tree,
666invoking this function on that element restores consistency of the
667augmentation state of the tree as if the element had been removed and
668inserted again.
669.Sh EXAMPLES
670The following example demonstrates how to declare a rank-balanced tree
671holding integers.
672Values are inserted into it and the contents of the tree are printed
673in order.
674To maintain the sum of the values in the tree, each element maintains
675the sum of its value and the sums from its left and right subtrees.
676Lastly, the internal structure of the tree is printed.
677.Bd -literal -offset 3n
678#define RB_AUGMENT(entry) sumaug(entry)
679
680#include <sys/tree.h>
681#include <err.h>
682#include <stdio.h>
683#include <stdlib.h>
684
685struct node {
686	RB_ENTRY(node) entry;
687	int i, sum;
688};
689
690int
691intcmp(struct node *e1, struct node *e2)
692{
693	return (e1->i < e2->i ? -1 : e1->i > e2->i);
694}
695
696void
697sumaug(struct node *e)
698{
699	e->sum = e->i;
700	if (RB_LEFT(e, entry) != NULL)
701		e->sum += RB_LEFT(e, entry)->sum;
702	if (RB_RIGHT(e, entry) != NULL)
703		e->sum += RB_RIGHT(e, entry)->sum;
704}
705
706RB_HEAD(inttree, node) head = RB_INITIALIZER(&head);
707RB_GENERATE(inttree, node, entry, intcmp)
708
709int testdata[] = {
710	20, 16, 17, 13, 3, 6, 1, 8, 2, 4, 10, 19, 5, 9, 12, 15, 18,
711	7, 11, 14
712};
713
714void
715print_tree(struct node *n)
716{
717	struct node *left, *right;
718
719	if (n == NULL) {
720		printf("nil");
721		return;
722	}
723	left = RB_LEFT(n, entry);
724	right = RB_RIGHT(n, entry);
725	if (left == NULL && right == NULL)
726		printf("%d", n->i);
727	else {
728		printf("%d(", n->i);
729		print_tree(left);
730		printf(",");
731		print_tree(right);
732		printf(")");
733	}
734}
735
736int
737main(void)
738{
739	int i;
740	struct node *n;
741
742	for (i = 0; i < sizeof(testdata) / sizeof(testdata[0]); i++) {
743		if ((n = malloc(sizeof(struct node))) == NULL)
744			err(1, NULL);
745		n->i = testdata[i];
746		RB_INSERT(inttree, &head, n);
747	}
748
749	RB_FOREACH(n, inttree, &head) {
750		printf("%d\en", n->i);
751	}
752	print_tree(RB_ROOT(&head));
753	printf("\enSum of values = %d\en", RB_ROOT(&head)->sum);
754	return (0);
755}
756.Ed
757.Sh NOTES
758Trying to free a tree in the following way is a common error:
759.Bd -literal -offset indent
760SPLAY_FOREACH(var, NAME, head) {
761	SPLAY_REMOVE(NAME, head, var);
762	free(var);
763}
764free(head);
765.Ed
766.Pp
767Since
768.Va var
769is freed, the
770.Fn FOREACH
771macro refers to a pointer that may have been reallocated already.
772Proper code needs a second variable.
773.Bd -literal -offset indent
774for (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) {
775	nxt = SPLAY_NEXT(NAME, head, var);
776	SPLAY_REMOVE(NAME, head, var);
777	free(var);
778}
779.Ed
780.Pp
781Both
782.Fn RB_INSERT
783and
784.Fn SPLAY_INSERT
785return
786.Dv NULL
787if the element was inserted in the tree successfully, otherwise they
788return a pointer to the element with the colliding key.
789.Pp
790Accordingly,
791.Fn RB_REMOVE
792and
793.Fn SPLAY_REMOVE
794return the pointer to the removed element otherwise they return
795.Dv NULL
796to indicate an error.
797.Sh SEE ALSO
798.Xr arb 3 ,
799.Xr queue 3
800.Rs
801.%A "Bernhard Haeupler"
802.%A "Siddhartha Sen"
803.%A "Robert E. Tarjan"
804.%T "Rank-Balanced Trees"
805.%U "http://sidsen.azurewebsites.net/papers/rb-trees-talg.pdf"
806.%J "ACM Transactions on Algorithms"
807.%V "11"
808.%N "4"
809.%D "June 2015"
810.Re
811.Sh HISTORY
812The tree macros first appeared in
813.Fx 4.6 .
814.Sh AUTHORS
815The author of the tree macros is
816.An Niels Provos .
817