VirtualBox

source: kStuff/trunk/include/k/kAvlTmpl/kAvlRemove2.h@ 58

Last change on this file since 58 was 34, checked in by bird, 15 years ago

kAvlTmpl: some typos in used code.

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