VirtualBox

source: kStuff/trunk/include/k/kAvlTmpl/kAvlDoWithAll.h@ 7

Last change on this file since 7 was 7, checked in by bird, 17 years ago

kAVL: Implemented locking, root node and a direct cache.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.5 KB
Line 
1/* $Id: kAvlDoWithAll.h 7 2008-02-04 02:08:02Z bird $ */
2/** @file
3 * kAvlTmpl - Templated AVL Trees, The Callback Iterator.
4 */
5
6/*
7 * Copyright (c) 1999-2007 knut st. osmundsen <[email protected]>
8 *
9 * This file is part of kStuff.
10 *
11 * kStuff is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * kStuff is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with kStuff; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 *
26 * As a special exception, since this is a source file and not a header
27 * file, you are granted permission to #include this file as you wish
28 * without this in itself causing the resulting program or whatever to be
29 * covered by the LGPL license. This exception does not however invalidate
30 * any other reasons why the resulting program/whatever should not be
31 * covered the LGPL or GPL.
32 */
33
34/*******************************************************************************
35* Structures and Typedefs *
36*******************************************************************************/
37/**
38 * Stack used by DoWithAll to avoid recusive function calls.
39 */
40typedef struct
41{
42 unsigned cEntries;
43 KAVLNODE *aEntries[KAVL_MAX_STACK];
44 char achFlags[KAVL_MAX_STACK];
45 KAVLROOT pRoot;
46} KAVL_INT(STACK2);
47
48
49/**
50 * Iterates thru all nodes in the given tree.
51 *
52 * @returns 0 on success. Return from callback on failure.
53 * @param pRoot Pointer to the AVL-tree root structure.
54 * @param fFromLeft K_TRUE: Left to right.
55 * K_FALSE: Right to left.
56 * @param pfnCallBack Pointer to callback function.
57 * @param pvUser User parameter passed on to the callback function.
58 */
59KAVL_DECL(int) KAVL_FN(DoWithAll)(KAVLROOT *pRoot, KBOOL fFromLeft, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
60{
61 KAVL_INT(STACK2) AVLStack;
62 KAVLNODE *pNode;
63#ifdef KAVL_EQUAL_ALLOWED
64 KAVLNODE *pEqual;
65#endif
66 int rc;
67
68 KAVL_READ_LOCK(pRoot);
69 if (pRoot->mpRoot == KAVL_NULL)
70 {
71 KAVL_READ_UNLOCK(pRoot);
72 return 0;
73 }
74
75 AVLStack.cEntries = 1;
76 AVLStack.achFlags[0] = 0;
77 AVLStack.aEntries[0] = KAVL_GET_POINTER(&pRoot->mpRoot);
78
79 if (fFromLeft)
80 { /* from left */
81 while (AVLStack.cEntries > 0)
82 {
83 pNode = AVLStack.aEntries[AVLStack.cEntries - 1];
84
85 /* left */
86 if (!AVLStack.achFlags[AVLStack.cEntries - 1]++)
87 {
88 if (pNode->mpLeft != KAVL_NULL)
89 {
90 AVLStack.achFlags[AVLStack.cEntries] = 0; /* 0 first, 1 last */
91 AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
92 continue;
93 }
94 }
95
96 /* center */
97 rc = pfnCallBack(pNode, pvUser);
98 if (rc)
99 return rc;
100#ifdef KAVL_EQUAL_ALLOWED
101 if (pNode->mpList != KAVL_NULL)
102 for (pEqual = KAVL_GET_POINTER(&pNode->mpList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->mpList))
103 {
104 rc = pfnCallBack(pEqual, pvUser);
105 if (rc)
106 {
107 KAVL_READ_UNLOCK(pRoot);
108 return rc;
109 }
110 }
111#endif
112
113 /* right */
114 AVLStack.cEntries--;
115 if (pNode->mpRight != KAVL_NULL)
116 {
117 AVLStack.achFlags[AVLStack.cEntries] = 0;
118 AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
119 }
120 } /* while */
121 }
122 else
123 { /* from right */
124 while (AVLStack.cEntries > 0)
125 {
126 pNode = AVLStack.aEntries[AVLStack.cEntries - 1];
127
128 /* right */
129 if (!AVLStack.achFlags[AVLStack.cEntries - 1]++)
130 {
131 if (pNode->mpRight != KAVL_NULL)
132 {
133 AVLStack.achFlags[AVLStack.cEntries] = 0; /* 0 first, 1 last */
134 AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
135 continue;
136 }
137 }
138
139 /* center */
140 rc = pfnCallBack(pNode, pvUser);
141 if (rc)
142 return rc;
143#ifdef KAVL_EQUAL_ALLOWED
144 if (pNode->mpList != KAVL_NULL)
145 for (pEqual = KAVL_GET_POINTER(&pNode->mpList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->pList))
146 {
147 rc = pfnCallBack(pEqual, pvUser);
148 if (rc)
149 {
150 KAVL_READ_UNLOCK(pRoot);
151 return rc;
152 }
153 }
154#endif
155
156 /* left */
157 AVLStack.cEntries--;
158 if (pNode->mpLeft != KAVL_NULL)
159 {
160 AVLStack.achFlags[AVLStack.cEntries] = 0;
161 AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
162 }
163 } /* while */
164 }
165
166 KAVL_READ_UNLOCK(pRoot);
167 return 0;
168}
169
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