xref: /aoo4110/main/sot/source/sdstor/stgavl.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_sot.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <osl/diagnose.h>
28*b1cdbd2cSJim Jagielski #include "stgavl.hxx"
29*b1cdbd2cSJim Jagielski 
StgAvlNode()30*b1cdbd2cSJim Jagielski StgAvlNode::StgAvlNode()
31*b1cdbd2cSJim Jagielski {
32*b1cdbd2cSJim Jagielski     pLeft = pRight = NULL;
33*b1cdbd2cSJim Jagielski     nBalance = nId = 0;
34*b1cdbd2cSJim Jagielski }
35*b1cdbd2cSJim Jagielski 
~StgAvlNode()36*b1cdbd2cSJim Jagielski StgAvlNode::~StgAvlNode()
37*b1cdbd2cSJim Jagielski {
38*b1cdbd2cSJim Jagielski     delete pLeft;
39*b1cdbd2cSJim Jagielski     delete pRight;
40*b1cdbd2cSJim Jagielski }
41*b1cdbd2cSJim Jagielski 
Find(StgAvlNode * pFind)42*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlNode::Find( StgAvlNode* pFind )
43*b1cdbd2cSJim Jagielski {
44*b1cdbd2cSJim Jagielski     if ( pFind )
45*b1cdbd2cSJim Jagielski     {
46*b1cdbd2cSJim Jagielski         StgAvlNode* p = this;
47*b1cdbd2cSJim Jagielski         while( p )
48*b1cdbd2cSJim Jagielski         {
49*b1cdbd2cSJim Jagielski             short nRes = p->Compare( pFind );
50*b1cdbd2cSJim Jagielski             if( !nRes )
51*b1cdbd2cSJim Jagielski                 return p;
52*b1cdbd2cSJim Jagielski             else p = ( nRes < 0 ) ? p->pLeft : p->pRight;
53*b1cdbd2cSJim Jagielski         }
54*b1cdbd2cSJim Jagielski     }
55*b1cdbd2cSJim Jagielski     return NULL;
56*b1cdbd2cSJim Jagielski }
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski // find point to add node to AVL tree and returns
59*b1cdbd2cSJim Jagielski // +/0/- for >/=/< previous
60*b1cdbd2cSJim Jagielski 
Locate(StgAvlNode * pFind,StgAvlNode ** pPivot,StgAvlNode ** pParent,StgAvlNode ** pPrev)61*b1cdbd2cSJim Jagielski short StgAvlNode::Locate
62*b1cdbd2cSJim Jagielski     ( StgAvlNode* pFind,
63*b1cdbd2cSJim Jagielski       StgAvlNode** pPivot, StgAvlNode **pParent, StgAvlNode** pPrev )
64*b1cdbd2cSJim Jagielski {
65*b1cdbd2cSJim Jagielski     short nRes = 0;
66*b1cdbd2cSJim Jagielski     StgAvlNode* pCur = this;
67*b1cdbd2cSJim Jagielski 
68*b1cdbd2cSJim Jagielski     OSL_ENSURE( pPivot && pParent && pPrev, "The pointers may not be NULL!" );
69*b1cdbd2cSJim Jagielski     *pParent = *pPrev = NULL;
70*b1cdbd2cSJim Jagielski     *pPivot = this;
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski     // search tree for insertion point
73*b1cdbd2cSJim Jagielski     if ( pFind )
74*b1cdbd2cSJim Jagielski     {
75*b1cdbd2cSJim Jagielski         while( pCur != NULL )
76*b1cdbd2cSJim Jagielski         {
77*b1cdbd2cSJim Jagielski             // check for pPivot
78*b1cdbd2cSJim Jagielski             if( pCur->nBalance != 0 )
79*b1cdbd2cSJim Jagielski                 *pPivot = pCur, *pParent = *pPrev;
80*b1cdbd2cSJim Jagielski             // save pPrev location and see what direction to go
81*b1cdbd2cSJim Jagielski             *pPrev = pCur;
82*b1cdbd2cSJim Jagielski             nRes = pCur->Compare( pFind );
83*b1cdbd2cSJim Jagielski             if( nRes == 0 )
84*b1cdbd2cSJim Jagielski                 break;
85*b1cdbd2cSJim Jagielski             else pCur = ( nRes < 0 ) ? pCur->pLeft : pCur->pRight;
86*b1cdbd2cSJim Jagielski         }
87*b1cdbd2cSJim Jagielski     }
88*b1cdbd2cSJim Jagielski 
89*b1cdbd2cSJim Jagielski     return( nRes );
90*b1cdbd2cSJim Jagielski }
91*b1cdbd2cSJim Jagielski 
92*b1cdbd2cSJim Jagielski // adjust balance factors in AVL tree from pivot down.
93*b1cdbd2cSJim Jagielski // Returns delta balance.
94*b1cdbd2cSJim Jagielski 
Adjust(StgAvlNode ** pHeavy,StgAvlNode * pNew)95*b1cdbd2cSJim Jagielski short StgAvlNode::Adjust( StgAvlNode** pHeavy, StgAvlNode* pNew )
96*b1cdbd2cSJim Jagielski {
97*b1cdbd2cSJim Jagielski     StgAvlNode* pCur = this;
98*b1cdbd2cSJim Jagielski     short nDelta;
99*b1cdbd2cSJim Jagielski     // no traversing
100*b1cdbd2cSJim Jagielski     OSL_ENSURE( pHeavy && pNew, "The pointers is not allowed to be NULL!" );
101*b1cdbd2cSJim Jagielski     if( pCur == pNew || !pNew )
102*b1cdbd2cSJim Jagielski         return nBalance;
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski     short nRes = Compare( pNew );
105*b1cdbd2cSJim Jagielski     if( nRes > 0 )
106*b1cdbd2cSJim Jagielski     {
107*b1cdbd2cSJim Jagielski         *pHeavy = pCur = pRight;
108*b1cdbd2cSJim Jagielski         nDelta = -1;
109*b1cdbd2cSJim Jagielski     }
110*b1cdbd2cSJim Jagielski     else
111*b1cdbd2cSJim Jagielski     {
112*b1cdbd2cSJim Jagielski         *pHeavy = pCur = pLeft;
113*b1cdbd2cSJim Jagielski         nDelta = 1;
114*b1cdbd2cSJim Jagielski     }
115*b1cdbd2cSJim Jagielski 	nBalance = 0;
116*b1cdbd2cSJim Jagielski 	while( pCur != pNew )
117*b1cdbd2cSJim Jagielski     {
118*b1cdbd2cSJim Jagielski         nRes = pCur->Compare( pNew );
119*b1cdbd2cSJim Jagielski         if( nRes > 0 )
120*b1cdbd2cSJim Jagielski         {
121*b1cdbd2cSJim Jagielski             // height of right increases by 1
122*b1cdbd2cSJim Jagielski             pCur->nBalance = -1;
123*b1cdbd2cSJim Jagielski             pCur = pCur->pRight;
124*b1cdbd2cSJim Jagielski         }
125*b1cdbd2cSJim Jagielski         else
126*b1cdbd2cSJim Jagielski         {
127*b1cdbd2cSJim Jagielski             // height of left increases by 1
128*b1cdbd2cSJim Jagielski             pCur->nBalance = 1;
129*b1cdbd2cSJim Jagielski             pCur = pCur->pLeft;
130*b1cdbd2cSJim Jagielski         }
131*b1cdbd2cSJim Jagielski     }
132*b1cdbd2cSJim Jagielski     nBalance = nBalance + nDelta;
133*b1cdbd2cSJim Jagielski     return nDelta;
134*b1cdbd2cSJim Jagielski }
135*b1cdbd2cSJim Jagielski 
136*b1cdbd2cSJim Jagielski // perform LL rotation and return new root
137*b1cdbd2cSJim Jagielski 
RotLL()138*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlNode::RotLL()
139*b1cdbd2cSJim Jagielski {
140*b1cdbd2cSJim Jagielski     OSL_ENSURE( pLeft, "The pointer is not allowed to be NULL!" );
141*b1cdbd2cSJim Jagielski     StgAvlNode *pHeavy = pLeft;
142*b1cdbd2cSJim Jagielski     pLeft = pHeavy->pRight;
143*b1cdbd2cSJim Jagielski     pHeavy->pRight = this;
144*b1cdbd2cSJim Jagielski     pHeavy->nBalance = nBalance = 0;
145*b1cdbd2cSJim Jagielski     return pHeavy;
146*b1cdbd2cSJim Jagielski }
147*b1cdbd2cSJim Jagielski 
148*b1cdbd2cSJim Jagielski // perform LR rotation and return new root
149*b1cdbd2cSJim Jagielski 
RotLR()150*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlNode::RotLR()
151*b1cdbd2cSJim Jagielski {
152*b1cdbd2cSJim Jagielski     OSL_ENSURE( pLeft && pLeft->pRight, "The pointer is not allowed to be NULL!" );
153*b1cdbd2cSJim Jagielski     StgAvlNode* pHeavy = pLeft;
154*b1cdbd2cSJim Jagielski     StgAvlNode* pNewRoot = pHeavy->pRight;
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski     pHeavy->pRight = pNewRoot->pLeft;
157*b1cdbd2cSJim Jagielski     pLeft = pNewRoot->pRight;
158*b1cdbd2cSJim Jagielski     pNewRoot->pLeft = pHeavy;
159*b1cdbd2cSJim Jagielski     pNewRoot->pRight = this;
160*b1cdbd2cSJim Jagielski 
161*b1cdbd2cSJim Jagielski     switch( pNewRoot->nBalance )
162*b1cdbd2cSJim Jagielski     {
163*b1cdbd2cSJim Jagielski         case 1:     // LR( b )
164*b1cdbd2cSJim Jagielski             nBalance = -1;
165*b1cdbd2cSJim Jagielski             pHeavy->nBalance = 0;
166*b1cdbd2cSJim Jagielski             break;
167*b1cdbd2cSJim Jagielski         case -1:    // LR( c )
168*b1cdbd2cSJim Jagielski             pHeavy->nBalance = 1;
169*b1cdbd2cSJim Jagielski             nBalance = 0;
170*b1cdbd2cSJim Jagielski             break;
171*b1cdbd2cSJim Jagielski         case 0:     // LR( a )
172*b1cdbd2cSJim Jagielski             nBalance = 0;
173*b1cdbd2cSJim Jagielski             pHeavy->nBalance = 0;
174*b1cdbd2cSJim Jagielski             break;
175*b1cdbd2cSJim Jagielski     }
176*b1cdbd2cSJim Jagielski     pNewRoot->nBalance = 0;
177*b1cdbd2cSJim Jagielski     return pNewRoot;
178*b1cdbd2cSJim Jagielski }
179*b1cdbd2cSJim Jagielski 
180*b1cdbd2cSJim Jagielski // perform RR rotation and return new root
181*b1cdbd2cSJim Jagielski 
RotRR()182*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlNode::RotRR()
183*b1cdbd2cSJim Jagielski {
184*b1cdbd2cSJim Jagielski     OSL_ENSURE( pRight, "The pointer is not allowed to be NULL!" );
185*b1cdbd2cSJim Jagielski     StgAvlNode* pHeavy = pRight;
186*b1cdbd2cSJim Jagielski     pRight = pHeavy->pLeft;
187*b1cdbd2cSJim Jagielski     pHeavy->pLeft = this;
188*b1cdbd2cSJim Jagielski     nBalance = pHeavy->nBalance = 0;
189*b1cdbd2cSJim Jagielski     return pHeavy;
190*b1cdbd2cSJim Jagielski }
191*b1cdbd2cSJim Jagielski 
192*b1cdbd2cSJim Jagielski // perform the RL rotation and return the new root
193*b1cdbd2cSJim Jagielski 
RotRL()194*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlNode::RotRL()
195*b1cdbd2cSJim Jagielski {
196*b1cdbd2cSJim Jagielski     OSL_ENSURE( pRight && pRight->pLeft, "The pointer is not allowed to be NULL!" );
197*b1cdbd2cSJim Jagielski     StgAvlNode* pHeavy = pRight;
198*b1cdbd2cSJim Jagielski     StgAvlNode* pNewRoot = pHeavy->pLeft;
199*b1cdbd2cSJim Jagielski     pHeavy->pLeft = pNewRoot->pRight;
200*b1cdbd2cSJim Jagielski     pRight = pNewRoot->pLeft;
201*b1cdbd2cSJim Jagielski     pNewRoot->pRight = pHeavy;
202*b1cdbd2cSJim Jagielski     pNewRoot->pLeft = this;
203*b1cdbd2cSJim Jagielski     switch( pNewRoot->nBalance )
204*b1cdbd2cSJim Jagielski     {
205*b1cdbd2cSJim Jagielski         case -1:    // RL( b )
206*b1cdbd2cSJim Jagielski             nBalance = 1;
207*b1cdbd2cSJim Jagielski             pHeavy->nBalance = 0;
208*b1cdbd2cSJim Jagielski             break;
209*b1cdbd2cSJim Jagielski         case 1:     // RL( c )
210*b1cdbd2cSJim Jagielski             pHeavy->nBalance = -1;
211*b1cdbd2cSJim Jagielski             nBalance = 0;
212*b1cdbd2cSJim Jagielski             break;
213*b1cdbd2cSJim Jagielski         case 0:     // RL( a )
214*b1cdbd2cSJim Jagielski             nBalance = 0;
215*b1cdbd2cSJim Jagielski             pHeavy->nBalance = 0;
216*b1cdbd2cSJim Jagielski             break;
217*b1cdbd2cSJim Jagielski     }
218*b1cdbd2cSJim Jagielski     pNewRoot->nBalance = 0;
219*b1cdbd2cSJim Jagielski     return pNewRoot;
220*b1cdbd2cSJim Jagielski }
221*b1cdbd2cSJim Jagielski 
222*b1cdbd2cSJim Jagielski // Remove a tree element. Return the removed element or NULL.
223*b1cdbd2cSJim Jagielski 
Rem(StgAvlNode ** p,StgAvlNode * pDel,sal_Bool bPtrs)224*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlNode::Rem( StgAvlNode** p, StgAvlNode* pDel, sal_Bool bPtrs )
225*b1cdbd2cSJim Jagielski {
226*b1cdbd2cSJim Jagielski     if( p && *p && pDel )
227*b1cdbd2cSJim Jagielski     {
228*b1cdbd2cSJim Jagielski         StgAvlNode* pCur = *p;
229*b1cdbd2cSJim Jagielski         short nRes = bPtrs ? short( pCur == pDel ) : short(pCur->Compare( pDel ));
230*b1cdbd2cSJim Jagielski         if( !nRes )
231*b1cdbd2cSJim Jagielski         {
232*b1cdbd2cSJim Jagielski             // Element found: remove
233*b1cdbd2cSJim Jagielski             if( !pCur->pRight )
234*b1cdbd2cSJim Jagielski             {
235*b1cdbd2cSJim Jagielski                 *p = pCur->pLeft; pCur->pLeft = NULL;
236*b1cdbd2cSJim Jagielski             }
237*b1cdbd2cSJim Jagielski             else if( !pCur->pLeft )
238*b1cdbd2cSJim Jagielski             {
239*b1cdbd2cSJim Jagielski                 *p = pCur->pRight; pCur->pRight = NULL;
240*b1cdbd2cSJim Jagielski             }
241*b1cdbd2cSJim Jagielski             else
242*b1cdbd2cSJim Jagielski             {
243*b1cdbd2cSJim Jagielski                 // The damn element has two leaves. Get the
244*b1cdbd2cSJim Jagielski                 // rightmost element of the left subtree (which
245*b1cdbd2cSJim Jagielski                 // is lexically before this element) and replace
246*b1cdbd2cSJim Jagielski                 // this element with the element found.
247*b1cdbd2cSJim Jagielski                 StgAvlNode* last = pCur;
248*b1cdbd2cSJim Jagielski                 StgAvlNode* l;
249*b1cdbd2cSJim Jagielski                 for( l = pCur->pLeft;
250*b1cdbd2cSJim Jagielski                      l->pRight; last = l, l = l->pRight ) {}
251*b1cdbd2cSJim Jagielski                 // remove the element from chain
252*b1cdbd2cSJim Jagielski                 if( l == last->pRight )
253*b1cdbd2cSJim Jagielski                     last->pRight = l->pLeft;
254*b1cdbd2cSJim Jagielski                 else
255*b1cdbd2cSJim Jagielski                     last->pLeft = l->pLeft;
256*b1cdbd2cSJim Jagielski                 // perform the replacement
257*b1cdbd2cSJim Jagielski                 l->pLeft = pCur->pLeft;
258*b1cdbd2cSJim Jagielski                 l->pRight = pCur->pRight;
259*b1cdbd2cSJim Jagielski                 *p = l;
260*b1cdbd2cSJim Jagielski                 // delete the element
261*b1cdbd2cSJim Jagielski                 pCur->pLeft = pCur->pRight = NULL;
262*b1cdbd2cSJim Jagielski             }
263*b1cdbd2cSJim Jagielski             return pCur;
264*b1cdbd2cSJim Jagielski         }
265*b1cdbd2cSJim Jagielski         else
266*b1cdbd2cSJim Jagielski         {
267*b1cdbd2cSJim Jagielski             if( nRes < 0 )
268*b1cdbd2cSJim Jagielski                 return Rem( &pCur->pLeft, pDel, bPtrs );
269*b1cdbd2cSJim Jagielski             else
270*b1cdbd2cSJim Jagielski                 return Rem( &pCur->pRight, pDel, bPtrs );
271*b1cdbd2cSJim Jagielski         }
272*b1cdbd2cSJim Jagielski     }
273*b1cdbd2cSJim Jagielski     return NULL;
274*b1cdbd2cSJim Jagielski }
275*b1cdbd2cSJim Jagielski 
276*b1cdbd2cSJim Jagielski // Enumerate the tree for later iteration
277*b1cdbd2cSJim Jagielski 
StgEnum(short & n)278*b1cdbd2cSJim Jagielski void StgAvlNode::StgEnum( short& n )
279*b1cdbd2cSJim Jagielski {
280*b1cdbd2cSJim Jagielski     if( pLeft )
281*b1cdbd2cSJim Jagielski         pLeft->StgEnum( n );
282*b1cdbd2cSJim Jagielski     nId = n++;
283*b1cdbd2cSJim Jagielski     if( pRight )
284*b1cdbd2cSJim Jagielski         pRight->StgEnum( n );
285*b1cdbd2cSJim Jagielski }
286*b1cdbd2cSJim Jagielski 
287*b1cdbd2cSJim Jagielski // Add node to AVL tree.
288*b1cdbd2cSJim Jagielski // Return sal_False if the element already exists.
289*b1cdbd2cSJim Jagielski 
Insert(StgAvlNode ** pRoot,StgAvlNode * pIns)290*b1cdbd2cSJim Jagielski sal_Bool StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns )
291*b1cdbd2cSJim Jagielski {
292*b1cdbd2cSJim Jagielski     StgAvlNode* pPivot, *pHeavy, *pNewRoot, *pParent, *pPrev;
293*b1cdbd2cSJim Jagielski     if ( !pRoot )
294*b1cdbd2cSJim Jagielski         return sal_False;
295*b1cdbd2cSJim Jagielski 
296*b1cdbd2cSJim Jagielski     // special case - empty tree
297*b1cdbd2cSJim Jagielski     if( *pRoot == NULL )
298*b1cdbd2cSJim Jagielski     {
299*b1cdbd2cSJim Jagielski         *pRoot = pIns;
300*b1cdbd2cSJim Jagielski         return sal_True;
301*b1cdbd2cSJim Jagielski     }
302*b1cdbd2cSJim Jagielski     // find insertion point and return if already present
303*b1cdbd2cSJim Jagielski     short nRes = (*pRoot)->Locate( pIns, &pPivot, &pParent, &pPrev );
304*b1cdbd2cSJim Jagielski     if( !nRes )
305*b1cdbd2cSJim Jagielski         return sal_False;
306*b1cdbd2cSJim Jagielski     OSL_ENSURE( pPivot && pPrev, "The pointers may not be NULL!" );
307*b1cdbd2cSJim Jagielski 
308*b1cdbd2cSJim Jagielski     // add new node
309*b1cdbd2cSJim Jagielski     if( nRes < 0 )
310*b1cdbd2cSJim Jagielski         pPrev->pLeft = pIns;
311*b1cdbd2cSJim Jagielski     else
312*b1cdbd2cSJim Jagielski         pPrev->pRight = pIns;
313*b1cdbd2cSJim Jagielski     // rebalance tree
314*b1cdbd2cSJim Jagielski     short nDelta = pPivot->Adjust( &pHeavy, pIns );
315*b1cdbd2cSJim Jagielski     if( pPivot->nBalance >= 2 || pPivot->nBalance <= -2 )
316*b1cdbd2cSJim Jagielski     {
317*b1cdbd2cSJim Jagielski         pHeavy = ( nDelta < 0 ) ? pPivot->pRight : pPivot->pLeft;
318*b1cdbd2cSJim Jagielski         // left imbalance
319*b1cdbd2cSJim Jagielski         if( nDelta > 0 )
320*b1cdbd2cSJim Jagielski             if( pHeavy->nBalance == 1 )
321*b1cdbd2cSJim Jagielski                 pNewRoot = pPivot->RotLL();
322*b1cdbd2cSJim Jagielski             else
323*b1cdbd2cSJim Jagielski                 pNewRoot = pPivot->RotLR();
324*b1cdbd2cSJim Jagielski         // right imbalance
325*b1cdbd2cSJim Jagielski         else if( pHeavy->nBalance == -1 )
326*b1cdbd2cSJim Jagielski             pNewRoot = pPivot->RotRR();
327*b1cdbd2cSJim Jagielski         else
328*b1cdbd2cSJim Jagielski             pNewRoot = pPivot->RotRL();
329*b1cdbd2cSJim Jagielski         // relink balanced subtree
330*b1cdbd2cSJim Jagielski         if( pParent == NULL )
331*b1cdbd2cSJim Jagielski             *pRoot = pNewRoot;
332*b1cdbd2cSJim Jagielski         else if( pPivot == pParent->pLeft )
333*b1cdbd2cSJim Jagielski             pParent->pLeft = pNewRoot;
334*b1cdbd2cSJim Jagielski         else if( pPivot == pParent->pRight )
335*b1cdbd2cSJim Jagielski             pParent->pRight = pNewRoot;
336*b1cdbd2cSJim Jagielski     }
337*b1cdbd2cSJim Jagielski     return sal_True;
338*b1cdbd2cSJim Jagielski }
339*b1cdbd2cSJim Jagielski 
340*b1cdbd2cSJim Jagielski // Remove node from tree. Returns sal_True is found and removed.
341*b1cdbd2cSJim Jagielski // Actually delete if bDel
342*b1cdbd2cSJim Jagielski 
Remove(StgAvlNode ** pRoot,StgAvlNode * pDel,sal_Bool bDel)343*b1cdbd2cSJim Jagielski sal_Bool StgAvlNode::Remove( StgAvlNode** pRoot, StgAvlNode* pDel, sal_Bool bDel )
344*b1cdbd2cSJim Jagielski {
345*b1cdbd2cSJim Jagielski     if ( !pRoot )
346*b1cdbd2cSJim Jagielski         return sal_False;
347*b1cdbd2cSJim Jagielski 
348*b1cdbd2cSJim Jagielski     // special case - empty tree
349*b1cdbd2cSJim Jagielski     if( *pRoot == NULL )
350*b1cdbd2cSJim Jagielski         return sal_False;
351*b1cdbd2cSJim Jagielski     // delete the element
352*b1cdbd2cSJim Jagielski     pDel = Rem( pRoot, pDel, sal_False );
353*b1cdbd2cSJim Jagielski 	if( pDel )
354*b1cdbd2cSJim Jagielski 	{
355*b1cdbd2cSJim Jagielski 		if( bDel )
356*b1cdbd2cSJim Jagielski 			delete pDel;
357*b1cdbd2cSJim Jagielski 		// Rebalance the tree the hard way
358*b1cdbd2cSJim Jagielski 		// OS 22.09.95: Auf MD's Wunsch auskommentiert wg. Absturz
359*b1cdbd2cSJim Jagielski /*		StgAvlNode* pNew = NULL;
360*b1cdbd2cSJim Jagielski 		while( *pRoot )
361*b1cdbd2cSJim Jagielski 		{
362*b1cdbd2cSJim Jagielski 			StgAvlNode* p = Rem( pRoot, *pRoot, sal_False );
363*b1cdbd2cSJim Jagielski 			Insert( &pNew, p );
364*b1cdbd2cSJim Jagielski 		}
365*b1cdbd2cSJim Jagielski 		*pRoot = pNew;*/
366*b1cdbd2cSJim Jagielski 		return sal_True;
367*b1cdbd2cSJim Jagielski 	}
368*b1cdbd2cSJim Jagielski 	else
369*b1cdbd2cSJim Jagielski 		return sal_False;
370*b1cdbd2cSJim Jagielski }
371*b1cdbd2cSJim Jagielski 
372*b1cdbd2cSJim Jagielski // Move node to a different tree. Returns sal_True is found and moved. This routine
373*b1cdbd2cSJim Jagielski // may be called when the key has changed.
374*b1cdbd2cSJim Jagielski 
Move(StgAvlNode ** pRoot1,StgAvlNode ** pRoot2,StgAvlNode * pMove)375*b1cdbd2cSJim Jagielski sal_Bool StgAvlNode::Move
376*b1cdbd2cSJim Jagielski 	( StgAvlNode** pRoot1, StgAvlNode** pRoot2, StgAvlNode* pMove )
377*b1cdbd2cSJim Jagielski {
378*b1cdbd2cSJim Jagielski     if ( !pRoot1 )
379*b1cdbd2cSJim Jagielski         return sal_False;
380*b1cdbd2cSJim Jagielski 
381*b1cdbd2cSJim Jagielski     // special case - empty tree
382*b1cdbd2cSJim Jagielski     if( *pRoot1 == NULL )
383*b1cdbd2cSJim Jagielski         return sal_False;
384*b1cdbd2cSJim Jagielski 	pMove = Rem( pRoot1, pMove, sal_False );
385*b1cdbd2cSJim Jagielski 	if( pMove )
386*b1cdbd2cSJim Jagielski 		return Insert( pRoot2, pMove );
387*b1cdbd2cSJim Jagielski 	else
388*b1cdbd2cSJim Jagielski 		return sal_False;
389*b1cdbd2cSJim Jagielski }
390*b1cdbd2cSJim Jagielski 
391*b1cdbd2cSJim Jagielski ////////////////////////// class AvlIterator /////////////////////////
392*b1cdbd2cSJim Jagielski 
393*b1cdbd2cSJim Jagielski // The iterator walks through a tree one entry by one.
394*b1cdbd2cSJim Jagielski 
StgAvlIterator(StgAvlNode * p)395*b1cdbd2cSJim Jagielski StgAvlIterator::StgAvlIterator( StgAvlNode* p )
396*b1cdbd2cSJim Jagielski {
397*b1cdbd2cSJim Jagielski     pRoot = p;
398*b1cdbd2cSJim Jagielski     nCount = 0;
399*b1cdbd2cSJim Jagielski 	if( p )
400*b1cdbd2cSJim Jagielski 	    p->StgEnum( nCount );
401*b1cdbd2cSJim Jagielski }
402*b1cdbd2cSJim Jagielski 
Find(short n)403*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlIterator::Find( short n )
404*b1cdbd2cSJim Jagielski {
405*b1cdbd2cSJim Jagielski     StgAvlNode* p = pRoot;
406*b1cdbd2cSJim Jagielski     while( p )
407*b1cdbd2cSJim Jagielski     {
408*b1cdbd2cSJim Jagielski         if( n == p->nId )
409*b1cdbd2cSJim Jagielski             break;
410*b1cdbd2cSJim Jagielski         else p = ( n < p->nId ) ? p->pLeft : p->pRight;
411*b1cdbd2cSJim Jagielski     }
412*b1cdbd2cSJim Jagielski     return p;
413*b1cdbd2cSJim Jagielski }
414*b1cdbd2cSJim Jagielski 
First()415*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlIterator::First()
416*b1cdbd2cSJim Jagielski {
417*b1cdbd2cSJim Jagielski     nCur = -1;
418*b1cdbd2cSJim Jagielski     return Next();
419*b1cdbd2cSJim Jagielski }
420*b1cdbd2cSJim Jagielski 
Last()421*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlIterator::Last()
422*b1cdbd2cSJim Jagielski {
423*b1cdbd2cSJim Jagielski     nCur = nCount;
424*b1cdbd2cSJim Jagielski     return Prev();
425*b1cdbd2cSJim Jagielski }
426*b1cdbd2cSJim Jagielski 
Next()427*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlIterator::Next()
428*b1cdbd2cSJim Jagielski {
429*b1cdbd2cSJim Jagielski     return Find( ++nCur );
430*b1cdbd2cSJim Jagielski }
431*b1cdbd2cSJim Jagielski 
Prev()432*b1cdbd2cSJim Jagielski StgAvlNode* StgAvlIterator::Prev()
433*b1cdbd2cSJim Jagielski {
434*b1cdbd2cSJim Jagielski     return Find( --nCur );
435*b1cdbd2cSJim Jagielski }
436*b1cdbd2cSJim Jagielski 
437