1*fad4b12bSEdward Tomasz Napierala.\" $OpenBSD: tree.3,v 1.7 2002/06/12 01:09:20 provos Exp $ 2*fad4b12bSEdward Tomasz Napierala.\" 3*fad4b12bSEdward Tomasz Napierala.\" Copyright 2002 Niels Provos <provos@citi.umich.edu> 4*fad4b12bSEdward Tomasz Napierala.\" All rights reserved. 5*fad4b12bSEdward Tomasz Napierala.\" 6*fad4b12bSEdward Tomasz Napierala.\" Redistribution and use in source and binary forms, with or without 7*fad4b12bSEdward Tomasz Napierala.\" modification, are permitted provided that the following conditions 8*fad4b12bSEdward Tomasz Napierala.\" are met: 9*fad4b12bSEdward Tomasz Napierala.\" 1. Redistributions of source code must retain the above copyright 10*fad4b12bSEdward Tomasz Napierala.\" notice, this list of conditions and the following disclaimer. 11*fad4b12bSEdward Tomasz Napierala.\" 2. Redistributions in binary form must reproduce the above copyright 12*fad4b12bSEdward Tomasz Napierala.\" notice, this list of conditions and the following disclaimer in the 13*fad4b12bSEdward Tomasz Napierala.\" documentation and/or other materials provided with the distribution. 14*fad4b12bSEdward Tomasz Napierala.\" 3. All advertising materials mentioning features or use of this software 15*fad4b12bSEdward Tomasz Napierala.\" must display the following acknowledgement: 16*fad4b12bSEdward Tomasz Napierala.\" This product includes software developed by Niels Provos. 17*fad4b12bSEdward Tomasz Napierala.\" 4. The name of the author may not be used to endorse or promote products 18*fad4b12bSEdward Tomasz Napierala.\" derived from this software without specific prior written permission. 19*fad4b12bSEdward Tomasz Napierala.\" 20*fad4b12bSEdward Tomasz Napierala.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21*fad4b12bSEdward Tomasz Napierala.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22*fad4b12bSEdward Tomasz Napierala.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23*fad4b12bSEdward Tomasz Napierala.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24*fad4b12bSEdward Tomasz Napierala.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25*fad4b12bSEdward Tomasz Napierala.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*fad4b12bSEdward Tomasz Napierala.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*fad4b12bSEdward Tomasz Napierala.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*fad4b12bSEdward Tomasz Napierala.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29*fad4b12bSEdward Tomasz Napierala.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*fad4b12bSEdward Tomasz Napierala.\" 31*fad4b12bSEdward Tomasz Napierala.\" $FreeBSD$ 32*fad4b12bSEdward Tomasz Napierala.\" 33*fad4b12bSEdward Tomasz Napierala.Dd May 8, 2019 34*fad4b12bSEdward Tomasz Napierala.Dt ARB 3 35*fad4b12bSEdward Tomasz Napierala.Os 36*fad4b12bSEdward Tomasz Napierala.Sh NAME 37*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE , 38*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_STATIC , 39*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_INSERT , 40*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_INSERT_COLOR , 41*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_REMOVE , 42*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_REMOVE_COLOR , 43*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_FIND , 44*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_NFIND , 45*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_NEXT , 46*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_PREV , 47*fad4b12bSEdward Tomasz Napierala.Nm ARB_PROTOTYPE_MINMAX , 48*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE , 49*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_STATIC , 50*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_INSERT , 51*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_INSERT_COLOR , 52*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_REMOVE , 53*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_REMOVE_COLOR , 54*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_FIND , 55*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_NFIND , 56*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_NEXT , 57*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_PREV , 58*fad4b12bSEdward Tomasz Napierala.Nm ARB_GENERATE_MINMAX , 59*fad4b12bSEdward Tomasz Napierala.Nm ARB8_ENTRY , 60*fad4b12bSEdward Tomasz Napierala.Nm ARB16_ENTRY , 61*fad4b12bSEdward Tomasz Napierala.Nm ARB32_ENTRY , 62*fad4b12bSEdward Tomasz Napierala.Nm ARB8_HEAD , 63*fad4b12bSEdward Tomasz Napierala.Nm ARB16_HEAD , 64*fad4b12bSEdward Tomasz Napierala.Nm ARB32_HEAD , 65*fad4b12bSEdward Tomasz Napierala.Nm ARB_ALLOCSIZE , 66*fad4b12bSEdward Tomasz Napierala.Nm ARB_INITIALIZER , 67*fad4b12bSEdward Tomasz Napierala.Nm ARB_ROOT , 68*fad4b12bSEdward Tomasz Napierala.Nm ARB_EMPTY , 69*fad4b12bSEdward Tomasz Napierala.Nm ARB_FULL , 70*fad4b12bSEdward Tomasz Napierala.Nm ARB_CURNODES , 71*fad4b12bSEdward Tomasz Napierala.Nm ARB_MAXNODES , 72*fad4b12bSEdward Tomasz Napierala.Nm ARB_NEXT , 73*fad4b12bSEdward Tomasz Napierala.Nm ARB_PREV , 74*fad4b12bSEdward Tomasz Napierala.Nm ARB_MIN , 75*fad4b12bSEdward Tomasz Napierala.Nm ARB_MAX , 76*fad4b12bSEdward Tomasz Napierala.Nm ARB_FIND , 77*fad4b12bSEdward Tomasz Napierala.Nm ARB_NFIND , 78*fad4b12bSEdward Tomasz Napierala.Nm ARB_LEFT , 79*fad4b12bSEdward Tomasz Napierala.Nm ARB_LEFTIDX , 80*fad4b12bSEdward Tomasz Napierala.Nm ARB_RIGHT , 81*fad4b12bSEdward Tomasz Napierala.Nm ARB_RIGHTIDX , 82*fad4b12bSEdward Tomasz Napierala.Nm ARB_PARENT , 83*fad4b12bSEdward Tomasz Napierala.Nm ARB_PARENTIDX , 84*fad4b12bSEdward Tomasz Napierala.Nm ARB_GETFREE , 85*fad4b12bSEdward Tomasz Napierala.Nm ARB_FREEIDX , 86*fad4b12bSEdward Tomasz Napierala.Nm ARB_FOREACH , 87*fad4b12bSEdward Tomasz Napierala.Nm ARB_FOREACH_FROM , 88*fad4b12bSEdward Tomasz Napierala.Nm ARB_FOREACH_SAFE , 89*fad4b12bSEdward Tomasz Napierala.Nm ARB_FOREACH_REVERSE , 90*fad4b12bSEdward Tomasz Napierala.Nm ARB_FOREACH_REVERSE_FROM , 91*fad4b12bSEdward Tomasz Napierala.Nm ARB_FOREACH_REVERSE_SAFE , 92*fad4b12bSEdward Tomasz Napierala.Nm ARB_INIT , 93*fad4b12bSEdward Tomasz Napierala.Nm ARB_INSERT , 94*fad4b12bSEdward Tomasz Napierala.Nm ARB_REMOVE 95*fad4b12bSEdward Tomasz Napierala.Nd "array-based red-black trees" 96*fad4b12bSEdward Tomasz Napierala.Sh SYNOPSIS 97*fad4b12bSEdward Tomasz Napierala.In sys/arb.h 98*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE NAME TYPE FIELD CMP 99*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_STATIC NAME TYPE FIELD CMP 100*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_INSERT NAME TYPE ATTR 101*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_INSERT_COLOR NAME TYPE ATTR 102*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_REMOVE NAME TYPE ATTR 103*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_REMOVE_COLOR NAME TYPE ATTR 104*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_FIND NAME TYPE ATTR 105*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_NFIND NAME TYPE ATTR 106*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_NEXT NAME TYPE ATTR 107*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_PREV NAME TYPE ATTR 108*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_MINMAX NAME TYPE ATTR 109*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE NAME TYPE FIELD CMP 110*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_STATIC NAME TYPE FIELD CMP 111*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_INSERT NAME TYPE FIELD CMP ATTR 112*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_INSERT_COLOR NAME TYPE FIELD ATTR 113*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_REMOVE NAME TYPE FIELD ATTR 114*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_REMOVE_COLOR NAME TYPE FIELD ATTR 115*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_FIND NAME TYPE FIELD CMP ATTR 116*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_NFIND NAME TYPE FIELD CMP ATTR 117*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_NEXT NAME TYPE FIELD ATTR 118*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_PREV NAME TYPE FIELD ATTR 119*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_MINMAX NAME TYPE FIELD ATTR 120*fad4b12bSEdward Tomasz Napierala.Fn ARB<8|16|32>_ENTRY 121*fad4b12bSEdward Tomasz Napierala.Fn ARB<8|16|32>_HEAD HEADNAME TYPE 122*fad4b12bSEdward Tomasz Napierala.Ft "size_t" 123*fad4b12bSEdward Tomasz Napierala.Fn ARB_ALLOCSIZE "ARB_HEAD *head" "int<8|16|32>_t maxnodes" "struct TYPE *elm" 124*fad4b12bSEdward Tomasz Napierala.Fn ARB_INITIALIZER "ARB_HEAD *head" "int<8|16|32>_t maxnodes" 125*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 126*fad4b12bSEdward Tomasz Napierala.Fn ARB_ROOT "ARB_HEAD *head" 127*fad4b12bSEdward Tomasz Napierala.Ft "bool" 128*fad4b12bSEdward Tomasz Napierala.Fn ARB_EMPTY "ARB_HEAD *head" 129*fad4b12bSEdward Tomasz Napierala.Ft "bool" 130*fad4b12bSEdward Tomasz Napierala.Fn ARB_FULL "ARB_HEAD *head" 131*fad4b12bSEdward Tomasz Napierala.Ft "int<8|16|32>_t" 132*fad4b12bSEdward Tomasz Napierala.Fn ARB_CURNODES "ARB_HEAD *head" 133*fad4b12bSEdward Tomasz Napierala.Ft "int<8|16|32>_t" 134*fad4b12bSEdward Tomasz Napierala.Fn ARB_MAXNODES "ARB_HEAD *head" 135*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 136*fad4b12bSEdward Tomasz Napierala.Fn ARB_NEXT NAME "ARB_HEAD *head" "struct TYPE *elm" 137*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 138*fad4b12bSEdward Tomasz Napierala.Fn ARB_PREV NAME "ARB_HEAD *head" "struct TYPE *elm" 139*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 140*fad4b12bSEdward Tomasz Napierala.Fn ARB_MIN NAME "ARB_HEAD *head" 141*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 142*fad4b12bSEdward Tomasz Napierala.Fn ARB_MAX NAME "ARB_HEAD *head" 143*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 144*fad4b12bSEdward Tomasz Napierala.Fn ARB_FIND NAME "ARB_HEAD *head" "struct TYPE *elm" 145*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 146*fad4b12bSEdward Tomasz Napierala.Fn ARB_NFIND NAME "ARB_HEAD *head" "struct TYPE *elm" 147*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 148*fad4b12bSEdward Tomasz Napierala.Fn ARB_LEFT "struct TYPE *elm" "ARB_ENTRY NAME" 149*fad4b12bSEdward Tomasz Napierala.Ft "int<8|16|32>_t" 150*fad4b12bSEdward Tomasz Napierala.Fn ARB_LEFTIDX "struct TYPE *elm" "ARB_ENTRY NAME" 151*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 152*fad4b12bSEdward Tomasz Napierala.Fn ARB_RIGHT "struct TYPE *elm" "ARB_ENTRY NAME" 153*fad4b12bSEdward Tomasz Napierala.Ft "int<8|16|32>_t" 154*fad4b12bSEdward Tomasz Napierala.Fn ARB_RIGHTIDX "struct TYPE *elm" "ARB_ENTRY NAME" 155*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 156*fad4b12bSEdward Tomasz Napierala.Fn ARB_PARENT "struct TYPE *elm" "ARB_ENTRY NAME" 157*fad4b12bSEdward Tomasz Napierala.Ft "int<8|16|32>_t" 158*fad4b12bSEdward Tomasz Napierala.Fn ARB_PARENTIDX "struct TYPE *elm" "ARB_ENTRY NAME" 159*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 160*fad4b12bSEdward Tomasz Napierala.Fn ARB_GETFREE "ARB_HEAD *head" "FIELD" 161*fad4b12bSEdward Tomasz Napierala.Ft "int<8|16|32>_t" 162*fad4b12bSEdward Tomasz Napierala.Fn ARB_FREEIDX "ARB_HEAD *head" 163*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH VARNAME NAME "ARB_HEAD *head" 164*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_FROM "VARNAME" "NAME" "POS_VARNAME" 165*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_SAFE "VARNAME" "NAME" "ARB_HEAD *head" "TEMP_VARNAME" 166*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_REVERSE VARNAME NAME "ARB_HEAD *head" 167*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_REVERSE_FROM "VARNAME" "NAME" "POS_VARNAME" 168*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "ARB_HEAD *head" "TEMP_VARNAME" 169*fad4b12bSEdward Tomasz Napierala.Ft void 170*fad4b12bSEdward Tomasz Napierala.Fn ARB_INIT "struct TYPE *elm" "FIELD" "ARB_HEAD *head" "int<8|16|32>_t maxnodes" 171*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 172*fad4b12bSEdward Tomasz Napierala.Fn ARB_INSERT NAME "ARB_HEAD *head" "struct TYPE *elm" 173*fad4b12bSEdward Tomasz Napierala.Ft "struct TYPE *" 174*fad4b12bSEdward Tomasz Napierala.Fn ARB_REMOVE NAME "ARB_HEAD *head" "struct TYPE *elm" 175*fad4b12bSEdward Tomasz Napierala.Sh DESCRIPTION 176*fad4b12bSEdward Tomasz NapieralaThese macros define data structures for and array-based red-black trees. 177*fad4b12bSEdward Tomasz NapieralaThey use a single, continuous chunk of memory, and are useful 178*fad4b12bSEdward Tomasz Napieralae.g., when the tree needs to be transferred between userspace and kernel. 179*fad4b12bSEdward Tomasz Napierala.Pp 180*fad4b12bSEdward Tomasz NapieralaIn the macro definitions, 181*fad4b12bSEdward Tomasz Napierala.Fa TYPE 182*fad4b12bSEdward Tomasz Napieralais the name tag of a user defined structure that must contain a field of type 183*fad4b12bSEdward Tomasz Napierala.Vt ARB_ENTRY , 184*fad4b12bSEdward Tomasz Napieralanamed 185*fad4b12bSEdward Tomasz Napierala.Fa ENTRYNAME . 186*fad4b12bSEdward Tomasz NapieralaThe argument 187*fad4b12bSEdward Tomasz Napierala.Fa HEADNAME 188*fad4b12bSEdward Tomasz Napieralais the name tag of a user defined structure that must be declared 189*fad4b12bSEdward Tomasz Napieralausing the 190*fad4b12bSEdward Tomasz Napierala.Fn ARB_HEAD 191*fad4b12bSEdward Tomasz Napieralamacro. 192*fad4b12bSEdward Tomasz NapieralaThe argument 193*fad4b12bSEdward Tomasz Napierala.Fa NAME 194*fad4b12bSEdward Tomasz Napieralahas to be a unique name prefix for every tree that is defined. 195*fad4b12bSEdward Tomasz Napierala.Pp 196*fad4b12bSEdward Tomasz NapieralaThe function prototypes are declared with 197*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE , 198*fad4b12bSEdward Tomasz Napieralaor 199*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_STATIC . 200*fad4b12bSEdward Tomasz NapieralaThe function bodies are generated with 201*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE , 202*fad4b12bSEdward Tomasz Napieralaor 203*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_STATIC . 204*fad4b12bSEdward Tomasz NapieralaSee the examples below for further explanation of how these macros are used. 205*fad4b12bSEdward Tomasz Napierala.Pp 206*fad4b12bSEdward Tomasz NapieralaA red-black tree is a binary search tree with the node color as an 207*fad4b12bSEdward Tomasz Napieralaextra attribute. 208*fad4b12bSEdward Tomasz NapieralaIt fulfills a set of conditions: 209*fad4b12bSEdward Tomasz Napierala.Bl -enum -offset indent 210*fad4b12bSEdward Tomasz Napierala.It 211*fad4b12bSEdward Tomasz NapieralaEvery search path from the root to a leaf consists of the same number of 212*fad4b12bSEdward Tomasz Napieralablack nodes. 213*fad4b12bSEdward Tomasz Napierala.It 214*fad4b12bSEdward Tomasz NapieralaEach red node (except for the root) has a black parent. 215*fad4b12bSEdward Tomasz Napierala.It 216*fad4b12bSEdward Tomasz NapieralaEach leaf node is black. 217*fad4b12bSEdward Tomasz Napierala.El 218*fad4b12bSEdward Tomasz Napierala.Pp 219*fad4b12bSEdward Tomasz NapieralaEvery operation on a red-black tree is bounded as 220*fad4b12bSEdward Tomasz Napierala.Fn O "lg n" . 221*fad4b12bSEdward Tomasz NapieralaThe maximum height of a red-black tree is 222*fad4b12bSEdward Tomasz Napierala.Fn 2lg "n + 1" . 223*fad4b12bSEdward Tomasz Napierala.Pp 224*fad4b12bSEdward Tomasz Napierala.Fn ARB_* 225*fad4b12bSEdward Tomasz Napieralatrees require entries to be allocated as an array, and uses array 226*fad4b12bSEdward Tomasz Napieralaindices to link entries together. 227*fad4b12bSEdward Tomasz NapieralaThe maximum number of 228*fad4b12bSEdward Tomasz Napierala.Fn ARB_* 229*fad4b12bSEdward Tomasz Napieralatree entries is therefore constrained by the minimum of array size and choice of 230*fad4b12bSEdward Tomasz Napieralasigned integer data type used to store array indices. 231*fad4b12bSEdward Tomasz NapieralaUse 232*fad4b12bSEdward Tomasz Napierala.Fn ARB_ALLOCSIZE 233*fad4b12bSEdward Tomasz Napieralato compute the size of memory chunk to allocate. 234*fad4b12bSEdward Tomasz Napierala.Pp 235*fad4b12bSEdward Tomasz NapieralaA red-black tree is headed by a structure defined by the 236*fad4b12bSEdward Tomasz Napierala.Fn ARB_HEAD 237*fad4b12bSEdward Tomasz Napieralamacro. 238*fad4b12bSEdward Tomasz NapieralaA 239*fad4b12bSEdward Tomasz Napieralastructure is declared with either of the following: 240*fad4b12bSEdward Tomasz Napierala.Bd -ragged -offset indent 241*fad4b12bSEdward Tomasz Napierala.Fn ARB<8|16|32>_HEAD HEADNAME TYPE 242*fad4b12bSEdward Tomasz Napierala.Va head ; 243*fad4b12bSEdward Tomasz Napierala.Ed 244*fad4b12bSEdward Tomasz Napierala.Pp 245*fad4b12bSEdward Tomasz Napieralawhere 246*fad4b12bSEdward Tomasz Napierala.Fa HEADNAME 247*fad4b12bSEdward Tomasz Napieralais the name of the structure to be defined, and struct 248*fad4b12bSEdward Tomasz Napierala.Fa TYPE 249*fad4b12bSEdward Tomasz Napieralais the type of the elements to be inserted into the tree. 250*fad4b12bSEdward Tomasz Napierala.Pp 251*fad4b12bSEdward Tomasz NapieralaThe 252*fad4b12bSEdward Tomasz Napierala.Fn ARB_HEAD 253*fad4b12bSEdward Tomasz Napieralavariant includes a suffix denoting the signed integer data type size 254*fad4b12bSEdward Tomasz Napierala.Pq in bits 255*fad4b12bSEdward Tomasz Napieralaused to store array indices. 256*fad4b12bSEdward Tomasz NapieralaFor example, 257*fad4b12bSEdward Tomasz Napierala.Fn ARB_HEAD8 258*fad4b12bSEdward Tomasz Napieralacreates a red-black tree head strucutre with 8-bit signed array indices capable 259*fad4b12bSEdward Tomasz Napieralaof indexing up to 128 entries. 260*fad4b12bSEdward Tomasz Napierala.Pp 261*fad4b12bSEdward Tomasz NapieralaThe 262*fad4b12bSEdward Tomasz Napierala.Fn ARB_ENTRY 263*fad4b12bSEdward Tomasz Napieralamacro declares a structure that allows elements to be connected in the tree. 264*fad4b12bSEdward Tomasz NapieralaSimilarly to the 265*fad4b12bSEdward Tomasz Napierala.Fn ARB<8|16|32>_HEAD 266*fad4b12bSEdward Tomasz Napieralamacro, the 267*fad4b12bSEdward Tomasz Napierala.Fn ARB_ENTRY 268*fad4b12bSEdward Tomasz Napieralavariant includes a suffix denoting the signed integer data type size 269*fad4b12bSEdward Tomasz Napierala.Pq in bits 270*fad4b12bSEdward Tomasz Napieralaused to store array indices. 271*fad4b12bSEdward Tomasz NapieralaEntries should use the same number of bits as the tree head structure they will 272*fad4b12bSEdward Tomasz Napieralabe linked into. 273*fad4b12bSEdward Tomasz Napierala.Pp 274*fad4b12bSEdward Tomasz NapieralaIn order to use the functions that manipulate the tree structure, 275*fad4b12bSEdward Tomasz Napieralatheir prototypes need to be declared with the 276*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE 277*fad4b12bSEdward Tomasz Napieralaor 278*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_STATIC 279*fad4b12bSEdward Tomasz Napieralamacro, 280*fad4b12bSEdward Tomasz Napieralawhere 281*fad4b12bSEdward Tomasz Napierala.Fa NAME 282*fad4b12bSEdward Tomasz Napieralais a unique identifier for this particular tree. 283*fad4b12bSEdward Tomasz NapieralaThe 284*fad4b12bSEdward Tomasz Napierala.Fa TYPE 285*fad4b12bSEdward Tomasz Napieralaargument is the type of the structure that is being managed 286*fad4b12bSEdward Tomasz Napieralaby the tree. 287*fad4b12bSEdward Tomasz NapieralaThe 288*fad4b12bSEdward Tomasz Napierala.Fa FIELD 289*fad4b12bSEdward Tomasz Napieralaargument is the name of the element defined by 290*fad4b12bSEdward Tomasz Napierala.Fn ARB_ENTRY . 291*fad4b12bSEdward Tomasz NapieralaIndividual prototypes can be declared with 292*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_INSERT , 293*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_INSERT_COLOR , 294*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_REMOVE , 295*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_REMOVE_COLOR , 296*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_FIND , 297*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_NFIND , 298*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_NEXT , 299*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_PREV , 300*fad4b12bSEdward Tomasz Napieralaand 301*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_MINMAX 302*fad4b12bSEdward Tomasz Napieralain case not all functions are required. 303*fad4b12bSEdward Tomasz NapieralaThe individual prototype macros expect 304*fad4b12bSEdward Tomasz Napierala.Fa NAME , 305*fad4b12bSEdward Tomasz Napierala.Fa TYPE , 306*fad4b12bSEdward Tomasz Napieralaand 307*fad4b12bSEdward Tomasz Napierala.Fa ATTR 308*fad4b12bSEdward Tomasz Napieralaarguments. 309*fad4b12bSEdward Tomasz NapieralaThe 310*fad4b12bSEdward Tomasz Napierala.Fa ATTR 311*fad4b12bSEdward Tomasz Napieralaargument must be empty for global functions or 312*fad4b12bSEdward Tomasz Napierala.Fa static 313*fad4b12bSEdward Tomasz Napieralafor static functions. 314*fad4b12bSEdward Tomasz Napierala.Pp 315*fad4b12bSEdward Tomasz NapieralaThe function bodies are generated with the 316*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE 317*fad4b12bSEdward Tomasz Napieralaor 318*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_STATIC 319*fad4b12bSEdward Tomasz Napieralamacro. 320*fad4b12bSEdward Tomasz NapieralaThese macros take the same arguments as the 321*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE 322*fad4b12bSEdward Tomasz Napieralaand 323*fad4b12bSEdward Tomasz Napierala.Fn ARB_PROTOTYPE_STATIC 324*fad4b12bSEdward Tomasz Napieralamacros, but should be used only once. 325*fad4b12bSEdward Tomasz NapieralaAs an alternative individual function bodies are generated with the 326*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_INSERT , 327*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_INSERT_COLOR , 328*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_REMOVE , 329*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_REMOVE_COLOR , 330*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_FIND , 331*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_NFIND , 332*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_NEXT , 333*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_PREV , 334*fad4b12bSEdward Tomasz Napieralaand 335*fad4b12bSEdward Tomasz Napierala.Fn ARB_GENERATE_MINMAX 336*fad4b12bSEdward Tomasz Napieralamacros. 337*fad4b12bSEdward Tomasz Napierala.Pp 338*fad4b12bSEdward Tomasz NapieralaFinally, 339*fad4b12bSEdward Tomasz Napieralathe 340*fad4b12bSEdward Tomasz Napierala.Fa CMP 341*fad4b12bSEdward Tomasz Napieralaargument is the name of a function used to compare tree nodes 342*fad4b12bSEdward Tomasz Napieralawith each other. 343*fad4b12bSEdward Tomasz NapieralaThe function takes two arguments of type 344*fad4b12bSEdward Tomasz Napierala.Vt "struct TYPE *" . 345*fad4b12bSEdward Tomasz NapieralaIf the first argument is smaller than the second, the function returns a 346*fad4b12bSEdward Tomasz Napieralavalue smaller than zero. 347*fad4b12bSEdward Tomasz NapieralaIf they are equal, the function returns zero. 348*fad4b12bSEdward Tomasz NapieralaOtherwise, it should return a value greater than zero. 349*fad4b12bSEdward Tomasz NapieralaThe compare 350*fad4b12bSEdward Tomasz Napieralafunction defines the order of the tree elements. 351*fad4b12bSEdward Tomasz Napierala.Pp 352*fad4b12bSEdward Tomasz NapieralaThe 353*fad4b12bSEdward Tomasz Napierala.Fn ARB_INIT 354*fad4b12bSEdward Tomasz Napieralamacro initializes the tree referenced by 355*fad4b12bSEdward Tomasz Napierala.Fa head , 356*fad4b12bSEdward Tomasz Napieralawith the array length of 357*fad4b12bSEdward Tomasz Napierala.Fa maxnodes . 358*fad4b12bSEdward Tomasz Napierala.Pp 359*fad4b12bSEdward Tomasz NapieralaThe red-black tree can also be initialized statically by using the 360*fad4b12bSEdward Tomasz Napierala.Fn ARB_INITIALIZER 361*fad4b12bSEdward Tomasz Napieralamacro: 362*fad4b12bSEdward Tomasz Napierala.Bd -ragged -offset indent 363*fad4b12bSEdward Tomasz Napierala.Fn ARB<8|16|32>_HEAD HEADNAME TYPE 364*fad4b12bSEdward Tomasz Napierala.Va head 365*fad4b12bSEdward Tomasz Napierala= 366*fad4b12bSEdward Tomasz Napierala.Fn ARB_INITIALIZER &head maxnodes ; 367*fad4b12bSEdward Tomasz Napierala.Ed 368*fad4b12bSEdward Tomasz Napierala.Pp 369*fad4b12bSEdward Tomasz NapieralaThe 370*fad4b12bSEdward Tomasz Napierala.Fn ARB_INSERT 371*fad4b12bSEdward Tomasz Napieralamacro inserts the new element 372*fad4b12bSEdward Tomasz Napierala.Fa elm 373*fad4b12bSEdward Tomasz Napieralainto the tree. 374*fad4b12bSEdward Tomasz Napierala.Pp 375*fad4b12bSEdward Tomasz NapieralaThe 376*fad4b12bSEdward Tomasz Napierala.Fn ARB_REMOVE 377*fad4b12bSEdward Tomasz Napieralamacro removes the element 378*fad4b12bSEdward Tomasz Napierala.Fa elm 379*fad4b12bSEdward Tomasz Napieralafrom the tree pointed by 380*fad4b12bSEdward Tomasz Napierala.Fa head . 381*fad4b12bSEdward Tomasz Napierala.Pp 382*fad4b12bSEdward Tomasz NapieralaThe 383*fad4b12bSEdward Tomasz Napierala.Fn ARB_FIND 384*fad4b12bSEdward Tomasz Napieralaand 385*fad4b12bSEdward Tomasz Napierala.Fn ARB_NFIND 386*fad4b12bSEdward Tomasz Napieralamacros can be used to find a particular element in the tree. 387*fad4b12bSEdward Tomasz Napierala.Bd -literal -offset indent 388*fad4b12bSEdward Tomasz Napieralastruct TYPE find, *res; 389*fad4b12bSEdward Tomasz Napieralafind.key = 30; 390*fad4b12bSEdward Tomasz Napieralares = RB_FIND(NAME, head, &find); 391*fad4b12bSEdward Tomasz Napierala.Ed 392*fad4b12bSEdward Tomasz Napierala.Pp 393*fad4b12bSEdward Tomasz NapieralaThe 394*fad4b12bSEdward Tomasz Napierala.Fn ARB_ROOT , 395*fad4b12bSEdward Tomasz Napierala.Fn ARB_MIN , 396*fad4b12bSEdward Tomasz Napierala.Fn ARB_MAX , 397*fad4b12bSEdward Tomasz Napierala.Fn ARB_NEXT , 398*fad4b12bSEdward Tomasz Napieralaand 399*fad4b12bSEdward Tomasz Napierala.Fn ARB_PREV 400*fad4b12bSEdward Tomasz Napieralamacros can be used to traverse the tree: 401*fad4b12bSEdward Tomasz Napierala.Pp 402*fad4b12bSEdward Tomasz Napierala.Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))" 403*fad4b12bSEdward Tomasz Napierala.Pp 404*fad4b12bSEdward Tomasz NapieralaOr, for simplicity, one can use the 405*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH 406*fad4b12bSEdward Tomasz Napieralaor 407*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_REVERSE 408*fad4b12bSEdward Tomasz Napieralamacro: 409*fad4b12bSEdward Tomasz Napierala.Bd -ragged -offset indent 410*fad4b12bSEdward Tomasz Napierala.Fn RB_FOREACH np NAME head 411*fad4b12bSEdward Tomasz Napierala.Ed 412*fad4b12bSEdward Tomasz Napierala.Pp 413*fad4b12bSEdward Tomasz NapieralaThe macros 414*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_SAFE 415*fad4b12bSEdward Tomasz Napieralaand 416*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_REVERSE_SAFE 417*fad4b12bSEdward Tomasz Napieralatraverse the tree referenced by head 418*fad4b12bSEdward Tomasz Napieralain a forward or reverse direction respectively, 419*fad4b12bSEdward Tomasz Napieralaassigning each element in turn to np. 420*fad4b12bSEdward Tomasz NapieralaHowever, unlike their unsafe counterparts, 421*fad4b12bSEdward Tomasz Napieralathey permit both the removal of np 422*fad4b12bSEdward Tomasz Napieralaas well as freeing it from within the loop safely 423*fad4b12bSEdward Tomasz Napieralawithout interfering with the traversal. 424*fad4b12bSEdward Tomasz Napierala.Pp 425*fad4b12bSEdward Tomasz NapieralaBoth 426*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_FROM 427*fad4b12bSEdward Tomasz Napieralaand 428*fad4b12bSEdward Tomasz Napierala.Fn ARB_FOREACH_REVERSE_FROM 429*fad4b12bSEdward Tomasz Napieralamay be used to continue an interrupted traversal 430*fad4b12bSEdward Tomasz Napieralain a forward or reverse direction respectively. 431*fad4b12bSEdward Tomasz NapieralaThe head pointer is not required. 432*fad4b12bSEdward Tomasz NapieralaThe pointer to the node from where to resume the traversal 433*fad4b12bSEdward Tomasz Napieralashould be passed as their last argument, 434*fad4b12bSEdward Tomasz Napieralaand will be overwritten to provide safe traversal. 435*fad4b12bSEdward Tomasz Napierala.Pp 436*fad4b12bSEdward Tomasz NapieralaThe 437*fad4b12bSEdward Tomasz Napierala.Fn ARB_EMPTY 438*fad4b12bSEdward Tomasz Napieralamacro should be used to check whether a red-black tree is empty. 439*fad4b12bSEdward Tomasz Napierala.Pp 440*fad4b12bSEdward Tomasz NapieralaGiven that ARB trees have an intrinsic upper bound on the number of entries, 441*fad4b12bSEdward Tomasz Napieralasome ARB-specific additional macros are defined. 442*fad4b12bSEdward Tomasz NapieralaThe 443*fad4b12bSEdward Tomasz Napierala.Fn ARB_FULL 444*fad4b12bSEdward Tomasz Napieralamacro returns a boolean indicating whether the current number of tree entries 445*fad4b12bSEdward Tomasz Napieralaequals the tree's maximum. 446*fad4b12bSEdward Tomasz NapieralaThe 447*fad4b12bSEdward Tomasz Napierala.Fn ARB_CURNODES 448*fad4b12bSEdward Tomasz Napieralaand 449*fad4b12bSEdward Tomasz Napierala.Fn ARB_MAXNODES 450*fad4b12bSEdward Tomasz Napieralamacros return the current and maximum number of entries respectively. 451*fad4b12bSEdward Tomasz NapieralaThe 452*fad4b12bSEdward Tomasz Napierala.Fn ARB_GETFREE 453*fad4b12bSEdward Tomasz Napieralamacro returns a pointer to the next free entry in the array of entries, ready to 454*fad4b12bSEdward Tomasz Napieralabe linked into the tree. 455*fad4b12bSEdward Tomasz NapieralaThe 456*fad4b12bSEdward Tomasz Napierala.Fn ARB_INSERT 457*fad4b12bSEdward Tomasz Napieralareturns 458*fad4b12bSEdward Tomasz Napierala.Dv NULL 459*fad4b12bSEdward Tomasz Napieralaif the element was inserted in the tree successfully, otherwise they 460*fad4b12bSEdward Tomasz Napieralareturn a pointer to the element with the colliding key. 461*fad4b12bSEdward Tomasz Napierala.Pp 462*fad4b12bSEdward Tomasz NapieralaAccordingly, 463*fad4b12bSEdward Tomasz Napierala.Fn ARB_REMOVE 464*fad4b12bSEdward Tomasz Napieralareturns the pointer to the removed element otherwise they return 465*fad4b12bSEdward Tomasz Napierala.Dv NULL 466*fad4b12bSEdward Tomasz Napieralato indicate an error. 467*fad4b12bSEdward Tomasz Napierala.Sh SEE ALSO 468*fad4b12bSEdward Tomasz Napierala.Xr queue 3 , 469*fad4b12bSEdward Tomasz Napierala.Xr tree 3 470*fad4b12bSEdward Tomasz Napierala.Sh HISTORY 471*fad4b12bSEdward Tomasz NapieralaThe 472*fad4b12bSEdward Tomasz Napierala.Nm ARB 473*fad4b12bSEdward Tomasz Napieralamacros first appeared in 474*fad4b12bSEdward Tomasz Napierala.Fx 13.0 . 475*fad4b12bSEdward Tomasz Napierala.Sh AUTHORS 476*fad4b12bSEdward Tomasz NapieralaThe 477*fad4b12bSEdward Tomasz Napierala.Nm ARB 478*fad4b12bSEdward Tomasz Napieralamacros were implemented by 479*fad4b12bSEdward Tomasz Napierala.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org , 480*fad4b12bSEdward Tomasz Napieralabased on 481*fad4b12bSEdward Tomasz Napierala.Xr tree 3 482*fad4b12bSEdward Tomasz Napieralamacros written by 483*fad4b12bSEdward Tomasz Napierala.An Niels Provos . 484