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 const 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), mSize(0), mAllocator(sizeof(RecordType)) {}
432 inline FbxRedBlackTree(
const FbxRedBlackTree& pTree) : mRoot(0), mSize(0), mAllocator(sizeof(RecordType)) { operator=(pTree); }
433 inline ~FbxRedBlackTree() { Clear(); }
437 inline FbxRedBlackTree& operator=(
const FbxRedBlackTree& pTree)
443 mAllocator = pTree.mAllocator;
447 void* lBuffer = mAllocator.AllocateRecords();
448 mRoot =
new(lBuffer) RecordType(*(pTree.mRoot));
449 mRoot->mLeftChild = DuplicateSubTree(pTree.mRoot->mLeftChild);
450 mRoot->mRightChild = DuplicateSubTree(pTree.mRoot->mRightChild);
452 if (mRoot->mLeftChild)
454 mRoot->mLeftChild->mParent = mRoot;
457 if (mRoot->mRightChild)
459 mRoot->mRightChild->mParent = mRoot;
464 FBX_ASSERT( pTree.mSize == 0 );
465 FBX_ASSERT( mRoot == 0 );
474 inline bool operator==(
const FbxRedBlackTree& pTree)
const
480 if( GetSize() != pTree.GetSize() )
485 ConstIteratorType End;
486 ConstIteratorType Iter1(Minimum());
487 ConstIteratorType Iter2(pTree.Minimum());
489 while( (Iter1 != End) && (Iter2 != End) &&
490 (Iter1->GetKey() == Iter2->GetKey()) &&
491 (Iter1->GetValue() == Iter2->GetValue()) )
497 return Iter1 == End && Iter2 == End;
503 inline void Reserve(
unsigned int pRecordCount)
505 mAllocator.Reserve(pRecordCount);
511 inline int GetSize()
const {
return mSize; }
513 inline bool Empty()
const {
return mSize == 0; }
522 Compare lCompareKeys;
523 bool lResult =
false;
524 RecordType* lParent = 0;
525 RecordType* lNode = mRoot;
528 const KeyType& lNodeKey = lNode->GetKey();
529 const KeyType& lDataKey = pData.GetKey();
531 if (lCompareKeys(lNodeKey, lDataKey) < 0)
534 lNode = lNode->mRightChild;
536 else if (lCompareKeys(lNodeKey, lDataKey) > 0)
539 lNode = lNode->mLeftChild;
549 void* lBuffer = mAllocator.AllocateRecords();
550 lNode =
new(lBuffer) RecordType(pData);
553 FBX_ASSERT(lNode == lBuffer);
557 if (lCompareKeys(lParent->GetKey(), pData.GetKey()) < 0)
559 FBX_ASSERT(lParent->mRightChild == 0);
560 lParent->mRightChild = lNode;
561 lNode->mParent = lParent;
565 FBX_ASSERT(lParent->mLeftChild == 0);
566 lParent->mLeftChild = lNode;
567 lNode->mParent = lParent;
576 FixNodesAfterInsertion(lNode);
587 inline bool Remove(
const KeyType& pKey)
589 Compare lCompareKeys;
590 bool lResult =
false;
591 RecordType* lNode = mRoot;
594 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
596 lNode = lNode->mRightChild;
598 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
600 lNode = lNode->mLeftChild;
612 lNode->~RecordType();
613 mAllocator.FreeMemory(lNode);
627 ClearSubTree(mRoot->mLeftChild);
628 ClearSubTree(mRoot->mRightChild);
629 mRoot->~RecordType();
630 mAllocator.FreeMemory(mRoot);
639 inline const RecordType* Minimum()
const
643 return mRoot->Minimum();
654 inline RecordType* Minimum()
658 return mRoot->Minimum();
669 inline const RecordType* Maximum()
const
673 return mRoot->Maximum();
684 inline RecordType* Maximum()
688 return mRoot->Maximum();
700 inline const RecordType* Find(
const KeyType& pKey)
const
702 Compare lCompareKeys;
703 const RecordType* lNode = mRoot;
706 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
708 lNode = lNode->mRightChild;
710 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
712 lNode = lNode->mLeftChild;
727 inline RecordType* Find(
const KeyType& pKey)
729 Compare lCompareKeys;
730 RecordType* lNode = mRoot;
733 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
735 lNode = lNode->mRightChild;
737 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
739 lNode = lNode->mLeftChild;
754 inline const RecordType* UpperBound(
const KeyType& pKey)
const
756 Compare lCompareKeys;
757 const RecordType* lNode = mRoot;
758 const RecordType* lCandidate = 0;
761 if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
763 lNode = lNode->mRightChild;
765 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
768 lNode = lNode->mLeftChild;
779 inline RecordType* UpperBound(
const KeyType& pKey)
781 Compare lCompareKeys;
782 RecordType* lNode = mRoot;
783 RecordType* lCandidate = 0;
786 if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
788 lNode = lNode->mRightChild;
790 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
793 lNode = lNode->mLeftChild;
804 AllocatorType mAllocator;
806 inline RecordType* DuplicateSubTree(
const RecordType* pNode)
808 RecordType* lNewSubTree = 0;
812 void* lBuffer = mAllocator.AllocateRecords();
813 lNewSubTree =
new(lBuffer) RecordType(*pNode);
814 lNewSubTree->mLeftChild = DuplicateSubTree(pNode->mLeftChild);
815 lNewSubTree->mRightChild = DuplicateSubTree(pNode->mRightChild);
817 if (lNewSubTree->mLeftChild)
819 lNewSubTree->mLeftChild->mParent = lNewSubTree;
822 if (lNewSubTree->mRightChild)
824 lNewSubTree->mRightChild->mParent = lNewSubTree;
831 inline void FixNodesAfterInsertion(RecordType* pNode)
833 RecordType* lNode = pNode;
840 if (lNode->mParent == 0)
842 lNode->mColor = RecordType::eBlack;
844 else if (lNode->mParent->mColor == RecordType::eRed)
846 RecordType* lUncle = 0;
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;
858 if (lUncle && lUncle->mColor == RecordType::eRed)
860 lNode->mParent->mColor = RecordType::eBlack;
861 lUncle->mColor = RecordType::eBlack;
862 lNode->mParent->mParent->mColor = RecordType::eRed;
863 lNode = lNode->mParent->mParent;
869 if ((lNode == lNode->mParent->mRightChild) &&
870 (lNode->mParent == lNode->mParent->mParent->mLeftChild))
872 LeftRotate(lNode->mParent);
873 lNode = lNode->mLeftChild;
875 else if ((lNode == lNode->mParent->mLeftChild) &&
876 (lNode->mParent == lNode->mParent->mParent->mRightChild))
878 RightRotate(lNode->mParent);
879 lNode = lNode->mRightChild;
882 lNode->mParent->mColor = RecordType::eBlack;
883 lNode->mParent->mParent->mColor = RecordType::eRed;
884 if ((lNode == lNode->mParent->mLeftChild) &&
885 (lNode->mParent == lNode->mParent->mParent->mLeftChild))
887 RightRotate(lNode->mParent->mParent);
891 LeftRotate(lNode->mParent->mParent);
897 mRoot->mColor = RecordType::eBlack;
900 inline void LeftRotate(RecordType* pNode)
902 FBX_ASSERT_RETURN(pNode);
904 RecordType* lNode = pNode->mRightChild;
905 FBX_ASSERT_RETURN(lNode);
908 RecordType* A = pNode->mLeftChild;
909 RecordType* B = lNode->mLeftChild;
910 RecordType* C = lNode->mRightChild;
911 RecordType* Z = pNode->mParent;
914 pNode->mRightChild = lNode->mLeftChild;
915 if (pNode->mRightChild)
917 pNode->mRightChild->mParent = pNode;
920 lNode->mParent = pNode->mParent;
921 if (pNode->mParent == 0)
923 FBX_ASSERT(mRoot == pNode);
926 else if (pNode == pNode->mParent->mLeftChild)
928 pNode->mParent->mLeftChild = lNode;
932 pNode->mParent->mRightChild = lNode;
934 pNode->mParent = lNode;
935 lNode->mLeftChild = pNode;
937 FBX_ASSERT(pNode->mLeftChild == A);
938 FBX_ASSERT(pNode->mRightChild == B);
939 FBX_ASSERT(pNode->mParent == lNode);
941 FBX_ASSERT(lNode->mLeftChild == pNode);
942 FBX_ASSERT(lNode->mRightChild == C);
943 FBX_ASSERT(lNode->mParent == Z);
945 FBX_ASSERT(A == 0 || A->mParent == pNode);
946 FBX_ASSERT(B == 0 || B->mParent == pNode);
947 FBX_ASSERT(C == 0 || C->mParent == lNode);
948 FBX_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
951 inline void RightRotate(RecordType* pNode)
953 RecordType* lNode = pNode->mLeftChild;
956 RecordType* A = lNode->mLeftChild;
957 RecordType* B = lNode->mRightChild;
958 RecordType* C = pNode->mRightChild;
959 RecordType* Z = pNode->mParent;
962 pNode->mLeftChild = lNode->mRightChild;
963 if (pNode->mLeftChild)
965 pNode->mLeftChild->mParent = pNode;
968 lNode->mParent = pNode->mParent;
969 if (pNode->mParent == 0)
971 FBX_ASSERT(mRoot == pNode);
974 else if (pNode == pNode->mParent->mRightChild)
976 pNode->mParent->mRightChild = lNode;
980 pNode->mParent->mLeftChild = lNode;
982 pNode->mParent = lNode;
983 lNode->mRightChild = pNode;
985 FBX_ASSERT(lNode->mLeftChild == A);
986 FBX_ASSERT(lNode->mRightChild == pNode);
987 FBX_ASSERT(lNode->mParent == Z);
989 FBX_ASSERT(pNode->mLeftChild == B);
990 FBX_ASSERT(pNode->mRightChild == C);
991 FBX_ASSERT(pNode->mParent == lNode);
993 FBX_ASSERT(A == 0 || A->mParent == lNode);
994 FBX_ASSERT(B == 0 || B->mParent == pNode);
995 FBX_ASSERT(C == 0 || C->mParent == pNode);
996 FBX_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
999 inline void RemoveNode(RecordType* pNode)
1001 if (pNode->mLeftChild == 0)
1003 if (pNode->mRightChild == 0)
1007 if (pNode->mParent->mLeftChild == pNode)
1009 pNode->mParent->mLeftChild = 0;
1011 else if (pNode->mParent->mRightChild == pNode)
1013 pNode->mParent->mRightChild = 0;
1017 FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
1022 FBX_ASSERT(mRoot == pNode);
1026 if (pNode->mColor == RecordType::eBlack)
1028 FixNodesAfterRemoval(pNode->mParent, 0);
1035 if (pNode->mParent->mLeftChild == pNode)
1037 pNode->mParent->mLeftChild = pNode->mRightChild;
1038 pNode->mRightChild->mParent = pNode->mParent;
1040 else if (pNode->mParent->mRightChild == pNode)
1042 pNode->mParent->mRightChild = pNode->mRightChild;
1043 pNode->mRightChild->mParent = pNode->mParent;
1047 FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
1052 FBX_ASSERT(mRoot == pNode);
1053 mRoot = pNode->mRightChild;
1054 pNode->mRightChild->mParent = 0;
1057 if (pNode->mColor == RecordType::eBlack)
1059 FixNodesAfterRemoval(pNode->mRightChild->mParent, pNode->mRightChild);
1065 if (pNode->mRightChild == 0)
1069 if (pNode->mParent->mLeftChild == pNode)
1071 pNode->mParent->mLeftChild = pNode->mLeftChild;
1072 pNode->mLeftChild->mParent = pNode->mParent;
1074 else if (pNode->mParent->mRightChild == pNode)
1076 pNode->mParent->mRightChild = pNode->mLeftChild;
1077 pNode->mLeftChild->mParent = pNode->mParent;
1081 FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
1086 FBX_ASSERT(mRoot == pNode);
1087 mRoot = pNode->mLeftChild;
1088 pNode->mLeftChild->mParent = 0;
1091 if (pNode->mColor == RecordType::eBlack)
1093 FixNodesAfterRemoval(pNode->mLeftChild->mParent, pNode->mLeftChild);
1098 RecordType* lMinRightNode = pNode->mRightChild->Minimum();
1099 RemoveNode(lMinRightNode);
1101 lMinRightNode->mColor = pNode->mColor;
1102 ReplaceNode(pNode, lMinRightNode);
1107 pNode->mLeftChild = 0;
1108 pNode->mRightChild = 0;
1111 inline void ReplaceNode(RecordType* pNodeToReplace, RecordType* pReplacement)
1113 pReplacement->mParent = pNodeToReplace->mParent;
1114 if (pNodeToReplace->mParent)
1116 if (pNodeToReplace->mParent->mLeftChild == pNodeToReplace)
1118 pNodeToReplace->mParent->mLeftChild = pReplacement;
1120 else if (pNodeToReplace->mParent->mRightChild == pNodeToReplace)
1122 pNodeToReplace->mParent->mRightChild = pReplacement;
1127 FBX_ASSERT(mRoot == pNodeToReplace);
1128 mRoot = pReplacement;
1131 pReplacement->mLeftChild = pNodeToReplace->mLeftChild;
1132 if (pReplacement->mLeftChild)
1134 pReplacement->mLeftChild->mParent = pReplacement;
1137 pReplacement->mRightChild = pNodeToReplace->mRightChild;
1138 if (pReplacement->mRightChild)
1140 pReplacement->mRightChild->mParent = pReplacement;
1144 inline RecordType* Sibling(
const RecordType* pParent,
const RecordType* pNode)
const
1148 if (pParent->mLeftChild == pNode)
1150 return pParent->mRightChild;
1152 else if (pParent->mRightChild == pNode)
1154 return pParent->mLeftChild;
1161 inline bool IsBlack(
const RecordType* pNode)
1163 return ((pNode == 0) || (pNode->mColor == RecordType::eBlack));
1166 inline void FixNodesAfterRemoval(RecordType* pParent, RecordType* pNode)
1168 RecordType* lParent = pParent;
1169 RecordType* lNode = pNode;
1176 if (!IsBlack(lNode))
1178 lNode->mColor = RecordType::eBlack;
1180 else if (lParent !=
NULL)
1182 RecordType* lSibling = Sibling(lParent, lNode);
1184 if (!IsBlack(lSibling))
1186 lParent->mColor = RecordType::eRed;
1187 lSibling->mColor = RecordType::eBlack;
1188 if (lNode == lParent->mLeftChild)
1190 LeftRotate(lParent);
1194 RightRotate(lParent);
1199 lSibling = Sibling(lParent, lNode);
1205 IsBlack(lSibling) &&
1206 IsBlack(lSibling->mLeftChild) &&
1207 IsBlack(lSibling->mRightChild))
1209 lSibling->mColor = RecordType::eRed;
1211 lParent = lParent->mParent;
1216 if (!IsBlack(lParent) &&
1217 IsBlack(lSibling) &&
1218 ((lSibling == 0) || IsBlack(lSibling->mLeftChild)) &&
1219 ((lSibling == 0) || IsBlack(lSibling->mRightChild)))
1223 lSibling->mColor = RecordType::eRed;
1225 lParent->mColor = RecordType::eBlack;
1227 else if( lSibling != 0 )
1229 if ((lNode == lParent->mLeftChild) &&
1230 IsBlack(lSibling) &&
1231 !IsBlack(lSibling->mLeftChild) &&
1232 IsBlack(lSibling->mRightChild))
1234 lSibling->mColor = RecordType::eRed;
1235 lSibling->mLeftChild->mColor = RecordType::eBlack;
1236 RightRotate(lSibling);
1238 else if ((lNode == lParent->mRightChild) &&
1239 IsBlack(lSibling) &&
1240 IsBlack(lSibling->mLeftChild) &&
1241 !IsBlack(lSibling->mRightChild))
1243 lSibling->mColor = RecordType::eRed;
1244 lSibling->mRightChild->mColor = RecordType::eBlack;
1245 LeftRotate(lSibling);
1249 lSibling = Sibling(lParent, lNode);
1250 FBX_ASSERT(lSibling != 0 && lParent != 0);
1255 if( lSibling != 0 && lParent != 0 )
1257 lSibling->mColor = lParent->mColor;
1258 lParent->mColor = RecordType::eBlack;
1259 if (lNode == lParent->mLeftChild)
1261 if (lSibling->mRightChild)
1263 lSibling->mRightChild->mColor = RecordType::eBlack;
1265 LeftRotate(lParent);
1269 if (lSibling->mLeftChild)
1271 lSibling->mLeftChild->mColor = RecordType::eBlack;
1273 RightRotate(lParent);
1283 mRoot->mColor = RecordType::eBlack;
1287 inline void ClearSubTree(RecordType* pNode)
1291 ClearSubTree(pNode->mLeftChild);
1292 ClearSubTree(pNode->mRightChild);
1293 pNode->~RecordType();
1294 mAllocator.FreeMemory(pNode);
1298 inline int GetSubTreeSize(RecordType* pNode)
const
1302 return GetSubTreeSize(pNode->mLeftChild) + GetSubTreeSize(pNode->mRightChild) + 1;
1311 inline void IsSane()
1313 FBX_ASSERT((mRoot == 0) || (mRoot->mColor == RecordType::eBlack));
1314 FBX_ASSERT(((mRoot == 0) && (mSize == 0)) || (mRoot != 0) && (mSize != 0));
1315 IsSubTreeSane(mRoot);
1317 ComputeBlackDepth(mRoot, 0);
1319 RecordType* lNode = mRoot;
1320 unsigned int lLeafBlackDepth = 0;
1323 if (lNode->mLeftChild == 0)
1325 lLeafBlackDepth = lNode->mBlackDepth + ((lNode->mColor == RecordType::eBlack) ? 1 : 0);
1328 lNode = lNode->mLeftChild;
1331 CheckLeavesBlackDepth(mRoot, lLeafBlackDepth);
1334 inline void IsSubTreeSane(
const RecordType* pNode)
const
1336 Compare lCompareKeys;
1340 FBX_ASSERT(pNode != pNode->mParent);
1341 FBX_ASSERT(pNode != pNode->mLeftChild);
1342 FBX_ASSERT(pNode != pNode->mRightChild);
1345 FBX_ASSERT((pNode->mColor == RecordType::eBlack) ||
1346 (pNode->mLeftChild ==
NULL) ||
1347 (pNode->mLeftChild->mColor == RecordType::eBlack));
1349 FBX_ASSERT((pNode->mColor == RecordType::eBlack) ||
1350 (pNode->mRightChild ==
NULL) ||
1351 (pNode->mRightChild->mColor == RecordType::eBlack));
1354 FBX_ASSERT((pNode->mLeftChild == 0 ||
1355 lCompareKeys(pNode->GetKey(), pNode->mLeftChild->GetKey()) > 0));
1357 FBX_ASSERT((pNode->mRightChild == 0 ||
1358 lCompareKeys(pNode->GetKey(), pNode->mRightChild->GetKey()) < 0));
1360 IsSubTreeSane(pNode->mLeftChild);
1361 IsSubTreeSane(pNode->mRightChild);
1365 inline void ComputeBlackDepth(RecordType* pNode,
unsigned int pDepth)
1369 pNode->mBlackDepth = pDepth;
1370 if( pNode->mColor == RecordType::eBlack )
1374 ComputeBlackDepth(pNode->mLeftChild, pDepth);
1375 ComputeBlackDepth(pNode->mRightChild, pDepth);
1379 inline void CheckLeavesBlackDepth(RecordType* pNode,
unsigned int pBlackDepth)
1383 if( pNode->mLeftChild == 0 || pNode->mRightChild == 0 )
1385 FBX_ASSERT((pNode->mBlackDepth + ((pNode->mColor == RecordType::eBlack) ? 1 : 0)) == pBlackDepth);
1387 CheckLeavesBlackDepth(pNode->mLeftChild, pBlackDepth);
1388 CheckLeavesBlackDepth(pNode->mRightChild, pBlackDepth);
FBX SDK environment definition.
This class template holds a pair of objects.