13 #ifndef _FBXSDK_CORE_BASE_REDBLACKTREE_H_
14 #define _FBXSDK_CORE_BASE_REDBLACKTREE_H_
26 #ifndef DOXYGEN_SHOULD_SKIP_THIS
28 template <
typename RecordType>
class FbxRedBlackConstIterator;
30 template <
typename RecordType>
class FbxRedBlackIterator
33 FbxRedBlackIterator() : mRecord(0) {}
34 FbxRedBlackIterator(RecordType* pRecord) : mRecord(pRecord) {}
35 FbxRedBlackIterator(
const FbxRedBlackIterator<RecordType>& pV) : mRecord(pV.mRecord) {}
37 FbxRedBlackIterator& operator++()
39 FBX_ASSERT( mRecord !=
NULL );
40 mRecord = mRecord->Successor();
44 const FbxRedBlackIterator operator++(
int)
46 FbxRedBlackIterator t(*
this);
51 FbxRedBlackIterator& operator+=(
int pCount)
53 FBX_ASSERT( mRecord !=
NULL );
54 for(
int i = 0; i < pCount; ++i )
57 mRecord = mRecord->Successor();
62 FbxRedBlackIterator& operator--()
64 FBX_ASSERT( mRecord );
65 mRecord = mRecord->Predecessor();
69 const FbxRedBlackIterator operator--(
int)
71 FbxRedBlackIterator t(*
this);
76 FbxRedBlackIterator& operator-=(
int pCount)
78 FBX_ASSERT( mRecord !=
NULL );
79 for(
int i = 0; i < pCount; ++i )
82 mRecord = mRecord->Predecessor();
87 const RecordType& operator*()
const
89 FBX_ASSERT( mRecord );
94 RecordType& operator*()
96 FBX_ASSERT( mRecord );
101 const RecordType* operator->()
const
103 FBX_ASSERT( mRecord );
108 RecordType* operator->()
110 FBX_ASSERT( mRecord );
115 inline bool operator==(
const FbxRedBlackIterator& pOther)
const
117 return mRecord == pOther.mRecord;
120 inline bool operator !=(
const FbxRedBlackIterator& pOther)
const
122 return mRecord != pOther.mRecord;
128 friend class FbxRedBlackConstIterator<RecordType>;
131 template <
typename RecordType>
class FbxRedBlackConstIterator
134 FbxRedBlackConstIterator() : mRecord(0) {}
135 FbxRedBlackConstIterator(
const RecordType* pRecord) : mRecord(pRecord) {}
136 FbxRedBlackConstIterator(
const FbxRedBlackIterator<RecordType>& pV) : mRecord(pV.mRecord) {}
137 FbxRedBlackConstIterator(
const FbxRedBlackConstIterator<RecordType>& pV) : mRecord(pV.mRecord) {}
139 FbxRedBlackConstIterator & operator++()
141 FBX_ASSERT( mRecord !=
NULL );
142 mRecord = mRecord->Successor();
146 const FbxRedBlackConstIterator operator++(
int)
148 FbxRedBlackConstIterator t(*
this);
153 FbxRedBlackConstIterator& operator+=(
int pCount)
155 FBX_ASSERT( mRecord !=
NULL );
156 for(
int i = 0; i < pCount; ++i )
158 if( !mRecord )
break;
159 mRecord = mRecord->Successor();
164 FbxRedBlackConstIterator & operator--()
166 FBX_ASSERT( mRecord );
167 mRecord = mRecord->Predecessor();
171 const FbxRedBlackConstIterator operator--(
int)
173 FbxRedBlackConstIterator t(*
this);
178 FbxRedBlackConstIterator& operator-=(
int pCount)
180 FBX_ASSERT( mRecord !=
NULL );
181 for(
int i = 0; i < pCount; ++i )
183 if( !mRecord )
break;
184 mRecord = mRecord->Predecessor();
189 const RecordType& operator*()
const
191 FBX_ASSERT( mRecord );
196 const RecordType& operator*()
198 FBX_ASSERT( mRecord );
203 const RecordType* operator->()
const
205 FBX_ASSERT( mRecord );
210 const RecordType* operator->()
212 FBX_ASSERT( mRecord );
217 inline bool operator==(
const FbxRedBlackConstIterator& pOther)
const
219 return mRecord == pOther.mRecord;
222 inline bool operator !=(
const FbxRedBlackConstIterator& pOther)
const
224 return mRecord != pOther.mRecord;
228 const RecordType* mRecord;
230 friend class FbxRedBlackIterator<RecordType>;
234 template <
typename Type,
typename Compare,
typename Allocator>
class FbxRedBlackTree
237 typedef Type DataType;
238 typedef typename Type::KeyType KeyType;
239 typedef typename Type::ConstKeyType ConstKeyType;
240 typedef typename Type::ValueType ValueType;
241 typedef typename Type::ConstValueType ConstValueType;
242 typedef Allocator AllocatorType;
251 inline ConstKeyType& GetKey()
const {
return mData.GetKey(); }
252 inline ConstValueType& GetValue()
const {
return mData.GetValue(); }
253 inline ValueType& GetValue() {
return mData.GetValue(); }
255 inline const RecordType* Minimum()
const
257 const RecordType* lParent = 0;
258 const RecordType* lNode =
this;
262 lNode = lNode->mLeftChild;
268 inline RecordType* Minimum()
270 RecordType* lParent = 0;
271 RecordType* lNode =
this;
275 lNode = lNode->mLeftChild;
281 inline const RecordType* Maximum()
const
283 const RecordType* lParent = 0;
284 const RecordType* lNode =
this;
288 lNode = lNode->mRightChild;
294 inline RecordType* Maximum()
296 RecordType* lParent = 0;
297 RecordType* lNode =
this;
301 lNode = lNode->mRightChild;
307 inline const RecordType* Predecessor()
const
311 return mLeftChild->Maximum();
315 const RecordType* lParent = mParent;
316 const RecordType* lNode =
this;
318 while (lParent && lParent->mLefttChild == lNode)
321 lParent = lParent->mParent;
328 inline RecordType* Predecessor()
332 return mLeftChild->Maximum();
336 RecordType* lParent = mParent;
337 RecordType* lNode =
this;
339 while (lParent && lParent->mLeftChild == lNode)
342 lParent = lParent->mParent;
349 inline const RecordType* Successor()
const
353 return mRightChild->Minimum();
357 const RecordType* lParent = mParent;
358 const RecordType* lNode =
this;
360 while (lParent && lParent->mRightChild == lNode)
363 lParent = lParent->mParent;
370 inline RecordType* Successor()
374 return mRightChild->Minimum();
378 RecordType* lParent = mParent;
379 RecordType* lNode =
this;
381 while (lParent && lParent->mRightChild == lNode)
384 lParent = lParent->mParent;
391 inline int GetBlackDepth() {
return mBlackDepth; }
394 enum ETreeType {eRed, eBlack};
396 inline RecordType(
const DataType& pData)
406 inline RecordType(
const RecordType& pRecordType)
407 : mData(pRecordType.mData)
411 , mColor(pRecordType.mColor)
412 , mBlackDepth(pRecordType.mBlackDepth)
418 friend class FbxRedBlackTree;
421 RecordType* mLeftChild;
422 RecordType* mRightChild;
423 unsigned int mColor:2;
424 unsigned int mBlackDepth:30;
428 typedef FbxRedBlackConstIterator<RecordType> ConstIteratorType;
429 typedef FbxRedBlackIterator<RecordType> IteratorType;
431 inline FbxRedBlackTree() : mRoot(0), mAllocator(sizeof(RecordType)), mSize(0) {}
432 inline FbxRedBlackTree(
const FbxRedBlackTree& pTree) : mRoot(0), mAllocator(sizeof(RecordType)), mSize(0) { operator=(pTree); }
433 inline ~FbxRedBlackTree() { Clear(); }
437 inline FbxRedBlackTree& operator=(
const FbxRedBlackTree& pTree)
445 void* lBuffer = mAllocator.AllocateRecords();
446 mRoot =
new(lBuffer) RecordType(*(pTree.mRoot));
447 mRoot->mLeftChild = DuplicateSubTree(pTree.mRoot->mLeftChild);
448 mRoot->mRightChild = DuplicateSubTree(pTree.mRoot->mRightChild);
450 if (mRoot->mLeftChild)
452 mRoot->mLeftChild->mParent = mRoot;
455 if (mRoot->mRightChild)
457 mRoot->mRightChild->mParent = mRoot;
462 FBX_ASSERT( pTree.mSize == 0 );
463 FBX_ASSERT( mRoot == 0 );
472 inline bool operator==(
const FbxRedBlackTree& pTree)
const
478 if( GetSize() != pTree.GetSize() )
483 ConstIteratorType End;
484 ConstIteratorType Iter1(Minimum());
485 ConstIteratorType Iter2(pTree.Minimum());
487 while( (Iter1 != End) && (Iter2 != End) &&
488 (Iter1->GetKey() == Iter2->GetKey()) &&
489 (Iter1->GetValue() == Iter2->GetValue()) )
495 return Iter1 == End && Iter2 == End;
501 inline void Reserve(
unsigned int pRecordCount)
503 mAllocator.Reserve(pRecordCount);
509 inline int GetSize()
const {
return mSize; }
511 inline bool Empty()
const {
return mSize == 0; }
520 Compare lCompareKeys;
521 bool lResult =
false;
522 RecordType* lParent = 0;
523 RecordType* lNode = mRoot;
526 const KeyType& lNodeKey = lNode->GetKey();
527 const KeyType& lDataKey = pData.GetKey();
529 if (lCompareKeys(lNodeKey, lDataKey) < 0)
532 lNode = lNode->mRightChild;
534 else if (lCompareKeys(lNodeKey, lDataKey) > 0)
537 lNode = lNode->mLeftChild;
547 void* lBuffer = mAllocator.AllocateRecords();
548 lNode =
new(lBuffer) RecordType(pData);
551 FBX_ASSERT(lNode == lBuffer);
555 if (lCompareKeys(lParent->GetKey(), pData.GetKey()) < 0)
557 FBX_ASSERT(lParent->mRightChild == 0);
558 lParent->mRightChild = lNode;
559 lNode->mParent = lParent;
563 FBX_ASSERT(lParent->mLeftChild == 0);
564 lParent->mLeftChild = lNode;
565 lNode->mParent = lParent;
574 FixNodesAfterInsertion(lNode);
585 inline bool Remove(
const KeyType& pKey)
587 Compare lCompareKeys;
588 bool lResult =
false;
589 RecordType* lNode = mRoot;
592 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
594 lNode = lNode->mRightChild;
596 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
598 lNode = lNode->mLeftChild;
610 lNode->~RecordType();
611 mAllocator.FreeMemory(lNode);
625 ClearSubTree(mRoot->mLeftChild);
626 ClearSubTree(mRoot->mRightChild);
627 mRoot->~RecordType();
628 mAllocator.FreeMemory(mRoot);
637 inline const RecordType* Minimum()
const
641 return mRoot->Minimum();
652 inline RecordType* Minimum()
656 return mRoot->Minimum();
667 inline const RecordType* Maximum()
const
671 return mRoot->Maximum();
682 inline RecordType* Maximum()
686 return mRoot->Maximum();
698 inline const RecordType* Find(
const KeyType& pKey)
const
700 Compare lCompareKeys;
701 const RecordType* lNode = mRoot;
704 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
706 lNode = lNode->mRightChild;
708 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
710 lNode = lNode->mLeftChild;
725 inline RecordType* Find(
const KeyType& pKey)
727 Compare lCompareKeys;
728 RecordType* lNode = mRoot;
731 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
733 lNode = lNode->mRightChild;
735 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
737 lNode = lNode->mLeftChild;
752 inline const RecordType* UpperBound(
const KeyType& pKey)
const
754 Compare lCompareKeys;
755 const RecordType* lNode = mRoot;
756 const RecordType* lCandidate = 0;
759 if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
761 lNode = lNode->mRightChild;
763 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
766 lNode = lNode->mLeftChild;
777 inline RecordType* UpperBound(
const KeyType& pKey)
779 Compare lCompareKeys;
780 RecordType* lNode = mRoot;
781 RecordType* lCandidate = 0;
784 if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
786 lNode = lNode->mRightChild;
788 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
791 lNode = lNode->mLeftChild;
800 AllocatorType mAllocator;
803 inline RecordType* DuplicateSubTree(
const RecordType* pNode)
805 RecordType* lNewSubTree = 0;
809 void* lBuffer = mAllocator.AllocateRecords();
810 lNewSubTree =
new(lBuffer) RecordType(*pNode);
811 lNewSubTree->mLeftChild = DuplicateSubTree(pNode->mLeftChild);
812 lNewSubTree->mRightChild = DuplicateSubTree(pNode->mRightChild);
814 if (lNewSubTree->mLeftChild)
816 lNewSubTree->mLeftChild->mParent = lNewSubTree;
819 if (lNewSubTree->mRightChild)
821 lNewSubTree->mRightChild->mParent = lNewSubTree;
828 inline void FixNodesAfterInsertion(RecordType* pNode)
830 RecordType* lNode = pNode;
837 if (lNode->mParent == 0)
839 lNode->mColor = RecordType::eBlack;
841 else if (lNode->mParent->mColor == RecordType::eRed)
843 RecordType* lUncle = 0;
845 if ((lNode->mParent !=
NULL) && (lNode->mParent->mParent !=
NULL))
847 if (lNode->mParent == lNode->mParent->mParent->mLeftChild)
849 lUncle = lNode->mParent->mParent->mRightChild;
851 else if (lNode->mParent == lNode->mParent->mParent->mRightChild)
853 lUncle = lNode->mParent->mParent->mLeftChild;
859 if ((lNode->mParent !=
NULL) && (lNode->mParent->mParent !=
NULL))
861 if (lUncle && lUncle->mColor == RecordType::eRed)
863 lNode->mParent->mColor = RecordType::eBlack;
864 lUncle->mColor = RecordType::eBlack;
865 lNode->mParent->mParent->mColor = RecordType::eRed;
866 lNode = lNode->mParent->mParent;
872 if ((lNode == lNode->mParent->mRightChild) &&
873 (lNode->mParent == lNode->mParent->mParent->mLeftChild))
875 LeftRotate(lNode->mParent);
876 lNode = lNode->mLeftChild;
878 else if ((lNode == lNode->mParent->mLeftChild) &&
879 (lNode->mParent == lNode->mParent->mParent->mRightChild))
881 RightRotate(lNode->mParent);
882 lNode = lNode->mRightChild;
885 lNode->mParent->mColor = RecordType::eBlack;
886 lNode->mParent->mParent->mColor = RecordType::eRed;
887 if ((lNode == lNode->mParent->mLeftChild) &&
888 (lNode->mParent == lNode->mParent->mParent->mLeftChild))
890 RightRotate(lNode->mParent->mParent);
894 LeftRotate(lNode->mParent->mParent);
901 mRoot->mColor = RecordType::eBlack;
904 inline void LeftRotate(RecordType* pNode)
906 FBX_ASSERT_RETURN(pNode);
908 RecordType* lNode = pNode->mRightChild;
909 FBX_ASSERT_RETURN(lNode);
912 RecordType* A = pNode->mLeftChild;
913 RecordType* B = lNode->mLeftChild;
914 RecordType* C = lNode->mRightChild;
915 RecordType* Z = pNode->mParent;
918 pNode->mRightChild = lNode->mLeftChild;
919 if (pNode->mRightChild)
921 pNode->mRightChild->mParent = pNode;
924 lNode->mParent = pNode->mParent;
925 if (pNode->mParent == 0)
927 FBX_ASSERT(mRoot == pNode);
930 else if (pNode == pNode->mParent->mLeftChild)
932 pNode->mParent->mLeftChild = lNode;
936 pNode->mParent->mRightChild = lNode;
938 pNode->mParent = lNode;
939 lNode->mLeftChild = pNode;
941 FBX_ASSERT(pNode->mLeftChild == A);
942 FBX_ASSERT(pNode->mRightChild == B);
943 FBX_ASSERT(pNode->mParent == lNode);
945 FBX_ASSERT(lNode->mLeftChild == pNode);
946 FBX_ASSERT(lNode->mRightChild == C);
947 FBX_ASSERT(lNode->mParent == Z);
949 FBX_ASSERT(A == 0 || A->mParent == pNode);
950 FBX_ASSERT(B == 0 || B->mParent == pNode);
951 FBX_ASSERT(C == 0 || C->mParent == lNode);
952 FBX_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
955 inline void RightRotate(RecordType* pNode)
957 RecordType* lNode = pNode->mLeftChild;
960 RecordType* A = lNode->mLeftChild;
961 RecordType* B = lNode->mRightChild;
962 RecordType* C = pNode->mRightChild;
963 RecordType* Z = pNode->mParent;
966 pNode->mLeftChild = lNode->mRightChild;
967 if (pNode->mLeftChild)
969 pNode->mLeftChild->mParent = pNode;
972 lNode->mParent = pNode->mParent;
973 if (pNode->mParent == 0)
975 FBX_ASSERT(mRoot == pNode);
978 else if (pNode == pNode->mParent->mRightChild)
980 pNode->mParent->mRightChild = lNode;
984 pNode->mParent->mLeftChild = lNode;
986 pNode->mParent = lNode;
987 lNode->mRightChild = pNode;
989 FBX_ASSERT(lNode->mLeftChild == A);
990 FBX_ASSERT(lNode->mRightChild == pNode);
991 FBX_ASSERT(lNode->mParent == Z);
993 FBX_ASSERT(pNode->mLeftChild == B);
994 FBX_ASSERT(pNode->mRightChild == C);
995 FBX_ASSERT(pNode->mParent == lNode);
997 FBX_ASSERT(A == 0 || A->mParent == lNode);
998 FBX_ASSERT(B == 0 || B->mParent == pNode);
999 FBX_ASSERT(C == 0 || C->mParent == pNode);
1000 FBX_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
1003 inline void RemoveNode(RecordType* pNode)
1005 if (pNode->mLeftChild == 0)
1007 if (pNode->mRightChild == 0)
1011 if (pNode->mParent->mLeftChild == pNode)
1013 pNode->mParent->mLeftChild = 0;
1015 else if (pNode->mParent->mRightChild == pNode)
1017 pNode->mParent->mRightChild = 0;
1021 FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
1026 FBX_ASSERT(mRoot == pNode);
1030 if (pNode->mColor == RecordType::eBlack)
1032 FixNodesAfterRemoval(pNode->mParent, 0);
1039 if (pNode->mParent->mLeftChild == pNode)
1041 pNode->mParent->mLeftChild = pNode->mRightChild;
1042 pNode->mRightChild->mParent = pNode->mParent;
1044 else if (pNode->mParent->mRightChild == pNode)
1046 pNode->mParent->mRightChild = pNode->mRightChild;
1047 pNode->mRightChild->mParent = pNode->mParent;
1051 FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
1056 FBX_ASSERT(mRoot == pNode);
1057 mRoot = pNode->mRightChild;
1058 pNode->mRightChild->mParent = 0;
1061 if (pNode->mColor == RecordType::eBlack)
1063 FixNodesAfterRemoval(pNode->mRightChild->mParent, pNode->mRightChild);
1069 if (pNode->mRightChild == 0)
1073 if (pNode->mParent->mLeftChild == pNode)
1075 pNode->mParent->mLeftChild = pNode->mLeftChild;
1076 pNode->mLeftChild->mParent = pNode->mParent;
1078 else if (pNode->mParent->mRightChild == pNode)
1080 pNode->mParent->mRightChild = pNode->mLeftChild;
1081 pNode->mLeftChild->mParent = pNode->mParent;
1085 FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
1090 FBX_ASSERT(mRoot == pNode);
1091 mRoot = pNode->mLeftChild;
1092 pNode->mLeftChild->mParent = 0;
1095 if (pNode->mColor == RecordType::eBlack)
1097 FixNodesAfterRemoval(pNode->mLeftChild->mParent, pNode->mLeftChild);
1102 RecordType* lMinRightNode = pNode->mRightChild->Minimum();
1103 RemoveNode(lMinRightNode);
1105 lMinRightNode->mColor = pNode->mColor;
1106 ReplaceNode(pNode, lMinRightNode);
1111 pNode->mLeftChild = 0;
1112 pNode->mRightChild = 0;
1115 inline void ReplaceNode(RecordType* pNodeToReplace, RecordType* pReplacement)
1117 pReplacement->mParent = pNodeToReplace->mParent;
1118 if (pNodeToReplace->mParent)
1120 if (pNodeToReplace->mParent->mLeftChild == pNodeToReplace)
1122 pNodeToReplace->mParent->mLeftChild = pReplacement;
1124 else if (pNodeToReplace->mParent->mRightChild == pNodeToReplace)
1126 pNodeToReplace->mParent->mRightChild = pReplacement;
1131 FBX_ASSERT(mRoot == pNodeToReplace);
1132 mRoot = pReplacement;
1135 pReplacement->mLeftChild = pNodeToReplace->mLeftChild;
1136 if (pReplacement->mLeftChild)
1138 pReplacement->mLeftChild->mParent = pReplacement;
1141 pReplacement->mRightChild = pNodeToReplace->mRightChild;
1142 if (pReplacement->mRightChild)
1144 pReplacement->mRightChild->mParent = pReplacement;
1148 inline RecordType* Sibling(
const RecordType* pParent,
const RecordType* pNode)
const
1152 if (pParent->mLeftChild == pNode)
1154 return pParent->mRightChild;
1156 else if (pParent->mRightChild == pNode)
1158 return pParent->mLeftChild;
1165 inline bool IsBlack(
const RecordType* pNode)
1167 return ((pNode == 0) || (pNode->mColor == RecordType::eBlack));
1170 inline void FixNodesAfterRemoval(RecordType* pParent, RecordType* pNode)
1172 RecordType* lParent = pParent;
1173 RecordType* lNode = pNode;
1180 if (!IsBlack(lNode))
1182 lNode->mColor = RecordType::eBlack;
1184 else if (lParent !=
NULL)
1186 RecordType* lSibling = Sibling(lParent, lNode);
1188 if (!IsBlack(lSibling))
1190 lParent->mColor = RecordType::eRed;
1191 lSibling->mColor = RecordType::eBlack;
1192 if (lNode == lParent->mLeftChild)
1194 LeftRotate(lParent);
1198 RightRotate(lParent);
1203 lSibling = Sibling(lParent, lNode);
1209 IsBlack(lSibling) &&
1210 IsBlack(lSibling->mLeftChild) &&
1211 IsBlack(lSibling->mRightChild))
1213 lSibling->mColor = RecordType::eRed;
1215 lParent = lParent->mParent;
1220 if (!IsBlack(lParent) &&
1221 IsBlack(lSibling) &&
1222 ((lSibling == 0) || IsBlack(lSibling->mLeftChild)) &&
1223 ((lSibling == 0) || IsBlack(lSibling->mRightChild)))
1227 lSibling->mColor = RecordType::eRed;
1229 lParent->mColor = RecordType::eBlack;
1231 else if( lSibling != 0 )
1233 if ((lNode == lParent->mLeftChild) &&
1234 IsBlack(lSibling) &&
1235 !IsBlack(lSibling->mLeftChild) &&
1236 IsBlack(lSibling->mRightChild))
1238 lSibling->mColor = RecordType::eRed;
1239 lSibling->mLeftChild->mColor = RecordType::eBlack;
1240 RightRotate(lSibling);
1242 else if ((lNode == lParent->mRightChild) &&
1243 IsBlack(lSibling) &&
1244 IsBlack(lSibling->mLeftChild) &&
1245 !IsBlack(lSibling->mRightChild))
1247 lSibling->mColor = RecordType::eRed;
1248 lSibling->mRightChild->mColor = RecordType::eBlack;
1249 LeftRotate(lSibling);
1253 lSibling = Sibling(lParent, lNode);
1254 FBX_ASSERT(lSibling != 0 && lParent != 0);
1259 if( lSibling != 0 && lParent != 0 )
1261 lSibling->mColor = lParent->mColor;
1262 lParent->mColor = RecordType::eBlack;
1263 if (lNode == lParent->mLeftChild)
1265 if (lSibling->mRightChild)
1267 lSibling->mRightChild->mColor = RecordType::eBlack;
1269 LeftRotate(lParent);
1273 if (lSibling->mLeftChild)
1275 lSibling->mLeftChild->mColor = RecordType::eBlack;
1277 RightRotate(lParent);
1287 mRoot->mColor = RecordType::eBlack;
1291 inline void ClearSubTree(RecordType* pNode)
1295 ClearSubTree(pNode->mLeftChild);
1296 ClearSubTree(pNode->mRightChild);
1297 pNode->~RecordType();
1298 mAllocator.FreeMemory(pNode);
1302 inline int GetSubTreeSize(RecordType* pNode)
const
1306 return GetSubTreeSize(pNode->mLeftChild) + GetSubTreeSize(pNode->mRightChild) + 1;
1315 inline void IsSane()
1317 FBX_ASSERT((mRoot == 0) || (mRoot->mColor == RecordType::eBlack));
1318 FBX_ASSERT(((mRoot == 0) && (mSize == 0)) || (mRoot != 0) && (mSize != 0));
1319 IsSubTreeSane(mRoot);
1321 ComputeBlackDepth(mRoot, 0);
1323 RecordType* lNode = mRoot;
1324 unsigned int lLeafBlackDepth = 0;
1327 if (lNode->mLeftChild == 0)
1329 lLeafBlackDepth = lNode->mBlackDepth + ((lNode->mColor == RecordType::eBlack) ? 1 : 0);
1332 lNode = lNode->mLeftChild;
1335 CheckLeavesBlackDepth(mRoot, lLeafBlackDepth);
1338 inline void IsSubTreeSane(
const RecordType* pNode)
const
1340 Compare lCompareKeys;
1344 FBX_ASSERT(pNode != pNode->mParent);
1345 FBX_ASSERT(pNode != pNode->mLeftChild);
1346 FBX_ASSERT(pNode != pNode->mRightChild);
1349 FBX_ASSERT((pNode->mColor == RecordType::eBlack) ||
1350 (pNode->mLeftChild ==
NULL) ||
1351 (pNode->mLeftChild->mColor == RecordType::eBlack));
1353 FBX_ASSERT((pNode->mColor == RecordType::eBlack) ||
1354 (pNode->mRightChild ==
NULL) ||
1355 (pNode->mRightChild->mColor == RecordType::eBlack));
1358 FBX_ASSERT((pNode->mLeftChild == 0 ||
1359 lCompareKeys(pNode->GetKey(), pNode->mLeftChild->GetKey()) > 0));
1361 FBX_ASSERT((pNode->mRightChild == 0 ||
1362 lCompareKeys(pNode->GetKey(), pNode->mRightChild->GetKey()) < 0));
1364 IsSubTreeSane(pNode->mLeftChild);
1365 IsSubTreeSane(pNode->mRightChild);
1369 inline void ComputeBlackDepth(RecordType* pNode,
unsigned int pDepth)
1373 pNode->mBlackDepth = pDepth;
1374 if( pNode->mColor == RecordType::eBlack )
1378 ComputeBlackDepth(pNode->mLeftChild, pDepth);
1379 ComputeBlackDepth(pNode->mRightChild, pDepth);
1383 inline void CheckLeavesBlackDepth(RecordType* pNode,
unsigned int pBlackDepth)
1387 if( pNode->mLeftChild == 0 || pNode->mRightChild == 0 )
1389 FBX_ASSERT((pNode->mBlackDepth + ((pNode->mColor == RecordType::eBlack) ? 1 : 0)) == pBlackDepth);
1391 CheckLeavesBlackDepth(pNode->mLeftChild, pBlackDepth);
1392 CheckLeavesBlackDepth(pNode->mRightChild, pBlackDepth);
FBX SDK environment definition.
This class template holds a pair of objects.