VirtualBox

source: kStuff/trunk/include/k/kAvlTmpl/kAvlRemove2.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: 4.4 KB
Line 
1/* $Id: kAvlRemove2.h 7 2008-02-04 02:08:02Z bird $ */
2/** @file
3 * kAvlTmpl - Templated AVL Trees, Remove A Specific Node.
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/**
36 * Removes the specified node from the tree.
37 *
38 * @returns Pointer to the removed node (NULL if not in the tree)
39 * @param pRoot Pointer to the AVL-tree root structure.
40 * @param Key The Key of which is to be found a best fitting match for..
41 *
42 * @remark This implementation isn't the most efficient, but this short and
43 * easier to manage.
44 */
45KAVL_DECL(KAVLNODE *) KAVL_FN(Remove2)(KAVLTROOT *pRoot, KAVLNODE *pNode)
46{
47#ifdef KAVL_EQUAL_ALLOWED
48 /*
49 * Find the right node by key and see if it's what we want.
50 */
51 KAVLNODE *pParent;
52 KAVLNODE *pCurNode = KAVL_FN(GetWithParent)(pRoot, pNode->mKey, &pParent);
53 if (!pCurNode)
54 return NULL;
55 KAVL_WRITE_LOCK(pRoot); /** @todo the locking here isn't 100% sane. The only way to archive that is by no calling worker functions. */
56 if (pCurNode != pNode)
57 {
58 /*
59 * It's not the one we want, but it could be in the duplicate list.
60 */
61 while (pCurNode->mpList != KAVL_NULL)
62 {
63 KAVLNODE *pNext = KAVL_GET_POINTER(&pCurNode->mpList);
64 if (pNext == pNode)
65 {
66 KAVL_SET_POINTER_NULL(&pCurNode->mpList, KAVL_GET_POINTER_NULL(&pNode->mpList));
67 pNode->mpList = KAVL_NULL;
68 KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
69 KAVL_WRITE_UNLOCK(pRoot);
70 return pNode;
71 }
72 pCurNode = pNext;
73 }
74 KAVL_WRITE_UNLOCK(pRoot);
75 return NULL;
76 }
77
78 /*
79 * Ok, it's the one we want alright.
80 *
81 * Simply remove it if it's the only one with they Key,
82 * if there are duplicates we'll have to unlink it and
83 * insert the first duplicate in our place.
84 */
85 if (pNode->mpList == KAVL_NODE)
86 {
87 KAVL_WRITE_UNLOCK(pRoot);
88 KAVL_FN(Remove)(pRoot, pNode->mKey);
89 }
90 else
91 {
92 KAVLNODE *pNewUs = KAVL_GET_POINTER(&pNode->mpList);
93
94 pNewUs->mHeight = pNode->mHeight;
95
96 if (pNode->mpLeft != KAVL_NULL)
97 KAVL_SET_POINTER(&pNewUs->mpLeft, KAVL_GET_POINTER(&pNode->mpLeft))
98 else
99 pNewUs->mpLeft = KAVL_NULL;
100
101 if (pNode->mpRight != KAVL_NULL)
102 KAVL_SET_POINTER(&pNewUs->mpRight, KAVL_GET_POINTER(&pNode->mpRight))
103 else
104 pNewUs->mpRight = KAVL_NULL;
105
106 if (pParent)
107 {
108 if (KAVL_GET_POINTER_NULL(&pParent->mpLeft) == pNode)
109 KAVL_SET_POINTER(&pParent->mpLeft, pNewUs);
110 else
111 KAVL_SET_POINTER(&pParent->mpRight, pNewUs);
112 }
113 else
114 KAVL_SET_POINTER(&pRoot->mpRoot, pNewUs);
115
116 KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
117 KAVL_WRITE_UNLOCK(pRoot);
118 }
119
120 return pNode;
121
122#else
123 /*
124 * Delete it, if we got the wrong one, reinsert it.
125 *
126 * This ASSUMS that the caller is NOT going to hand us a lot
127 * of wrong nodes but just uses this API for his convenience.
128 */
129 KAVLNODE *pRemovedNode = KAVL_FN(Remove)(pRoot, pNode->mKey);
130 if (pRemovedNode == pNode)
131 return pRemovedNode;
132
133 KAVL_FN(Insert)(pRoot, pRemovedNode);
134 return NULL;
135#endif
136}
137
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