xref: /illumos-gate/usr/src/man/man3lib/libavl.3lib (revision 7a87437fd36d10a97e4d5952dba549b6f0fadbfc)
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