187f5f0ecSDag-Erling Smørgrav.\" $OpenBSD: tree.3,v 1.7 2002/06/12 01:09:20 provos Exp $ 2480565d5SRuslan Ermilov.\" 3480565d5SRuslan Ermilov.\" Copyright 2002 Niels Provos <provos@citi.umich.edu> 4480565d5SRuslan Ermilov.\" All rights reserved. 5480565d5SRuslan Ermilov.\" 6480565d5SRuslan Ermilov.\" Redistribution and use in source and binary forms, with or without 7480565d5SRuslan Ermilov.\" modification, are permitted provided that the following conditions 8480565d5SRuslan Ermilov.\" are met: 9480565d5SRuslan Ermilov.\" 1. Redistributions of source code must retain the above copyright 10480565d5SRuslan Ermilov.\" notice, this list of conditions and the following disclaimer. 11480565d5SRuslan Ermilov.\" 2. Redistributions in binary form must reproduce the above copyright 12480565d5SRuslan Ermilov.\" notice, this list of conditions and the following disclaimer in the 13480565d5SRuslan Ermilov.\" documentation and/or other materials provided with the distribution. 14480565d5SRuslan Ermilov.\" 3. All advertising materials mentioning features or use of this software 15480565d5SRuslan Ermilov.\" must display the following acknowledgement: 16480565d5SRuslan Ermilov.\" This product includes software developed by Niels Provos. 17480565d5SRuslan Ermilov.\" 4. The name of the author may not be used to endorse or promote products 18480565d5SRuslan Ermilov.\" derived from this software without specific prior written permission. 19480565d5SRuslan Ermilov.\" 20480565d5SRuslan Ermilov.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21480565d5SRuslan Ermilov.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22480565d5SRuslan Ermilov.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23480565d5SRuslan Ermilov.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24480565d5SRuslan Ermilov.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25480565d5SRuslan Ermilov.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26480565d5SRuslan Ermilov.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27480565d5SRuslan Ermilov.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28480565d5SRuslan Ermilov.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29480565d5SRuslan Ermilov.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30480565d5SRuslan Ermilov.\" 31480565d5SRuslan Ermilov.\" $FreeBSD$ 32480565d5SRuslan Ermilov.\" 33*51782e3aSKonstantin Belousov.Dd January 24, 2015 3487f5f0ecSDag-Erling Smørgrav.Dt TREE 3 3587f5f0ecSDag-Erling Smørgrav.Os 3687f5f0ecSDag-Erling Smørgrav.Sh NAME 3787f5f0ecSDag-Erling Smørgrav.Nm SPLAY_PROTOTYPE , 3887f5f0ecSDag-Erling Smørgrav.Nm SPLAY_GENERATE , 3987f5f0ecSDag-Erling Smørgrav.Nm SPLAY_ENTRY , 4087f5f0ecSDag-Erling Smørgrav.Nm SPLAY_HEAD , 4187f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INITIALIZER , 4287f5f0ecSDag-Erling Smørgrav.Nm SPLAY_ROOT , 4387f5f0ecSDag-Erling Smørgrav.Nm SPLAY_EMPTY , 4487f5f0ecSDag-Erling Smørgrav.Nm SPLAY_NEXT , 4587f5f0ecSDag-Erling Smørgrav.Nm SPLAY_MIN , 4687f5f0ecSDag-Erling Smørgrav.Nm SPLAY_MAX , 4787f5f0ecSDag-Erling Smørgrav.Nm SPLAY_FIND , 4887f5f0ecSDag-Erling Smørgrav.Nm SPLAY_LEFT , 4987f5f0ecSDag-Erling Smørgrav.Nm SPLAY_RIGHT , 5087f5f0ecSDag-Erling Smørgrav.Nm SPLAY_FOREACH , 5187f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INIT , 5287f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INSERT , 5387f5f0ecSDag-Erling Smørgrav.Nm SPLAY_REMOVE , 5487f5f0ecSDag-Erling Smørgrav.Nm RB_PROTOTYPE , 55d72cd779SJason Evans.Nm RB_PROTOTYPE_STATIC , 56*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_INSERT , 57*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_INSERT_COLOR , 58*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_REMOVE , 59*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_REMOVE_COLOR , 60*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_FIND , 61*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_NFIND , 62*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_NEXT , 63*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_PREV , 64*51782e3aSKonstantin Belousov.Nm RB_PROTOTYPE_MINMAX , 6587f5f0ecSDag-Erling Smørgrav.Nm RB_GENERATE , 66d72cd779SJason Evans.Nm RB_GENERATE_STATIC , 67*51782e3aSKonstantin Belousov.Nm RB_GENERATE_INSERT , 68*51782e3aSKonstantin Belousov.Nm RB_GENERATE_INSERT_COLOR , 69*51782e3aSKonstantin Belousov.Nm RB_GENERATE_REMOVE , 70*51782e3aSKonstantin Belousov.Nm RB_GENERATE_REMOVE_COLOR , 71*51782e3aSKonstantin Belousov.Nm RB_GENERATE_FIND , 72*51782e3aSKonstantin Belousov.Nm RB_GENERATE_NFIND , 73*51782e3aSKonstantin Belousov.Nm RB_GENERATE_NEXT , 74*51782e3aSKonstantin Belousov.Nm RB_GENERATE_PREV , 75*51782e3aSKonstantin Belousov.Nm RB_GENERATE_MINMAX , 7687f5f0ecSDag-Erling Smørgrav.Nm RB_ENTRY , 7787f5f0ecSDag-Erling Smørgrav.Nm RB_HEAD , 7887f5f0ecSDag-Erling Smørgrav.Nm RB_INITIALIZER , 7987f5f0ecSDag-Erling Smørgrav.Nm RB_ROOT , 8087f5f0ecSDag-Erling Smørgrav.Nm RB_EMPTY , 8187f5f0ecSDag-Erling Smørgrav.Nm RB_NEXT , 828e4fd0a1SJason Evans.Nm RB_PREV , 8387f5f0ecSDag-Erling Smørgrav.Nm RB_MIN , 8487f5f0ecSDag-Erling Smørgrav.Nm RB_MAX , 8587f5f0ecSDag-Erling Smørgrav.Nm RB_FIND , 8606115e08SJason Evans.Nm RB_NFIND , 8787f5f0ecSDag-Erling Smørgrav.Nm RB_LEFT , 8887f5f0ecSDag-Erling Smørgrav.Nm RB_RIGHT , 8987f5f0ecSDag-Erling Smørgrav.Nm RB_PARENT , 9087f5f0ecSDag-Erling Smørgrav.Nm RB_FOREACH , 91bff27689SBruce M Simpson.Nm RB_FOREACH_FROM , 929dbae282SGleb Smirnoff.Nm RB_FOREACH_SAFE , 938e4fd0a1SJason Evans.Nm RB_FOREACH_REVERSE , 94bff27689SBruce M Simpson.Nm RB_FOREACH_REVERSE_FROM , 959dbae282SGleb Smirnoff.Nm RB_FOREACH_REVERSE_SAFE , 9687f5f0ecSDag-Erling Smørgrav.Nm RB_INIT , 9787f5f0ecSDag-Erling Smørgrav.Nm RB_INSERT , 9887f5f0ecSDag-Erling Smørgrav.Nm RB_REMOVE 9987f5f0ecSDag-Erling Smørgrav.Nd "implementations of splay and red-black trees" 10087f5f0ecSDag-Erling Smørgrav.Sh SYNOPSIS 101480565d5SRuslan Ermilov.In sys/tree.h 102480565d5SRuslan Ermilov.Fn SPLAY_PROTOTYPE NAME TYPE FIELD CMP 103480565d5SRuslan Ermilov.Fn SPLAY_GENERATE NAME TYPE FIELD CMP 104480565d5SRuslan Ermilov.Fn SPLAY_ENTRY TYPE 105480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE 10687f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 10787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head" 10887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT "SPLAY_HEAD *head" 109480565d5SRuslan Ermilov.Ft bool 11087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY "SPLAY_HEAD *head" 11187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 112480565d5SRuslan Ermilov.Fn SPLAY_NEXT NAME "SPLAY_HEAD *head" "struct TYPE *elm" 11387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 114480565d5SRuslan Ermilov.Fn SPLAY_MIN NAME "SPLAY_HEAD *head" 11587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 116480565d5SRuslan Ermilov.Fn SPLAY_MAX NAME "SPLAY_HEAD *head" 11787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 118480565d5SRuslan Ermilov.Fn SPLAY_FIND NAME "SPLAY_HEAD *head" "struct TYPE *elm" 11987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 12087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME" 12187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 12287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME" 123480565d5SRuslan Ermilov.Fn SPLAY_FOREACH VARNAME NAME "SPLAY_HEAD *head" 12487f5f0ecSDag-Erling Smørgrav.Ft void 12587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT "SPLAY_HEAD *head" 12687f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 127480565d5SRuslan Ermilov.Fn SPLAY_INSERT NAME "SPLAY_HEAD *head" "struct TYPE *elm" 12887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 129480565d5SRuslan Ermilov.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm" 130480565d5SRuslan Ermilov.Fn RB_PROTOTYPE NAME TYPE FIELD CMP 131d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP 132*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_INSERT NAME TYPE ATTR 133*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_INSERT_COLOR NAME TYPE ATTR 134*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_REMOVE NAME TYPE ATTR 135*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_REMOVE_COLOR NAME TYPE ATTR 136*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_FIND NAME TYPE ATTR 137*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_NFIND NAME TYPE ATTR 138*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_NEXT NAME TYPE ATTR 139*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_PREV NAME TYPE ATTR 140*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_MINMAX NAME TYPE ATTR 141480565d5SRuslan Ermilov.Fn RB_GENERATE NAME TYPE FIELD CMP 142d72cd779SJason Evans.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP 143*51782e3aSKonstantin Belousov.Fn RB_GENERATE_INSERT NAME TYPE FIELD CMP ATTR 144*51782e3aSKonstantin Belousov.Fn RB_GENERATE_INSERT_COLOR NAME TYPE FIELD ATTR 145*51782e3aSKonstantin Belousov.Fn RB_GENERATE_REMOVE NAME TYPE FIELD ATTR 146*51782e3aSKonstantin Belousov.Fn RB_GENERATE_REMOVE_COLOR NAME TYPE FIELD ATTR 147*51782e3aSKonstantin Belousov.Fn RB_GENERATE_FIND NAME TYPE FIELD CMP ATTR 148*51782e3aSKonstantin Belousov.Fn RB_GENERATE_NFIND NAME TYPE FIELD CMP ATTR 149*51782e3aSKonstantin Belousov.Fn RB_GENERATE_NEXT NAME TYPE FIELD ATTR 150*51782e3aSKonstantin Belousov.Fn RB_GENERATE_PREV NAME TYPE FIELD ATTR 151*51782e3aSKonstantin Belousov.Fn RB_GENERATE_MINMAX NAME TYPE FIELD ATTR 152480565d5SRuslan Ermilov.Fn RB_ENTRY TYPE 153480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE 15487f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER "RB_HEAD *head" 15587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 15687f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT "RB_HEAD *head" 15787f5f0ecSDag-Erling Smørgrav.Ft "bool" 15887f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY "RB_HEAD *head" 15987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 160480565d5SRuslan Ermilov.Fn RB_NEXT NAME "RB_HEAD *head" "struct TYPE *elm" 16187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 1628e4fd0a1SJason Evans.Fn RB_PREV NAME "RB_HEAD *head" "struct TYPE *elm" 1638e4fd0a1SJason Evans.Ft "struct TYPE *" 164480565d5SRuslan Ermilov.Fn RB_MIN NAME "RB_HEAD *head" 16587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 166480565d5SRuslan Ermilov.Fn RB_MAX NAME "RB_HEAD *head" 16787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 168480565d5SRuslan Ermilov.Fn RB_FIND NAME "RB_HEAD *head" "struct TYPE *elm" 16987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 17006115e08SJason Evans.Fn RB_NFIND NAME "RB_HEAD *head" "struct TYPE *elm" 17106115e08SJason Evans.Ft "struct TYPE *" 17287f5f0ecSDag-Erling Smørgrav.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME" 17387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 17487f5f0ecSDag-Erling Smørgrav.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME" 17587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 17687f5f0ecSDag-Erling Smørgrav.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME" 177480565d5SRuslan Ermilov.Fn RB_FOREACH VARNAME NAME "RB_HEAD *head" 178639bf7bdSBruce M Simpson.Fn RB_FOREACH_FROM "VARNAME" "NAME" "POS_VARNAME" 1799dbae282SGleb Smirnoff.Fn RB_FOREACH_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME" 1808e4fd0a1SJason Evans.Fn RB_FOREACH_REVERSE VARNAME NAME "RB_HEAD *head" 181639bf7bdSBruce M Simpson.Fn RB_FOREACH_REVERSE_FROM "VARNAME" "NAME" "POS_VARNAME" 1829dbae282SGleb Smirnoff.Fn RB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME" 18387f5f0ecSDag-Erling Smørgrav.Ft void 18487f5f0ecSDag-Erling Smørgrav.Fn RB_INIT "RB_HEAD *head" 18587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 186480565d5SRuslan Ermilov.Fn RB_INSERT NAME "RB_HEAD *head" "struct TYPE *elm" 18787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *" 188480565d5SRuslan Ermilov.Fn RB_REMOVE NAME "RB_HEAD *head" "struct TYPE *elm" 18987f5f0ecSDag-Erling Smørgrav.Sh DESCRIPTION 190480565d5SRuslan ErmilovThese macros define data structures for different types of trees: 19187f5f0ecSDag-Erling Smørgravsplay trees and red-black trees. 19287f5f0ecSDag-Erling Smørgrav.Pp 19387f5f0ecSDag-Erling SmørgravIn the macro definitions, 19487f5f0ecSDag-Erling Smørgrav.Fa TYPE 19587f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must contain a field of type 196480565d5SRuslan Ermilov.Vt SPLAY_ENTRY , 19787f5f0ecSDag-Erling Smørgravor 198480565d5SRuslan Ermilov.Vt RB_ENTRY , 19987f5f0ecSDag-Erling Smørgravnamed 20087f5f0ecSDag-Erling Smørgrav.Fa ENTRYNAME . 20187f5f0ecSDag-Erling SmørgravThe argument 20287f5f0ecSDag-Erling Smørgrav.Fa HEADNAME 20387f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must be declared 20487f5f0ecSDag-Erling Smørgravusing the macros 20587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD , 20687f5f0ecSDag-Erling Smørgravor 20787f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD . 20887f5f0ecSDag-Erling SmørgravThe argument 20987f5f0ecSDag-Erling Smørgrav.Fa NAME 21087f5f0ecSDag-Erling Smørgravhas to be a unique name prefix for every tree that is defined. 21187f5f0ecSDag-Erling Smørgrav.Pp 212d72cd779SJason EvansThe function prototypes are declared with 213480565d5SRuslan Ermilov.Fn SPLAY_PROTOTYPE , 214d72cd779SJason Evans.Fn RB_PROTOTYPE , 21587f5f0ecSDag-Erling Smørgravor 216d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC . 217d72cd779SJason EvansThe function bodies are generated with 218480565d5SRuslan Ermilov.Fn SPLAY_GENERATE , 219d72cd779SJason Evans.Fn RB_GENERATE , 22087f5f0ecSDag-Erling Smørgravor 221d72cd779SJason Evans.Fn RB_GENERATE_STATIC . 22287f5f0ecSDag-Erling SmørgravSee the examples below for further explanation of how these macros are used. 22387f5f0ecSDag-Erling Smørgrav.Sh SPLAY TREES 224480565d5SRuslan ErmilovA splay tree is a self-organizing data structure. 225480565d5SRuslan ErmilovEvery operation on the tree causes a splay to happen. 226480565d5SRuslan ErmilovThe splay moves the requested 22787f5f0ecSDag-Erling Smørgravnode to the root of the tree and partly rebalances it. 22887f5f0ecSDag-Erling Smørgrav.Pp 22987f5f0ecSDag-Erling SmørgravThis has the benefit that request locality causes faster lookups as 230480565d5SRuslan Ermilovthe requested nodes move to the top of the tree. 231480565d5SRuslan ErmilovOn the other hand, every lookup causes memory writes. 23287f5f0ecSDag-Erling Smørgrav.Pp 233480565d5SRuslan ErmilovThe Balance Theorem bounds the total access time for 234480565d5SRuslan Ermilov.Ar m 235480565d5SRuslan Ermilovoperations and 236480565d5SRuslan Ermilov.Ar n 237480565d5SRuslan Ermilovinserts on an initially empty tree as 238480565d5SRuslan Ermilov.Fn O "\*[lp]m + n\*[rp]lg n" . 239480565d5SRuslan ErmilovThe 240480565d5SRuslan Ermilovamortized cost for a sequence of 241480565d5SRuslan Ermilov.Ar m 242480565d5SRuslan Ermilovaccesses to a splay tree is 243480565d5SRuslan Ermilov.Fn O "lg n" . 24487f5f0ecSDag-Erling Smørgrav.Pp 24587f5f0ecSDag-Erling SmørgravA splay tree is headed by a structure defined by the 24687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD 24787f5f0ecSDag-Erling Smørgravmacro. 24887f5f0ecSDag-Erling SmørgravA 24987f5f0ecSDag-Erling Smørgravstructure is declared as follows: 250480565d5SRuslan Ermilov.Bd -ragged -offset indent 251480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE 252480565d5SRuslan Ermilov.Va head ; 25387f5f0ecSDag-Erling Smørgrav.Ed 25487f5f0ecSDag-Erling Smørgrav.Pp 25587f5f0ecSDag-Erling Smørgravwhere 25687f5f0ecSDag-Erling Smørgrav.Fa HEADNAME 25787f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct 25887f5f0ecSDag-Erling Smørgrav.Fa TYPE 25987f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree. 26087f5f0ecSDag-Erling Smørgrav.Pp 26187f5f0ecSDag-Erling SmørgravThe 26287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY 26387f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree. 26487f5f0ecSDag-Erling Smørgrav.Pp 26587f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure, 26687f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the 26787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE 26887f5f0ecSDag-Erling Smørgravmacro, 26987f5f0ecSDag-Erling Smørgravwhere 27087f5f0ecSDag-Erling Smørgrav.Fa NAME 27187f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree. 27287f5f0ecSDag-Erling SmørgravThe 27387f5f0ecSDag-Erling Smørgrav.Fa TYPE 27487f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed 27587f5f0ecSDag-Erling Smørgravby the tree. 27687f5f0ecSDag-Erling SmørgravThe 27787f5f0ecSDag-Erling Smørgrav.Fa FIELD 27887f5f0ecSDag-Erling Smørgravargument is the name of the element defined by 27987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY . 28087f5f0ecSDag-Erling Smørgrav.Pp 28187f5f0ecSDag-Erling SmørgravThe function bodies are generated with the 28287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_GENERATE 283480565d5SRuslan Ermilovmacro. 284480565d5SRuslan ErmilovIt takes the same arguments as the 28587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE 28687f5f0ecSDag-Erling Smørgravmacro, but should be used only once. 28787f5f0ecSDag-Erling Smørgrav.Pp 28887f5f0ecSDag-Erling SmørgravFinally, 28987f5f0ecSDag-Erling Smørgravthe 29087f5f0ecSDag-Erling Smørgrav.Fa CMP 291480565d5SRuslan Ermilovargument is the name of a function used to compare tree nodes 292480565d5SRuslan Ermilovwith each other. 293480565d5SRuslan ErmilovThe function takes two arguments of type 294480565d5SRuslan Ermilov.Vt "struct TYPE *" . 29587f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a 296480565d5SRuslan Ermilovvalue smaller than zero. 297480565d5SRuslan ErmilovIf they are equal, the function returns zero. 298480565d5SRuslan ErmilovOtherwise, it should return a value greater than zero. 299480565d5SRuslan ErmilovThe compare 30087f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements. 30187f5f0ecSDag-Erling Smørgrav.Pp 30287f5f0ecSDag-Erling SmørgravThe 30387f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT 30487f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by 30587f5f0ecSDag-Erling Smørgrav.Fa head . 30687f5f0ecSDag-Erling Smørgrav.Pp 30787f5f0ecSDag-Erling SmørgravThe splay tree can also be initialized statically by using the 30887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER 30987f5f0ecSDag-Erling Smørgravmacro like this: 310480565d5SRuslan Ermilov.Bd -ragged -offset indent 311480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE 312480565d5SRuslan Ermilov.Va head 313480565d5SRuslan Ermilov= 314480565d5SRuslan Ermilov.Fn SPLAY_INITIALIZER &head ; 31587f5f0ecSDag-Erling Smørgrav.Ed 31687f5f0ecSDag-Erling Smørgrav.Pp 31787f5f0ecSDag-Erling SmørgravThe 31887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT 31987f5f0ecSDag-Erling Smørgravmacro inserts the new element 32087f5f0ecSDag-Erling Smørgrav.Fa elm 32187f5f0ecSDag-Erling Smørgravinto the tree. 32287f5f0ecSDag-Erling Smørgrav.Pp 32387f5f0ecSDag-Erling SmørgravThe 32487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE 32587f5f0ecSDag-Erling Smørgravmacro removes the element 32687f5f0ecSDag-Erling Smørgrav.Fa elm 32787f5f0ecSDag-Erling Smørgravfrom the tree pointed by 32887f5f0ecSDag-Erling Smørgrav.Fa head . 32987f5f0ecSDag-Erling Smørgrav.Pp 33087f5f0ecSDag-Erling SmørgravThe 33187f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FIND 33287f5f0ecSDag-Erling Smørgravmacro can be used to find a particular element in the tree. 33387f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent 33487f5f0ecSDag-Erling Smørgravstruct TYPE find, *res; 33587f5f0ecSDag-Erling Smørgravfind.key = 30; 33687f5f0ecSDag-Erling Smørgravres = SPLAY_FIND(NAME, head, &find); 33787f5f0ecSDag-Erling Smørgrav.Ed 33887f5f0ecSDag-Erling Smørgrav.Pp 33987f5f0ecSDag-Erling SmørgravThe 34087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT , 34187f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MIN , 34287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MAX , 34387f5f0ecSDag-Erling Smørgravand 34487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_NEXT 34587f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree: 34687f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent 34787f5f0ecSDag-Erling Smørgravfor (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np)) 34887f5f0ecSDag-Erling Smørgrav.Ed 34987f5f0ecSDag-Erling Smørgrav.Pp 35087f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the 35187f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FOREACH 35287f5f0ecSDag-Erling Smørgravmacro: 353480565d5SRuslan Ermilov.Bd -ragged -offset indent 354480565d5SRuslan Ermilov.Fn SPLAY_FOREACH np NAME head 35587f5f0ecSDag-Erling Smørgrav.Ed 35687f5f0ecSDag-Erling Smørgrav.Pp 35787f5f0ecSDag-Erling SmørgravThe 35887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY 35987f5f0ecSDag-Erling Smørgravmacro should be used to check whether a splay tree is empty. 36087f5f0ecSDag-Erling Smørgrav.Sh RED-BLACK TREES 36187f5f0ecSDag-Erling SmørgravA red-black tree is a binary search tree with the node color as an 362480565d5SRuslan Ermilovextra attribute. 363480565d5SRuslan ErmilovIt fulfills a set of conditions: 364480565d5SRuslan Ermilov.Bl -enum -offset indent 36587f5f0ecSDag-Erling Smørgrav.It 366480565d5SRuslan ErmilovEvery search path from the root to a leaf consists of the same number of 367480565d5SRuslan Ermilovblack nodes. 36887f5f0ecSDag-Erling Smørgrav.It 369480565d5SRuslan ErmilovEach red node (except for the root) has a black parent. 37087f5f0ecSDag-Erling Smørgrav.It 371480565d5SRuslan ErmilovEach leaf node is black. 37287f5f0ecSDag-Erling Smørgrav.El 37387f5f0ecSDag-Erling Smørgrav.Pp 374480565d5SRuslan ErmilovEvery operation on a red-black tree is bounded as 375480565d5SRuslan Ermilov.Fn O "lg n" . 376480565d5SRuslan ErmilovThe maximum height of a red-black tree is 377480565d5SRuslan Ermilov.Fn 2lg "n + 1" . 37887f5f0ecSDag-Erling Smørgrav.Pp 37987f5f0ecSDag-Erling SmørgravA red-black tree is headed by a structure defined by the 38087f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD 38187f5f0ecSDag-Erling Smørgravmacro. 38287f5f0ecSDag-Erling SmørgravA 38387f5f0ecSDag-Erling Smørgravstructure is declared as follows: 384480565d5SRuslan Ermilov.Bd -ragged -offset indent 385480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE 386480565d5SRuslan Ermilov.Va head ; 38787f5f0ecSDag-Erling Smørgrav.Ed 38887f5f0ecSDag-Erling Smørgrav.Pp 38987f5f0ecSDag-Erling Smørgravwhere 39087f5f0ecSDag-Erling Smørgrav.Fa HEADNAME 39187f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct 39287f5f0ecSDag-Erling Smørgrav.Fa TYPE 39387f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree. 39487f5f0ecSDag-Erling Smørgrav.Pp 39587f5f0ecSDag-Erling SmørgravThe 39687f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY 39787f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree. 39887f5f0ecSDag-Erling Smørgrav.Pp 39987f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure, 40087f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the 40187f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE 402d72cd779SJason Evansor 403d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC 40487f5f0ecSDag-Erling Smørgravmacro, 40587f5f0ecSDag-Erling Smørgravwhere 40687f5f0ecSDag-Erling Smørgrav.Fa NAME 40787f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree. 40887f5f0ecSDag-Erling SmørgravThe 40987f5f0ecSDag-Erling Smørgrav.Fa TYPE 41087f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed 41187f5f0ecSDag-Erling Smørgravby the tree. 41287f5f0ecSDag-Erling SmørgravThe 41387f5f0ecSDag-Erling Smørgrav.Fa FIELD 41487f5f0ecSDag-Erling Smørgravargument is the name of the element defined by 41587f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY . 416*51782e3aSKonstantin BelousovIndividual prototypes can be declared with 417*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_INSERT , 418*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_INSERT_COLOR , 419*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_REMOVE , 420*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_REMOVE_COLOR , 421*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_FIND , 422*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_NFIND , 423*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_NEXT , 424*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_PREV , 425*51782e3aSKonstantin Belousovand 426*51782e3aSKonstantin Belousov.Fn RB_PROTOTYPE_MINMAX 427*51782e3aSKonstantin Belousovin case not all functions are required. The individual prototype macros expect 428*51782e3aSKonstantin Belousov.Fa NAME , 429*51782e3aSKonstantin Belousov.Fa TYPE , 430*51782e3aSKonstantin Belousovand 431*51782e3aSKonstantin Belousov.Fa ATTR 432*51782e3aSKonstantin Belousovarguments. The 433*51782e3aSKonstantin Belousov.Fa ATTR 434*51782e3aSKonstantin Belousovargument must be empty for global functions or 435*51782e3aSKonstantin Belousov.Fa static 436*51782e3aSKonstantin Belousovfor static functions. 43787f5f0ecSDag-Erling Smørgrav.Pp 43887f5f0ecSDag-Erling SmørgravThe function bodies are generated with the 43987f5f0ecSDag-Erling Smørgrav.Fn RB_GENERATE 440d72cd779SJason Evansor 441d72cd779SJason Evans.Fn RB_GENERATE_STATIC 442480565d5SRuslan Ermilovmacro. 443d72cd779SJason EvansThese macros take the same arguments as the 44487f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE 445d72cd779SJason Evansand 446d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC 447d72cd779SJason Evansmacros, but should be used only once. 448*51782e3aSKonstantin BelousovAs an alternative individual function bodies are generated with the 449*51782e3aSKonstantin Belousov.Fn RB_GENERATE_INSERT , 450*51782e3aSKonstantin Belousov.Fn RB_GENERATE_INSERT_COLOR , 451*51782e3aSKonstantin Belousov.Fn RB_GENERATE_REMOVE , 452*51782e3aSKonstantin Belousov.Fn RB_GENERATE_REMOVE_COLOR , 453*51782e3aSKonstantin Belousov.Fn RB_GENERATE_FIND , 454*51782e3aSKonstantin Belousov.Fn RB_GENERATE_NFIND , 455*51782e3aSKonstantin Belousov.Fn RB_GENERATE_NEXT , 456*51782e3aSKonstantin Belousov.Fn RB_GENERATE_PREV , 457*51782e3aSKonstantin Belousovand 458*51782e3aSKonstantin Belousov.Fn RB_GENERATE_MINMAX 459*51782e3aSKonstantin Belousovmacros. 46087f5f0ecSDag-Erling Smørgrav.Pp 46187f5f0ecSDag-Erling SmørgravFinally, 46287f5f0ecSDag-Erling Smørgravthe 46387f5f0ecSDag-Erling Smørgrav.Fa CMP 4649d44cd42SBenno Riceargument is the name of a function used to compare tree nodes 465480565d5SRuslan Ermilovwith each other. 466480565d5SRuslan ErmilovThe function takes two arguments of type 467480565d5SRuslan Ermilov.Vt "struct TYPE *" . 46887f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a 469480565d5SRuslan Ermilovvalue smaller than zero. 470480565d5SRuslan ErmilovIf they are equal, the function returns zero. 471480565d5SRuslan ErmilovOtherwise, it should return a value greater than zero. 472480565d5SRuslan ErmilovThe compare 47387f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements. 47487f5f0ecSDag-Erling Smørgrav.Pp 47587f5f0ecSDag-Erling SmørgravThe 47687f5f0ecSDag-Erling Smørgrav.Fn RB_INIT 47787f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by 47887f5f0ecSDag-Erling Smørgrav.Fa head . 47987f5f0ecSDag-Erling Smørgrav.Pp 4803b96c71fSMike PritchardThe red-black tree can also be initialized statically by using the 48187f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER 48287f5f0ecSDag-Erling Smørgravmacro like this: 483480565d5SRuslan Ermilov.Bd -ragged -offset indent 484480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE 485480565d5SRuslan Ermilov.Va head 486480565d5SRuslan Ermilov= 487480565d5SRuslan Ermilov.Fn RB_INITIALIZER &head ; 48887f5f0ecSDag-Erling Smørgrav.Ed 48987f5f0ecSDag-Erling Smørgrav.Pp 49087f5f0ecSDag-Erling SmørgravThe 49187f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT 49287f5f0ecSDag-Erling Smørgravmacro inserts the new element 49387f5f0ecSDag-Erling Smørgrav.Fa elm 49487f5f0ecSDag-Erling Smørgravinto the tree. 49587f5f0ecSDag-Erling Smørgrav.Pp 49687f5f0ecSDag-Erling SmørgravThe 49787f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE 49887f5f0ecSDag-Erling Smørgravmacro removes the element 49987f5f0ecSDag-Erling Smørgrav.Fa elm 50087f5f0ecSDag-Erling Smørgravfrom the tree pointed by 50187f5f0ecSDag-Erling Smørgrav.Fa head . 50287f5f0ecSDag-Erling Smørgrav.Pp 50387f5f0ecSDag-Erling SmørgravThe 50487f5f0ecSDag-Erling Smørgrav.Fn RB_FIND 50506115e08SJason Evansand 50606115e08SJason Evans.Fn RB_NFIND 50706115e08SJason Evansmacros can be used to find a particular element in the tree. 50887f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent 50987f5f0ecSDag-Erling Smørgravstruct TYPE find, *res; 51087f5f0ecSDag-Erling Smørgravfind.key = 30; 51187f5f0ecSDag-Erling Smørgravres = RB_FIND(NAME, head, &find); 51287f5f0ecSDag-Erling Smørgrav.Ed 51387f5f0ecSDag-Erling Smørgrav.Pp 51487f5f0ecSDag-Erling SmørgravThe 51587f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT , 51687f5f0ecSDag-Erling Smørgrav.Fn RB_MIN , 51787f5f0ecSDag-Erling Smørgrav.Fn RB_MAX , 5188e4fd0a1SJason Evans.Fn RB_NEXT , 51987f5f0ecSDag-Erling Smørgravand 5208e4fd0a1SJason Evans.Fn RB_PREV 52187f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree: 522480565d5SRuslan Ermilov.Pp 523480565d5SRuslan Ermilov.Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))" 52487f5f0ecSDag-Erling Smørgrav.Pp 52587f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the 52687f5f0ecSDag-Erling Smørgrav.Fn RB_FOREACH 5278e4fd0a1SJason Evansor 5288e4fd0a1SJason Evans.Fn RB_FOREACH_REVERSE 52987f5f0ecSDag-Erling Smørgravmacro: 530480565d5SRuslan Ermilov.Bd -ragged -offset indent 531480565d5SRuslan Ermilov.Fn RB_FOREACH np NAME head 53287f5f0ecSDag-Erling Smørgrav.Ed 53387f5f0ecSDag-Erling Smørgrav.Pp 5349dbae282SGleb SmirnoffThe macros 5359dbae282SGleb Smirnoff.Fn RB_FOREACH_SAFE 5369dbae282SGleb Smirnoffand 5379dbae282SGleb Smirnoff.Fn RB_FOREACH_REVERSE_SAFE 5389dbae282SGleb Smirnofftraverse the tree referenced by head 5399dbae282SGleb Smirnoffin a forward or reverse direction respectively, 5409dbae282SGleb Smirnoffassigning each element in turn to np. 5419dbae282SGleb SmirnoffHowever, unlike their unsafe counterparts, 5429dbae282SGleb Smirnoffthey permit both the removal of np 5439dbae282SGleb Smirnoffas well as freeing it from within the loop safely 5449dbae282SGleb Smirnoffwithout interfering with the traversal. 5459dbae282SGleb Smirnoff.Pp 546bff27689SBruce M SimpsonBoth 547bff27689SBruce M Simpson.Fn RB_FOREACH_FROM 548bff27689SBruce M Simpsonand 549bff27689SBruce M Simpson.Fn RB_FOREACH_REVERSE_FROM 550bff27689SBruce M Simpsonmay be used to continue an interrupted traversal 551bff27689SBruce M Simpsonin a forward or reverse direction respectively. 552639bf7bdSBruce M SimpsonThe head pointer is not required. 553639bf7bdSBruce M SimpsonThe pointer to the node from where to resume the traversal 554639bf7bdSBruce M Simpsonshould be passed as their last argument, 555bff27689SBruce M Simpsonand will be overwritten to provide safe traversal. 556bff27689SBruce M Simpson.Pp 55787f5f0ecSDag-Erling SmørgravThe 55887f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY 559309e4b9bSDag-Erling Smørgravmacro should be used to check whether a red-black tree is empty. 56087f5f0ecSDag-Erling Smørgrav.Sh NOTES 56187f5f0ecSDag-Erling SmørgravTrying to free a tree in the following way is a common error: 56287f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent 56387f5f0ecSDag-Erling SmørgravSPLAY_FOREACH(var, NAME, head) { 56487f5f0ecSDag-Erling Smørgrav SPLAY_REMOVE(NAME, head, var); 56587f5f0ecSDag-Erling Smørgrav free(var); 56687f5f0ecSDag-Erling Smørgrav} 56787f5f0ecSDag-Erling Smørgravfree(head); 56887f5f0ecSDag-Erling Smørgrav.Ed 56987f5f0ecSDag-Erling Smørgrav.Pp 57087f5f0ecSDag-Erling SmørgravSince 57187f5f0ecSDag-Erling Smørgrav.Va var 572480565d5SRuslan Ermilovis freed, the 57387f5f0ecSDag-Erling Smørgrav.Fn FOREACH 57487f5f0ecSDag-Erling Smørgravmacro refers to a pointer that may have been reallocated already. 57587f5f0ecSDag-Erling SmørgravProper code needs a second variable. 57687f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent 57787f5f0ecSDag-Erling Smørgravfor (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) { 57887f5f0ecSDag-Erling Smørgrav nxt = SPLAY_NEXT(NAME, head, var); 57987f5f0ecSDag-Erling Smørgrav SPLAY_REMOVE(NAME, head, var); 58087f5f0ecSDag-Erling Smørgrav free(var); 58187f5f0ecSDag-Erling Smørgrav} 58287f5f0ecSDag-Erling Smørgrav.Ed 58387f5f0ecSDag-Erling Smørgrav.Pp 58487f5f0ecSDag-Erling SmørgravBoth 58587f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT 58687f5f0ecSDag-Erling Smørgravand 58787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT 58887f5f0ecSDag-Erling Smørgravreturn 589480565d5SRuslan Ermilov.Dv NULL 59087f5f0ecSDag-Erling Smørgravif the element was inserted in the tree successfully, otherwise they 59187f5f0ecSDag-Erling Smørgravreturn a pointer to the element with the colliding key. 59287f5f0ecSDag-Erling Smørgrav.Pp 59387f5f0ecSDag-Erling SmørgravAccordingly, 59487f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE 59587f5f0ecSDag-Erling Smørgravand 59687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE 59787f5f0ecSDag-Erling Smørgravreturn the pointer to the removed element otherwise they return 598480565d5SRuslan Ermilov.Dv NULL 59987f5f0ecSDag-Erling Smørgravto indicate an error. 600b9ec8f3bSSimon L. B. Nielsen.Sh SEE ALSO 601b9ec8f3bSSimon L. B. Nielsen.Xr queue 3 60287f5f0ecSDag-Erling Smørgrav.Sh AUTHORS 603480565d5SRuslan ErmilovThe author of the tree macros is 604480565d5SRuslan Ermilov.An Niels Provos . 605