]>
git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/BonjourTop/source/LLRBTree.h
5 // Created by Terrin Eager on 7/9/12.
7 // based on rbtree.h but converted to C++
8 // ll from http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf
10 #ifndef __TestTB__LLRBTree__
11 #define __TestTB__LLRBTree__
15 #include <sys/socket.h>
19 template < class KeyType
>
23 CRBNode () { m_bIsRed
= true ; m_rbLeft
= m_rbRight
= NULL
;};
26 inline virtual BJ_COMPARE
Compare ( KeyType
* pKey
) = 0 ; // Key values are equal
28 inline virtual void CopyNode ( CRBNode
* pSource
) = 0 ;
29 inline virtual void Init ()= 0 ;
30 inline virtual void Clear ()= 0 ;
32 CRBNode
* GetMinNode ();
33 CRBNode
* GetMaxNode ();
36 inline CRBNode
* RotateNodeLeft ();
37 inline CRBNode
* RotateNodeRight ();
40 CRBNode
* AddRecord ( CRBNode
* pNewRecord
);
48 CRBNode
* MoveRedLeft ();
49 CRBNode
* MoveRedRight ();
51 void CallBack ( int (* callback
)( const void *, const void *), void * pParam
);
64 template < class KeyType
, class NodeType
>
70 virtual ~ CLLRBTree () { if ( m_Root
) delete m_Root
;};
72 NodeType
* Find ( KeyType
* pKey
);
74 NodeType
* FindwithAddRecord ( KeyType
* pKey
);
75 NodeType
* AddRecord ( KeyType
* pKey
);
76 void RemoveRecord ( KeyType
* pKey
);
78 NodeType
* GetRoot () { return m_Root
;};
79 void ClearAll () { delete m_Root
; m_Root
= NULL
;};
84 NodeType
* GetMinNode ();
85 NodeType
* GetMaxNode ();
87 NodeType
* deleteMin ( NodeType
* pRecord
);
91 NodeType
* RemoveRecord ( NodeType
* pRecord
, KeyType
* pKey
);
93 virtual NodeType
* newNode ( KeyType
* pKey
) { return new NodeType ( pKey
);}
94 virtual void freeNode ( NodeType
* pNode
){ delete pNode
;};
104 template < class KeyType
>
105 CRBNode
< KeyType
>::~ CRBNode ()
117 template < class KeyType
>
118 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: RotateNodeLeft ()
120 CRBNode
< KeyType
>* pTemp
= m_rbRight
;
121 m_rbRight
= pTemp
-> m_rbLeft
;
122 pTemp
-> m_rbLeft
= this ;
123 pTemp
-> m_bIsRed
= pTemp
-> m_rbLeft
-> m_bIsRed
;
124 pTemp
-> m_rbLeft
-> m_bIsRed
= 1 ;
130 template < class KeyType
>
131 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: RotateNodeRight ()
133 CRBNode
< KeyType
>* pTemp
= m_rbLeft
;
134 m_rbLeft
= pTemp
-> m_rbRight
;
135 pTemp
-> m_rbRight
= this ;
136 pTemp
-> m_bIsRed
= pTemp
-> m_rbRight
-> m_bIsRed
;
137 pTemp
-> m_rbRight
-> m_bIsRed
= 1 ;
142 template < class KeyType
>
143 BJ_UINT64 CRBNode
< KeyType
>:: GetCount ()
147 Num
+= m_rbLeft
-> GetCount ();
149 Num
+= m_rbRight
-> GetCount ();
155 template < class KeyType
>
156 void CRBNode
< KeyType
>:: FlipColor ()
158 m_bIsRed
= ! m_bIsRed
;
160 m_rbLeft
-> m_bIsRed
= ! m_rbLeft
-> m_bIsRed
;
162 m_rbRight
-> m_bIsRed
= ! m_rbRight
-> m_bIsRed
;
166 template < class KeyType
>
167 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: Fixup ()
169 // fix the tree balance
170 CRBNode
< KeyType
>* pNode
= this ;
172 if ( m_rbRight
&& m_rbRight
-> m_bIsRed
) // fix right leaning reds on the way up
173 pNode
= RotateNodeLeft ();
175 if ( pNode
&& pNode
-> m_rbLeft
&& pNode
-> m_rbLeft
-> m_bIsRed
&& pNode
-> m_rbLeft
-> m_rbLeft
&& pNode
-> m_rbLeft
-> m_rbLeft
-> m_bIsRed
) // fix two reds in a row on the way up
176 pNode
= RotateNodeRight ();
178 if ( pNode
&& pNode
-> m_rbRight
&& pNode
-> m_rbRight
-> m_bIsRed
&& pNode
-> m_rbLeft
&& pNode
-> m_rbLeft
-> m_bIsRed
) //split 4-nodes on the way up
184 template < class KeyType
>
185 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: MoveRedLeft ()
187 CRBNode
* pNode
= this ;
190 if ( m_rbRight
&& m_rbRight
-> m_rbLeft
&& m_rbRight
-> m_rbLeft
-> m_bIsRed
)
192 m_rbRight
= m_rbRight
-> RotateNodeRight ();
193 pNode
= RotateNodeLeft ();
200 template < class KeyType
>
201 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: MoveRedRight ()
203 CRBNode
* pNode
= this ;
206 if ( m_rbLeft
&& m_rbLeft
-> m_rbLeft
&& m_rbLeft
-> m_rbLeft
-> m_bIsRed
)
208 pNode
= RotateNodeRight ();
215 template < class KeyType
>
216 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: AddRecord ( CRBNode
* pNewRecord
)
219 switch ( Compare (& pNewRecord
-> m_Key
))
223 m_rbRight
= m_rbRight
-> AddRecord ( pNewRecord
);
225 m_rbRight
= pNewRecord
;
230 m_rbLeft
= m_rbLeft
-> AddRecord ( pNewRecord
);
232 m_rbLeft
= pNewRecord
;
236 pNewRecord
-> m_bIsRed
= false ;
237 pNewRecord
-> m_rbLeft
= m_rbLeft
;
238 m_rbLeft
= pNewRecord
;
242 // fix the tree balance
243 CRBNode
* pRecord
= this ;
245 // fix the tree balance
247 if ( pRecord
&& pRecord
-> m_rbRight
&& pRecord
-> m_rbRight
-> m_bIsRed
) // fix right leaning reds on the way up
248 pRecord
= pRecord
-> RotateNodeLeft ();
250 if ( pRecord
&& pRecord
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_bIsRed
&& pRecord
-> m_rbLeft
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_rbLeft
-> m_bIsRed
) // fix two reds in a row on the way up
251 pRecord
= pRecord
-> RotateNodeRight ();
253 if ( pRecord
&& pRecord
-> m_rbRight
&& pRecord
-> m_rbRight
-> m_bIsRed
&& pRecord
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_bIsRed
) //split 4-nodes on the way up
254 pRecord
-> FlipColor ();
262 template < class KeyType
>
263 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: GetMinNode ()
265 CRBNode
* pRecord
= this ;
266 while ( pRecord
&& pRecord
-> m_rbLeft
)
267 pRecord
= pRecord
-> m_rbLeft
;
271 template < class KeyType
>
272 CRBNode
< KeyType
>* CRBNode
< KeyType
>:: GetMaxNode ()
274 CRBNode
* pRecord
= this ;
275 while ( pRecord
&& pRecord
-> m_rbRight
)
276 pRecord
= pRecord
-> m_rbRight
;
281 template < class KeyType
>
282 void CRBNode
< KeyType
>:: CallBack ( int (* callback
)( const void *, const void *), void * pParam
)
286 m_rbLeft
-> CallBack ( callback
, pParam
);
288 callback ( this , pParam
);
291 m_rbRight
-> CallBack ( callback
, pParam
);
299 template < class KeyType
, class NodeType
>
300 CLLRBTree
< KeyType
, NodeType
>:: CLLRBTree ()
305 template < class KeyType
, class NodeType
>
306 NodeType
* CLLRBTree
< KeyType
, NodeType
>:: Find ( KeyType
* pKey
)
309 CRBNode
< KeyType
>* pNode
= m_Root
;
313 switch ( pNode
-> Compare ( pKey
))
316 pNode
= pNode
-> m_rbRight
;
319 pNode
= pNode
-> m_rbLeft
;
322 return ( NodeType
*) pNode
;
331 template < class KeyType
, class NodeType
>
332 NodeType
* CLLRBTree
< KeyType
, NodeType
>:: AddRecord ( KeyType
* pKey
)
334 NodeType
* pRecord
= newNode ( pKey
);
336 m_Root
= ( NodeType
*) m_Root
-> AddRecord ( pRecord
);
341 m_Root
-> m_bIsRed
= false ;
346 template < class KeyType
, class NodeType
>
347 NodeType
* CLLRBTree
< KeyType
, NodeType
>:: FindwithAddRecord ( KeyType
* pKey
)
349 NodeType
* pRecord
= NULL
;
351 pRecord
= Find ( pKey
);
354 pRecord
= AddRecord ( pKey
);
359 template < class KeyType
, class NodeType
>
360 void CLLRBTree
< KeyType
, NodeType
>:: RemoveRecord ( KeyType
* pKey
)
362 m_Root
= RemoveRecord ( m_Root
, pKey
);
365 template < class KeyType
, class NodeType
>
366 NodeType
* CLLRBTree
< KeyType
, NodeType
>:: deleteMin ( NodeType
* pRecord
)
368 if ( pRecord
-> m_rbLeft
== NULL
)
374 if (!( pRecord
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_bIsRed
) && !( pRecord
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_rbLeft
-> m_bIsRed
))
375 pRecord
= ( NodeType
*) pRecord
-> MoveRedLeft ();
377 pRecord
-> m_rbLeft
= deleteMin (( NodeType
*) pRecord
-> m_rbLeft
);
379 return ( NodeType
*) pRecord
-> Fixup ();
382 template < class KeyType
, class NodeType
>
383 NodeType
* CLLRBTree
< KeyType
, NodeType
>:: RemoveRecord ( NodeType
* pRecord
, KeyType
* pKey
)
385 NodeType
* pTempRecord
= NULL
;
390 if ( pRecord
-> Compare ( pKey
) == BJ_LT
)
392 if (!( pRecord
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_bIsRed
) && !( pRecord
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_rbLeft
-> m_bIsRed
))
393 pRecord
-> MoveRedLeft ();
394 pRecord
= RemoveRecord (( NodeType
*) pRecord
-> m_rbLeft
, pKey
);
398 if ( pRecord
-> m_rbLeft
&& pRecord
-> m_rbLeft
-> m_bIsRed
)
399 pRecord
-> RotateNodeRight ();
401 if ( pRecord
-> Compare ( pKey
) == BJ_EQUAL
&& pRecord
-> m_rbRight
== NULL
)
407 if (!( pRecord
-> m_rbRight
&& pRecord
-> m_rbRight
-> m_bIsRed
) && !( pRecord
-> m_rbRight
&& pRecord
-> m_rbRight
-> m_rbLeft
&& pRecord
-> m_rbRight
-> m_rbLeft
-> m_bIsRed
))
408 pRecord
= ( NodeType
*) pRecord
-> MoveRedRight ();
410 if ( pRecord
-> Compare ( pKey
) == BJ_EQUAL
)
412 pTempRecord
= ( NodeType
*) pRecord
-> GetMinNode ();
413 pRecord
-> CopyNode ( pTempRecord
);
414 pRecord
-> m_rbRight
= deleteMin (( NodeType
*) pRecord
-> m_rbRight
);
418 pRecord
-> m_rbRight
= RemoveRecord (( NodeType
*) pRecord
-> m_rbRight
, pKey
);
421 return pRecord
?( NodeType
*) pRecord
-> Fixup (): NULL
;
427 template < class KeyType
, class NodeType
>
428 BJ_UINT64 CLLRBTree
< KeyType
, NodeType
>:: GetCount ()
431 return m_Root
-> GetCount ();
436 template < class KeyType
, class NodeType
>
437 NodeType
* CLLRBTree
< KeyType
, NodeType
>:: GetMinNode ()
440 return m_Root
-> GetMinNode ();
446 template < class KeyType
, class NodeType
>
447 NodeType
* CLLRBTree
< KeyType
, NodeType
>:: GetMaxNode ()
450 return m_Root
-> GetMaxNode ();
460 #endif /* defined(__TestTB__LLRBTree__) */