1fa9922c2SRobert Mustacchi.\" 2fa9922c2SRobert Mustacchi.\" This file and its contents are supplied under the terms of the 3fa9922c2SRobert Mustacchi.\" Common Development and Distribution License ("CDDL"), version 1.0. 4fa9922c2SRobert Mustacchi.\" You may only use this file in accordance with the terms of version 5fa9922c2SRobert Mustacchi.\" 1.0 of the CDDL. 6fa9922c2SRobert Mustacchi.\" 7fa9922c2SRobert Mustacchi.\" A full copy of the text of the CDDL should have accompanied this 8fa9922c2SRobert Mustacchi.\" source. A copy of the CDDL is also available via the Internet at 9fa9922c2SRobert Mustacchi.\" http://www.illumos.org/license/CDDL. 10fa9922c2SRobert Mustacchi.\" 11fa9922c2SRobert Mustacchi.\" 12fa9922c2SRobert Mustacchi.\" Copyright 2015 Joyent, Inc. 13*7a87437fSAndy Fiddaman.\" Copyright 2024 Oxide Computer Company 14fa9922c2SRobert Mustacchi.\" 15*7a87437fSAndy Fiddaman.Dd January 27, 2024 16fa9922c2SRobert Mustacchi.Dt LIBAVL 3LIB 17fa9922c2SRobert Mustacchi.Os 18fa9922c2SRobert Mustacchi.Sh NAME 19fa9922c2SRobert Mustacchi.Nm libavl 20fa9922c2SRobert Mustacchi.Nd generic self-balancing binary search tree library 21fa9922c2SRobert Mustacchi.Sh SYNOPSIS 22fa9922c2SRobert Mustacchi.Lb libavl 23fa9922c2SRobert Mustacchi.In sys/avl.h 24fa9922c2SRobert Mustacchi.Sh DESCRIPTION 25fa9922c2SRobert MustacchiThe 26fa9922c2SRobert Mustacchi.Nm 27fa9922c2SRobert Mustacchilibrary provides a generic implementation of AVL trees, a form of 2872d3dbb9SYuri Pankovself-balancing binary tree. 2972d3dbb9SYuri PankovThe interfaces provided allow for an efficient way of implementing an ordered 3072d3dbb9SYuri Pankovset of data structures and, due to its embeddable nature, allow for a single 3172d3dbb9SYuri Pankovinstance of a data structure to belong to multiple AVL trees. 32fa9922c2SRobert Mustacchi.Lp 33fa9922c2SRobert MustacchiEach AVL tree contains entries of a single type of data structure. 34fa9922c2SRobert MustacchiRather than allocating memory for pointers for those data structures, 35fa9922c2SRobert Mustacchithe storage for the tree is embedded into the data structures by 36fa9922c2SRobert Mustacchideclaring a member of type 37fa9922c2SRobert Mustacchi.Vt avl_node_t . 38fa9922c2SRobert MustacchiWhen an AVL tree is created, through the use of 39fa9922c2SRobert Mustacchi.Fn avl_create , 40fa9922c2SRobert Mustacchiit encodes the size of the data structure, the offset of the data 41fa9922c2SRobert Mustacchistructure, and a comparator function which is used to compare two 4272d3dbb9SYuri Pankovinstances of a data structure. 4372d3dbb9SYuri PankovA data structure may be a member of multiple AVL trees by creating AVL trees 4472d3dbb9SYuri Pankovwhich use different offsets (different members) into the data structure. 45fa9922c2SRobert Mustacchi.Lp 46fa9922c2SRobert MustacchiAVL trees support both look up of an arbitrary item and ordered 4772d3dbb9SYuri Pankoviteration over the contents of the entire tree. 4872d3dbb9SYuri PankovIn addition, from any node, you can find the previous and next entries in the 4972d3dbb9SYuri Pankovtree, if they exist. 5072d3dbb9SYuri PankovIn addition, AVL trees support arbitrary insertion and deletion. 51fa9922c2SRobert Mustacchi.Ss Performance 5272d3dbb9SYuri PankovAVL trees are often used in place of linked lists. 5372d3dbb9SYuri PankovCompared to the standard, intrusive, doubly linked list, it has the following 54fa9922c2SRobert Mustacchiperformance characteristics: 55fa9922c2SRobert Mustacchi.Bl -hang -width Ds 56fa9922c2SRobert Mustacchi.It Sy Lookup One Node 57fa9922c2SRobert Mustacchi.Bd -filled -compact 58fa9922c2SRobert MustacchiLookup of a single node in a linked list is 59fa9922c2SRobert Mustacchi.Sy O(n) , 60fa9922c2SRobert Mustacchiwhereas lookup of a single node in an AVL tree is 61fa9922c2SRobert Mustacchi.Sy O(log(n)) . 62fa9922c2SRobert Mustacchi.Ed 63fa9922c2SRobert Mustacchi.It Sy Insert One Node 64fa9922c2SRobert Mustacchi.Bd -filled -compact 65fa9922c2SRobert MustacchiInserting a single node into a linked list is 66fa9922c2SRobert Mustacchi.Sy O(1) . 67fa9922c2SRobert MustacchiInserting a single node into an AVL tree is 68fa9922c2SRobert Mustacchi.Sy O(log(n)) . 69fa9922c2SRobert Mustacchi.Pp 70fa9922c2SRobert MustacchiNote, insertions into an AVL tree always result in an ordered tree. 7172d3dbb9SYuri PankovInsertions into a linked list do not guarantee order. 7272d3dbb9SYuri PankovIf order is required, then the time to do the insertion into a linked list will 7372d3dbb9SYuri Pankovdepend on the time of the search algorithm being employed to find the place to 7472d3dbb9SYuri Pankovinsert at. 75fa9922c2SRobert Mustacchi.Ed 76fa9922c2SRobert Mustacchi.It Sy Delete One Node 77fa9922c2SRobert Mustacchi.Bd -filled -compact 78fa9922c2SRobert MustacchiDeleting a single node from a linked list is 79fa9922c2SRobert Mustacchi.Sy O(1), 80fa9922c2SRobert Mustacchiwhereas deleting a single node from an AVL tree takes 81fa9922c2SRobert Mustacchi.Sy O(log(n)) 82fa9922c2SRobert Mustacchitime. 83fa9922c2SRobert Mustacchi.Ed 84fa9922c2SRobert Mustacchi.It Sy Delete All Nodes 85fa9922c2SRobert Mustacchi.Bd -filled -compact 86fa9922c2SRobert MustacchiDeleting all nodes from a linked list is 87fa9922c2SRobert Mustacchi.Sy O(n) . 88fa9922c2SRobert MustacchiWith an AVL tree, if using the 895690df7eSMohamed A. Khalfella.Xr avl_destroy_nodes 3AVL 90fa9922c2SRobert Mustacchifunction then deleting all nodes 91fa9922c2SRobert Mustacchiis 92fa9922c2SRobert Mustacchi.Sy O(n) . 93fa9922c2SRobert MustacchiHowever, if iterating over each entry in the tree and then removing it using 94fa9922c2SRobert Mustacchia while loop, 95fa9922c2SRobert Mustacchi.Xr avl_first 3AVL 96fa9922c2SRobert Mustacchiand 97fa9922c2SRobert Mustacchi.Xr avl_remove 3AVL 98fa9922c2SRobert Mustacchithen the time to remove all nodes is 99fa9922c2SRobert Mustacchi.Sy O(n\ *\ log(n)). 100fa9922c2SRobert Mustacchi.Ed 101fa9922c2SRobert Mustacchi.It Sy Visit the Next or Previous Node 102fa9922c2SRobert Mustacchi.Bd -filled -compact 103fa9922c2SRobert MustacchiVisiting the next or previous node in a linked list is 104fa9922c2SRobert Mustacchi.Sy O(1) , 105fa9922c2SRobert Mustacchiwhereas going from the next to the previous node in an AVL tree will 106fa9922c2SRobert Mustacchitake between 107fa9922c2SRobert Mustacchi.Sy O(1) 108fa9922c2SRobert Mustacchiand 109fa9922c2SRobert Mustacchi.Sy O(log(n)) . 110fa9922c2SRobert Mustacchi.Ed 111fa9922c2SRobert Mustacchi.El 112fa9922c2SRobert Mustacchi.Pp 113fa9922c2SRobert MustacchiIn general, AVL trees are a good alternative for linked lists when order 114fa9922c2SRobert Mustacchior lookup speed is important and a reasonable number of items will be 115fa9922c2SRobert Mustacchipresent. 116fa9922c2SRobert Mustacchi.Sh INTERFACES 117fa9922c2SRobert MustacchiThe shared object 118fa9922c2SRobert Mustacchi.Sy libavl.so.1 11972d3dbb9SYuri Pankovprovides the public interfaces defined below. 12072d3dbb9SYuri PankovSee 12172d3dbb9SYuri Pankov.Xr Intro 3 12272d3dbb9SYuri Pankovfor additional information on shared object interfaces. 12372d3dbb9SYuri PankovIndividual functions are documented in their own manual pages. 124fa9922c2SRobert Mustacchi.Bl -column -offset indent ".Sy avl_is_empty" ".Sy avl_destroy_nodes" 125fa9922c2SRobert Mustacchi.It Sy avl_add Ta Sy avl_create 126fa9922c2SRobert Mustacchi.It Sy avl_destroy Ta Sy avl_destroy_nodes 127fa9922c2SRobert Mustacchi.It Sy avl_find Ta Sy avl_first 128fa9922c2SRobert Mustacchi.It Sy avl_insert Ta Sy avl_insert_here 129fa9922c2SRobert Mustacchi.It Sy avl_is_empty Ta Sy avl_last 130fa9922c2SRobert Mustacchi.It Sy avl_nearest Ta Sy avl_numnodes 131fa9922c2SRobert Mustacchi.It Sy avl_remove Ta Sy avl_swap 132*7a87437fSAndy Fiddaman.It Sy avl_update Ta Sy avl_update_gt 133*7a87437fSAndy Fiddaman.It Sy avl_update_lt Ta 134fa9922c2SRobert Mustacchi.El 135fa9922c2SRobert Mustacchi.Pp 136fa9922c2SRobert MustacchiIn addition, the library defines C pre-processor macros which are 137fa9922c2SRobert Mustacchidefined below and documented in their own manual pages. 138fa9922c2SRobert Mustacchi.\" 139fa9922c2SRobert Mustacchi.\" Use the same column widths in both cases where we describe the list 140fa9922c2SRobert Mustacchi.\" of interfaces, to allow the manual page to better line up when rendered. 141fa9922c2SRobert Mustacchi.\" 142fa9922c2SRobert Mustacchi.Bl -column -offset indent ".Sy avl_is_empty" ".Sy avl_destroy_nodes" 143fa9922c2SRobert Mustacchi.It Sy AVL_NEXT Ta Sy AVL_PREV 144fa9922c2SRobert Mustacchi.El 145fa9922c2SRobert Mustacchi.Sh TYPES 146fa9922c2SRobert MustacchiThe 147fa9922c2SRobert Mustacchi.Nm 148fa9922c2SRobert Mustacchilibrary defines the following types: 149fa9922c2SRobert Mustacchi.Lp 150fa9922c2SRobert Mustacchi.Sy avl_tree_t 151fa9922c2SRobert Mustacchi.Lp 15272d3dbb9SYuri PankovType used for the root of the AVL tree. 15372d3dbb9SYuri PankovConsumers define one of these for each of the different trees that they want to 15472d3dbb9SYuri Pankovhave. 155fa9922c2SRobert Mustacchi.Lp 156fa9922c2SRobert Mustacchi.Sy avl_node_t 157fa9922c2SRobert Mustacchi.Lp 15872d3dbb9SYuri PankovType used as the data node for an AVL tree. 15972d3dbb9SYuri PankovOne of these is embedded in each data structure that is the member of an AVL 16072d3dbb9SYuri Pankovtree. 161fa9922c2SRobert Mustacchi.Lp 162fa9922c2SRobert Mustacchi.Sy avl_index_t 163fa9922c2SRobert Mustacchi.Lp 16472d3dbb9SYuri PankovType used to locate a position in a tree. 16572d3dbb9SYuri PankovThis is used with 166fa9922c2SRobert Mustacchi.Xr avl_find 3AVL 167fa9922c2SRobert Mustacchiand 168fa9922c2SRobert Mustacchi.Xr avl_insert 3AVL . 169fa9922c2SRobert Mustacchi.Sh LOCKING 170fa9922c2SRobert MustacchiThe 171fa9922c2SRobert Mustacchi.Nm 17272d3dbb9SYuri Pankovlibrary provides no locking. 17372d3dbb9SYuri PankovCallers that are using the same AVL tree from multiple threads need to provide 17472d3dbb9SYuri Pankovtheir own synchronization. 17572d3dbb9SYuri PankovIf only one thread is ever accessing or modifying the AVL tree, then there are 17672d3dbb9SYuri Pankovno synchronization concerns. 17772d3dbb9SYuri PankovIf multiple AVL trees exist, then they may all be used simultaneously; however, 17872d3dbb9SYuri Pankovthey are subject to the same rules around simultaneous access from a single 17972d3dbb9SYuri Pankovthread. 180fa9922c2SRobert Mustacchi.Lp 181fa9922c2SRobert MustacchiAll routines are both 182fa9922c2SRobert Mustacchi.Sy Fork-safe 183fa9922c2SRobert Mustacchiand 184fa9922c2SRobert Mustacchi.Sy Async-Signal-Safe . 185fa9922c2SRobert MustacchiCallers may call functions in 186fa9922c2SRobert Mustacchi.Nm 187fa9922c2SRobert Mustacchifrom a signal handler and 188fa9922c2SRobert Mustacchi.Nm 189fa9922c2SRobert Mustacchicalls are all safe in face of 190fa9922c2SRobert Mustacchi.Xr fork 2 ; 191fa9922c2SRobert Mustacchihowever, if callers have their own locks, then they must make sure that 192fa9922c2SRobert Mustacchithey are accounted for by the use of routines such as 193fa9922c2SRobert Mustacchi.Xr pthread_atfork 3C . 194fa9922c2SRobert Mustacchi.Sh EXAMPLES 195fa9922c2SRobert MustacchiThe following code shows examples of exercising all of the functionality 196fa9922c2SRobert Mustacchithat is present in 197fa9922c2SRobert Mustacchi.Nm . 198fa9922c2SRobert MustacchiIt can be compiled by using a C compiler and linking 199fa9922c2SRobert Mustacchiagainst 200fa9922c2SRobert Mustacchi.Nm . 201fa9922c2SRobert MustacchiFor example, given a file named avl.c, with gcc, one would run: 202fa9922c2SRobert Mustacchi.Bd -literal 203fa9922c2SRobert Mustacchi$ gcc -Wall -o avl avl.c -lavl 204fa9922c2SRobert Mustacchi.Ed 205fa9922c2SRobert Mustacchi.Bd -literal 206fa9922c2SRobert Mustacchi/* 207fa9922c2SRobert Mustacchi * Example of using AVL Trees 208fa9922c2SRobert Mustacchi */ 209fa9922c2SRobert Mustacchi 210fa9922c2SRobert Mustacchi#include <sys/avl.h> 211*7a87437fSAndy Fiddaman#include <assert.h> 212fa9922c2SRobert Mustacchi#include <stddef.h> 213fa9922c2SRobert Mustacchi#include <stdlib.h> 214fa9922c2SRobert Mustacchi#include <stdio.h> 215fa9922c2SRobert Mustacchi 216fa9922c2SRobert Mustacchistatic avl_tree_t inttree; 217fa9922c2SRobert Mustacchi 218fa9922c2SRobert Mustacchi/* 219fa9922c2SRobert Mustacchi * The structure that we're storing in an AVL tree. 220fa9922c2SRobert Mustacchi */ 221fa9922c2SRobert Mustacchitypedef struct intnode { 222fa9922c2SRobert Mustacchi int in_val; 223fa9922c2SRobert Mustacchi avl_node_t in_avl; 224fa9922c2SRobert Mustacchi} intnode_t; 225fa9922c2SRobert Mustacchi 226fa9922c2SRobert Mustacchistatic int 227fa9922c2SRobert Mustacchiintnode_comparator(const void *l, const void *r) 228fa9922c2SRobert Mustacchi{ 229fa9922c2SRobert Mustacchi const intnode_t *li = l; 230fa9922c2SRobert Mustacchi const intnode_t *ri = r; 231fa9922c2SRobert Mustacchi 232fa9922c2SRobert Mustacchi if (li->in_val > ri->in_val) 233fa9922c2SRobert Mustacchi return (1); 234fa9922c2SRobert Mustacchi if (li->in_val < ri->in_val) 235fa9922c2SRobert Mustacchi return (-1); 236fa9922c2SRobert Mustacchi return (0); 237fa9922c2SRobert Mustacchi} 238fa9922c2SRobert Mustacchi 239fa9922c2SRobert Mustacchi/* 240fa9922c2SRobert Mustacchi * Create an AVL Tree 241fa9922c2SRobert Mustacchi */ 242fa9922c2SRobert Mustacchistatic void 243fa9922c2SRobert Mustacchicreate_avl(void) 244fa9922c2SRobert Mustacchi{ 245fa9922c2SRobert Mustacchi avl_create(&inttree, intnode_comparator, sizeof (intnode_t), 246fa9922c2SRobert Mustacchi offsetof(intnode_t, in_avl)); 247fa9922c2SRobert Mustacchi} 248fa9922c2SRobert Mustacchi 249fa9922c2SRobert Mustacchi/* 250fa9922c2SRobert Mustacchi * Add entries to the tree with the avl_add function. 251fa9922c2SRobert Mustacchi */ 252fa9922c2SRobert Mustacchistatic void 253fa9922c2SRobert Mustacchifill_avl(void) 254fa9922c2SRobert Mustacchi{ 255fa9922c2SRobert Mustacchi int i; 256fa9922c2SRobert Mustacchi intnode_t *inp; 257fa9922c2SRobert Mustacchi 258fa9922c2SRobert Mustacchi for (i = 0; i < 20; i++) { 259fa9922c2SRobert Mustacchi inp = malloc(sizeof (intnode_t)); 260fa9922c2SRobert Mustacchi assert(inp != NULL); 261fa9922c2SRobert Mustacchi inp->in_val = i; 262fa9922c2SRobert Mustacchi avl_add(&inttree, inp); 263fa9922c2SRobert Mustacchi } 264fa9922c2SRobert Mustacchi} 265fa9922c2SRobert Mustacchi 266fa9922c2SRobert Mustacchi/* 267fa9922c2SRobert Mustacchi * Find entries in the AVL tree. Note, we create an intnode_t on the 268fa9922c2SRobert Mustacchi * stack that we use to look this up. 269fa9922c2SRobert Mustacchi */ 270fa9922c2SRobert Mustacchistatic void 271fa9922c2SRobert Mustacchifind_avl(void) 272fa9922c2SRobert Mustacchi{ 273fa9922c2SRobert Mustacchi int i; 274fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 275fa9922c2SRobert Mustacchi 276fa9922c2SRobert Mustacchi for (i = 10; i < 30; i++) { 277fa9922c2SRobert Mustacchi lookup.in_val = i; 278fa9922c2SRobert Mustacchi inp = avl_find(&inttree, &lookup, NULL); 279fa9922c2SRobert Mustacchi if (inp == NULL) { 28011994f6fSRobert Mustacchi printf("Entry %d is not in the tree\en", i); 281fa9922c2SRobert Mustacchi } else { 28211994f6fSRobert Mustacchi printf("Entry %d is in the tree\en", 283fa9922c2SRobert Mustacchi inp->in_val); 284fa9922c2SRobert Mustacchi } 285fa9922c2SRobert Mustacchi } 286fa9922c2SRobert Mustacchi} 287fa9922c2SRobert Mustacchi 288fa9922c2SRobert Mustacchi/* 289fa9922c2SRobert Mustacchi * Walk the tree forwards 290fa9922c2SRobert Mustacchi */ 291fa9922c2SRobert Mustacchistatic void 292fa9922c2SRobert Mustacchiwalk_forwards(void) 293fa9922c2SRobert Mustacchi{ 294fa9922c2SRobert Mustacchi intnode_t *inp; 295fa9922c2SRobert Mustacchi for (inp = avl_first(&inttree); inp != NULL; 296fa9922c2SRobert Mustacchi inp = AVL_NEXT(&inttree, inp)) { 29711994f6fSRobert Mustacchi printf("Found entry %d\en", inp->in_val); 298fa9922c2SRobert Mustacchi } 299fa9922c2SRobert Mustacchi} 300fa9922c2SRobert Mustacchi 301fa9922c2SRobert Mustacchi/* 302fa9922c2SRobert Mustacchi * Walk the tree backwards. 303fa9922c2SRobert Mustacchi */ 304fa9922c2SRobert Mustacchistatic void 305fa9922c2SRobert Mustacchiwalk_backwards(void) 306fa9922c2SRobert Mustacchi{ 307fa9922c2SRobert Mustacchi intnode_t *inp; 308fa9922c2SRobert Mustacchi for (inp = avl_last(&inttree); inp != NULL; 309fa9922c2SRobert Mustacchi inp = AVL_PREV(&inttree, inp)) { 31011994f6fSRobert Mustacchi printf("Found entry %d\en", inp->in_val); 311fa9922c2SRobert Mustacchi } 312fa9922c2SRobert Mustacchi} 313fa9922c2SRobert Mustacchi 314fa9922c2SRobert Mustacchi/* 315fa9922c2SRobert Mustacchi * Determine the number of nodes in the tree and if it is empty or 316fa9922c2SRobert Mustacchi * not. 317fa9922c2SRobert Mustacchi */ 318fa9922c2SRobert Mustacchistatic void 319fa9922c2SRobert Mustacchiinttree_inspect(void) 320fa9922c2SRobert Mustacchi{ 32111994f6fSRobert Mustacchi printf("The tree is %s, there are %ld nodes in it\en", 322fa9922c2SRobert Mustacchi avl_is_empty(&inttree) == B_TRUE ? "empty" : "not empty", 323fa9922c2SRobert Mustacchi avl_numnodes(&inttree)); 324fa9922c2SRobert Mustacchi} 325fa9922c2SRobert Mustacchi 326fa9922c2SRobert Mustacchi/* 327fa9922c2SRobert Mustacchi * Use avl_remove to remove entries from the tree. 328fa9922c2SRobert Mustacchi */ 329fa9922c2SRobert Mustacchistatic void 330fa9922c2SRobert Mustacchiremove_nodes(void) 331fa9922c2SRobert Mustacchi{ 332fa9922c2SRobert Mustacchi int i; 333fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 334fa9922c2SRobert Mustacchi 335fa9922c2SRobert Mustacchi for (i = 0; i < 20; i+= 4) { 336fa9922c2SRobert Mustacchi lookup.in_val = i; 337fa9922c2SRobert Mustacchi inp = avl_find(&inttree, &lookup, NULL); 338fa9922c2SRobert Mustacchi if (inp != NULL) 339fa9922c2SRobert Mustacchi avl_remove(&inttree, inp); 340fa9922c2SRobert Mustacchi } 341fa9922c2SRobert Mustacchi} 342fa9922c2SRobert Mustacchi 343fa9922c2SRobert Mustacchi/* 344fa9922c2SRobert Mustacchi * Find the nearest nodes in the tree. 345fa9922c2SRobert Mustacchi */ 346fa9922c2SRobert Mustacchistatic void 347fa9922c2SRobert Mustacchinearest_nodes(void) 348fa9922c2SRobert Mustacchi{ 349fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 350fa9922c2SRobert Mustacchi avl_index_t where; 351fa9922c2SRobert Mustacchi 352fa9922c2SRobert Mustacchi lookup.in_val = 12; 353fa9922c2SRobert Mustacchi if (avl_find(&inttree, &lookup, &where) != NULL) 354fa9922c2SRobert Mustacchi abort(); 355fa9922c2SRobert Mustacchi inp = avl_nearest(&inttree, where, AVL_BEFORE); 356fa9922c2SRobert Mustacchi assert(inp != NULL); 35711994f6fSRobert Mustacchi printf("closest node before 12 is: %d\en", inp->in_val); 358fa9922c2SRobert Mustacchi inp = avl_nearest(&inttree, where, AVL_AFTER); 359fa9922c2SRobert Mustacchi assert(inp != NULL); 36011994f6fSRobert Mustacchi printf("closest node after 12 is: %d\en", inp->in_val); 361fa9922c2SRobert Mustacchi} 362fa9922c2SRobert Mustacchi 363fa9922c2SRobert Mustacchistatic void 364fa9922c2SRobert Mustacchiinsert_avl(void) 365fa9922c2SRobert Mustacchi{ 366fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 367fa9922c2SRobert Mustacchi avl_index_t where; 368fa9922c2SRobert Mustacchi 369fa9922c2SRobert Mustacchi lookup.in_val = 12; 370fa9922c2SRobert Mustacchi if (avl_find(&inttree, &lookup, &where) != NULL) 371fa9922c2SRobert Mustacchi abort(); 372fa9922c2SRobert Mustacchi inp = malloc(sizeof (intnode_t)); 373fa9922c2SRobert Mustacchi assert(inp != NULL); 374fa9922c2SRobert Mustacchi avl_insert(&inttree, inp, where); 375fa9922c2SRobert Mustacchi} 376fa9922c2SRobert Mustacchi 377fa9922c2SRobert Mustacchistatic void 378fa9922c2SRobert Mustacchiswap_avl(void) 379fa9922c2SRobert Mustacchi{ 380fa9922c2SRobert Mustacchi avl_tree_t swap; 381fa9922c2SRobert Mustacchi 382fa9922c2SRobert Mustacchi avl_create(&swap, intnode_comparator, sizeof (intnode_t), 383fa9922c2SRobert Mustacchi offsetof(intnode_t, in_avl)); 384fa9922c2SRobert Mustacchi avl_swap(&inttree, &swap); 385fa9922c2SRobert Mustacchi inttree_inspect(); 386fa9922c2SRobert Mustacchi avl_swap(&inttree, &swap); 387fa9922c2SRobert Mustacchi inttree_inspect(); 388fa9922c2SRobert Mustacchi} 389fa9922c2SRobert Mustacchi 390*7a87437fSAndy Fiddamanstatic void 391*7a87437fSAndy Fiddamanupdate_avl(void) 392*7a87437fSAndy Fiddaman{ 393*7a87437fSAndy Fiddaman intnode_t lookup, *inp; 394*7a87437fSAndy Fiddaman avl_index_t where; 395*7a87437fSAndy Fiddaman 396*7a87437fSAndy Fiddaman lookup.in_val = 9; 397*7a87437fSAndy Fiddaman inp = avl_find(&inttree, &lookup, &where); 398*7a87437fSAndy Fiddaman assert(inp != NULL); 399*7a87437fSAndy Fiddaman inp->in_val = 25; 400*7a87437fSAndy Fiddaman avl_update(&inttree, inp); 401*7a87437fSAndy Fiddaman} 402*7a87437fSAndy Fiddaman 403fa9922c2SRobert Mustacchi/* 404fa9922c2SRobert Mustacchi * Remove all remaining nodes in the tree. We first use 405fa9922c2SRobert Mustacchi * avl_destroy_nodes to empty the tree, then avl_destroy to finish. 406fa9922c2SRobert Mustacchi */ 407fa9922c2SRobert Mustacchistatic void 408fa9922c2SRobert Mustacchicleanup(void) 409fa9922c2SRobert Mustacchi{ 410fa9922c2SRobert Mustacchi intnode_t *inp; 411fa9922c2SRobert Mustacchi void *c = NULL; 412fa9922c2SRobert Mustacchi 413fa9922c2SRobert Mustacchi while ((inp = avl_destroy_nodes(&inttree, &c)) != NULL) { 414fa9922c2SRobert Mustacchi free(inp); 415fa9922c2SRobert Mustacchi } 416fa9922c2SRobert Mustacchi avl_destroy(&inttree); 417fa9922c2SRobert Mustacchi} 418fa9922c2SRobert Mustacchi 419fa9922c2SRobert Mustacchiint 420fa9922c2SRobert Mustacchimain(void) 421fa9922c2SRobert Mustacchi{ 422fa9922c2SRobert Mustacchi create_avl(); 423fa9922c2SRobert Mustacchi inttree_inspect(); 424fa9922c2SRobert Mustacchi fill_avl(); 425fa9922c2SRobert Mustacchi find_avl(); 426fa9922c2SRobert Mustacchi walk_forwards(); 427fa9922c2SRobert Mustacchi walk_backwards(); 428fa9922c2SRobert Mustacchi inttree_inspect(); 429fa9922c2SRobert Mustacchi remove_nodes(); 430fa9922c2SRobert Mustacchi inttree_inspect(); 431fa9922c2SRobert Mustacchi nearest_nodes(); 432fa9922c2SRobert Mustacchi insert_avl(); 433fa9922c2SRobert Mustacchi inttree_inspect(); 434fa9922c2SRobert Mustacchi swap_avl(); 435*7a87437fSAndy Fiddaman update_avl(); 436fa9922c2SRobert Mustacchi cleanup(); 437fa9922c2SRobert Mustacchi return (0); 438fa9922c2SRobert Mustacchi} 439fa9922c2SRobert Mustacchi.Ed 440fa9922c2SRobert Mustacchi.Sh INTERFACE STABILITY 441fa9922c2SRobert Mustacchi.Sy Committed 442fa9922c2SRobert Mustacchi.Sh MT-Level 443fa9922c2SRobert MustacchiSee 444fa9922c2SRobert Mustacchi.Sx Locking. 445fa9922c2SRobert Mustacchi.Sh SEE ALSO 446fa9922c2SRobert Mustacchi.Xr Intro 3 , 447fa9922c2SRobert Mustacchi.Xr pthread_atfork 3C 448fa9922c2SRobert Mustacchi.Lp 449fa9922c2SRobert Mustacchi.Xr avl_add 3AVL , 450fa9922c2SRobert Mustacchi.Xr avl_create 3AVL , 451fa9922c2SRobert Mustacchi.Xr avl_destroy 3AVL , 452fa9922c2SRobert Mustacchi.Xr avl_destroy_nodes 3AVL , 453fa9922c2SRobert Mustacchi.Xr avl_find 3AVL , 454fa9922c2SRobert Mustacchi.Xr avl_first 3AVL , 455fa9922c2SRobert Mustacchi.Xr avl_insert 3AVL , 456fa9922c2SRobert Mustacchi.Xr avl_insert_here 3AVL , 457fa9922c2SRobert Mustacchi.Xr avl_is_empty 3AVL , 458fa9922c2SRobert Mustacchi.Xr avl_last 3AVL , 459fa9922c2SRobert Mustacchi.Xr avl_nearest 3AVL , 460fa9922c2SRobert Mustacchi.Xr avl_numnodes 3AVL , 461fa9922c2SRobert Mustacchi.Xr avl_remove 3AVL , 462fa9922c2SRobert Mustacchi.Xr avl_swap 3AVL , 463*7a87437fSAndy Fiddaman.Xr avl_update 3AVL , 464*7a87437fSAndy Fiddaman.Xr avl_update_gt 3AVL , 465*7a87437fSAndy Fiddaman.Xr avl_update_lt 3AVL 466fa9922c2SRobert Mustacchi.Rs 467fa9922c2SRobert Mustacchi.%A Adel'son-Vel'skiy, G. M. 468fa9922c2SRobert Mustacchi.%A Landis, Ye. M. 469fa9922c2SRobert Mustacchi.%T "An Algorithm for the Organization of Information" 470fa9922c2SRobert Mustacchi.%Q Deklady Akademii Nauk 471fa9922c2SRobert Mustacchi.%C USSR, Moscow 472fa9922c2SRobert Mustacchi.%P 263-266 473fa9922c2SRobert Mustacchi.%V Vol. 16 474fa9922c2SRobert Mustacchi.%N No. 2 475fa9922c2SRobert Mustacchi.%D 1962 476fa9922c2SRobert Mustacchi.Re 477