VirtualBox

source: kStuff/trunk/include/k/kAvlTmpl/kAvlEnum.h@ 75

Last change on this file since 75 was 29, checked in by bird, 15 years ago

Finally got around execute the switch to the MIT license.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 6.3 KB
Line 
1/* $Id: kAvlEnum.h 29 2009-07-01 20:30:29Z bird $ */
2/** @file
3 * kAvlTmpl - Templated AVL Trees, Node Enumeration.
4 */
5
6/*
7 * Copyright (c) 1999-2009 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31/*******************************************************************************
32* Structures and Typedefs *
33*******************************************************************************/
34/**
35 * Enumeration control data.
36 *
37 * This is initialized by BeginEnum and used by GetNext to figure out what
38 * to do next.
39 */
40typedef struct KAVL_TYPE(,ENUMDATA)
41{
42 KBOOL fFromLeft;
43 KI8 cEntries;
44 KU8 achFlags[KAVL_MAX_STACK];
45 KAVLNODE * aEntries[KAVL_MAX_STACK];
46} KAVL_TYPE(,ENUMDATA), *KAVL_TYPE(P,ENUMDATA);
47
48
49/**
50 * Ends an enumeration.
51 *
52 * The purpose of this function is to unlock the tree should the
53 * AVL implementation include locking. It's good practice to call
54 * it anyway even if the tree doesn't do any locking.
55 *
56 * @param pEnumData Pointer to enumeration control data.
57 */
58KAVL_DECL(void) KAVL_FN(EndEnum)(KAVL_TYPE(,ENUMDATA) *pEnumData)
59{
60 KAVLROOT pRoot = pEnumData->pRoot;
61 pEnumData->pRoot = NULL;
62 if (pRoot)
63 KAVL_READ_UNLOCK(pEnumData->pRoot);
64}
65
66
67/**
68 * Get the next node in the tree enumeration.
69 *
70 * The current implementation of this function willl not walk the mpList
71 * chain like the DoWithAll function does. This may be changed later.
72 *
73 * @returns Pointer to the next node in the tree.
74 * NULL is returned when the end of the tree has been reached,
75 * it is not necessary to call EndEnum in this case.
76 * @param pEnumData Pointer to enumeration control data.
77 */
78KAVL_DECL(KAVLNODE *) KAVL_FN(GetNext)(KAVL_TYPE(,ENUMDATA) *pEnumData)
79{
80 if (pEnumData->fFromLeft)
81 { /* from left */
82 while (pEnumData->cEntries > 0)
83 {
84 KAVLNODE *pNode = pEnumData->aEntries[pEnumData->cEntries - 1];
85
86 /* left */
87 if (pEnumData->achFlags[pEnumData->cEntries - 1] == 0)
88 {
89 pEnumData->achFlags[pEnumData->cEntries - 1]++;
90 if (pNode->mpLeft != KAVL_NULL)
91 {
92 pEnumData->achFlags[pEnumData->cEntries] = 0; /* 0 left, 1 center, 2 right */
93 pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
94 continue;
95 }
96 }
97
98 /* center */
99 if (pEnumData->achFlags[pEnumData->cEntries - 1] == 1)
100 {
101 pEnumData->achFlags[pEnumData->cEntries - 1]++;
102 return pNode;
103 }
104
105 /* right */
106 pEnumData->cEntries--;
107 if (pNode->mpRight != KAVL_NULL)
108 {
109 pEnumData->achFlags[pEnumData->cEntries] = 0;
110 pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
111 }
112 } /* while */
113 }
114 else
115 { /* from right */
116 while (pEnumData->cEntries > 0)
117 {
118 KAVLNODE *pNode = pEnumData->aEntries[pEnumData->cEntries - 1];
119
120 /* right */
121 if (pEnumData->achFlags[pEnumData->cEntries - 1] == 0)
122 {
123 pEnumData->achFlags[pEnumData->cEntries - 1]++;
124 if (pNode->mpRight != KAVL_NULL)
125 {
126 pEnumData->achFlags[pEnumData->cEntries] = 0; /* 0 right, 1 center, 2 left */
127 pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
128 continue;
129 }
130 }
131
132 /* center */
133 if (pEnumData->achFlags[pEnumData->cEntries - 1] == 1)
134 {
135 pEnumData->achFlags[pEnumData->cEntries - 1]++;
136 return pNode;
137 }
138
139 /* left */
140 pEnumData->cEntries--;
141 if (pNode->mpLeft != KAVL_NULL)
142 {
143 pEnumData->achFlags[pEnumData->cEntries] = 0;
144 pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
145 }
146 } /* while */
147 }
148
149 /*
150 * Call EndEnum.
151 */
152 KAVL_FN(EndEnum)(pEnumData);
153 return NULL;
154}
155
156
157/**
158 * Starts an enumeration of all nodes in the given AVL tree.
159 *
160 * The current implementation of this function will not walk the mpList
161 * chain like the DoWithAll function does. This may be changed later.
162 *
163 * @returns Pointer to the first node in the enumeration.
164 * If NULL is returned the tree is empty calling EndEnum isn't
165 * strictly necessary (although it will do no harm).
166 * @param pRoot Pointer to the AVL-tree root structure.
167 * @param pEnumData Pointer to enumeration control data.
168 * @param fFromLeft K_TRUE: Left to right.
169 * K_FALSE: Right to left.
170 */
171KAVL_DECL(KAVLNODE *) KAVL_FN(BeginEnum)(KAVLROOT *pRoot, KAVL_TYPE(,ENUMDATA) *pEnumData, KBOOL fFromLeft)
172{
173 KAVL_READ_LOCK(pRoot);
174 pEnumData->pRoot = pRoot;
175 if (pRoot->mpRoot != KAVL_NULL)
176 {
177 pEnumData->fFromLeft = fFromLeft;
178 pEnumData->cEntries = 1;
179 pEnumData->aEntries[0] = KAVL_GET_POINTER(pRoot->mpRoot);
180 pEnumData->achFlags[0] = 0;
181 }
182 else
183 pEnumData->cEntries = 0;
184
185 return KAVL_FN(GetNext)(pEnumData);
186}
187
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette