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