25 #include "dCoreStdafx.h"
28 #include "dContainersAlloc.h"
50 D_CORE_API
void RemoveAllLow ();
56 D_CORE_API
inline void Initdata (
dRedBackNode*
const parent);
57 D_CORE_API
inline void SetColor (REDBLACK_COLOR color);
58 D_CORE_API REDBLACK_COLOR GetColor ()
const;
59 D_CORE_API dUnsigned32 IsInTree ()
const;
60 D_CORE_API
inline void SetInTreeFlag (dUnsigned32 flag);
62 D_CORE_API
void RemoveAll ();
74 dUnsigned32 m_color : 1;
75 dUnsigned32 m_inTree : 1;
78 template<
class OBJECT,
class KEY,
class allocator = dContainersAlloc<OBJECT> >
105 return (
dTreeNode* )dRedBackNode::m_left;
110 return (
dTreeNode* )dRedBackNode::m_right;
115 return (
dTreeNode* )dRedBackNode::m_parent;
120 dRedBackNode::m_left = node;
125 dRedBackNode::m_right = node;
130 dRedBackNode::m_parent = node;
134 const KEY& GetKey()
const
147 friend class dTree<OBJECT, KEY, allocator>;
165 m_ptr = m_tree->Minimum();
170 m_ptr = m_tree->Maximum();
178 operator dInt32()
const
180 return m_ptr !=
nullptr;
186 m_ptr = m_ptr->Next();
189 void operator++ (dInt32)
192 m_ptr = m_ptr->Next();
198 m_ptr = m_ptr->Prev();
201 void operator-- (dInt32)
204 m_ptr = m_ptr->Prev();
207 OBJECT &operator* ()
const
220 return tmp ? tmp->GetKey() : KEY(0);
236 operator dInt32()
const;
237 const dInt32 GetCount()
const;
246 dTreeNode* FindGreaterEqual (KEY key)
const;
247 dTreeNode* FindCreate(KEY key,
bool& wasFound);
249 dTreeNode* GetNodeFromInfo (OBJECT &info)
const;
251 dTreeNode* Insert (
const OBJECT &element, KEY key,
bool& wasFound);
252 dTreeNode* Insert (
const OBJECT &element, KEY key);
255 dTreeNode* Replace (OBJECT &element, KEY key);
256 dTreeNode* ReplaceKey (KEY oldKey, KEY newKey);
259 void Remove (KEY key);
264 void SwapInfo (
dTree& tree);
266 bool SanityCheck ()
const;
268 static void FlushFreeList()
270 allocator::FlushFreeList();
281 dInt32 CompareKeys (
const KEY &key0,
const KEY &key1)
const;
282 bool SanityCheck (dTreeNode*
const ptr, dInt32 height)
const;
284 friend class dTreeNode;
287 inline dRedBackNode::dRedBackNode (
dRedBackNode*
const parent)
292 inline void dRedBackNode::Initdata (
dRedBackNode*
const parent)
295 SetInTreeFlag (
true);
301 inline void dRedBackNode::SetColor (dRedBackNode::REDBLACK_COLOR color)
306 inline dRedBackNode::REDBLACK_COLOR dRedBackNode::GetColor ()
const
308 return REDBLACK_COLOR (m_color);
311 inline void dRedBackNode::SetInTreeFlag (dUnsigned32 flag)
316 inline dUnsigned32 dRedBackNode::IsInTree ()
const
321 template<
class OBJECT,
class KEY,
class allocator>
328 template<
class OBJECT,
class KEY,
class allocator>
334 template<
class OBJECT,
class KEY,
class allocator>
337 return m_head !=
nullptr;
340 template<
class OBJECT,
class KEY,
class allocator>
346 template<
class OBJECT,
class KEY,
class allocator>
349 return m_head ? (dTreeNode* )m_head->Minimum() :
nullptr;
352 template<
class OBJECT,
class KEY,
class allocator>
355 return m_head ? (dTreeNode* )m_head->Maximum() :
nullptr;
358 template<
class OBJECT,
class KEY,
class allocator>
364 template<
class OBJECT,
class KEY,
class allocator>
367 if (m_head ==
nullptr)
372 dTreeNode* ptr = m_head;
373 while (ptr !=
nullptr)
375 if (key < ptr->m_key)
377 dAssert (CompareKeys (ptr->m_key, key) == -1) ;
378 ptr = ptr->GetLeft();
380 else if (key > ptr->m_key)
382 dAssert (CompareKeys (ptr->m_key, key) == 1) ;
383 ptr = ptr->GetRight();
387 dAssert (CompareKeys (ptr->m_key, key) == 0) ;
394 template<
class OBJECT,
class KEY,
class allocator>
397 dTreeNode*
const node = (dTreeNode* ) &info;
398 dInt64 offset = ((
char*) &node->m_info) - ((
char *) node);
399 dTreeNode*
const retnode = (dTreeNode* ) (((
char *) node) - offset);
401 dAssert (retnode->IsInTree ());
402 dAssert (&retnode->GetInfo () == &info);
403 return (retnode->IsInTree ()) ? retnode :
nullptr;
406 template<
class OBJECT,
class KEY,
class allocator>
409 if (m_head ==
nullptr)
414 dTreeNode* prev =
nullptr;
415 dTreeNode* ptr = m_head;
417 while (ptr !=
nullptr)
419 if (key < ptr->m_key)
422 ptr = ptr->GetLeft();
426 ptr = ptr->GetRight();
430 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
433 Iterator iter (*
this);
434 for (iter.Begin(); iter.GetNode() != prev; iter ++)
436 KEY key1 = iter.GetKey();
437 dAssert (key1 <= key);
439 for (; iter.GetNode(); iter ++)
441 KEY key1 = iter.GetKey();
442 dAssert (key1 > key);
447 return (dTreeNode* )prev;
450 template<
class OBJECT,
class KEY,
class allocator>
453 if (m_head ==
nullptr)
458 dTreeNode* prev =
nullptr;
459 dTreeNode* ptr = m_head;
461 while (ptr !=
nullptr)
463 if (key == ptr->m_key)
467 if (key < ptr->m_key)
470 ptr = ptr->GetLeft();
474 ptr = ptr->GetRight();
478 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
481 Iterator iter (*
this);
482 for (iter.Begin(); iter.GetNode() != prev; iter ++)
484 KEY key1 = iter.GetKey();
485 dAssert (key1 <= key);
487 for (; iter.GetNode(); iter ++)
489 KEY key1 = iter.GetKey();
490 dAssert (key1 >= key);
495 return (dTreeNode* )prev;
498 template<
class OBJECT,
class KEY,
class allocator>
501 if (m_head ==
nullptr)
506 dTreeNode* prev =
nullptr;
507 dTreeNode* ptr = m_head;
509 while (ptr !=
nullptr)
511 if (key == ptr->m_key)
516 if (key < ptr->m_key)
518 ptr = ptr->GetLeft();
523 ptr = ptr->GetRight();
528 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
531 Iterator iter (*
this);
532 for (iter.End(); iter.GetNode() != prev; iter --)
534 KEY key1 = iter.GetKey();
535 dAssert (key1 >= key);
537 for (; iter.GetNode(); iter --)
539 KEY key1 = iter.GetKey();
540 dAssert (key1 < key);
545 return (dTreeNode* )prev;
548 template<
class OBJECT,
class KEY,
class allocator>
551 dTreeNode* parent =
nullptr;
552 dTreeNode* ptr = m_head;
554 while (ptr !=
nullptr)
558 if (key < ptr->m_key)
560 dAssert (CompareKeys (ptr->m_key, key) == -1) ;
562 ptr = ptr->GetLeft();
564 else if (key > ptr->m_key)
566 dAssert (CompareKeys (ptr->m_key, key) == 1) ;
568 ptr = ptr->GetRight();
572 dAssert (CompareKeys (ptr->m_key, key) == 0) ;
580 ptr =
new dTreeNode (element, key, parent);
589 parent->m_left = ptr;
593 parent->m_right = ptr;
597 dTreeNode**
const headPtr = (dTreeNode**) &m_head;
602 template<
class OBJECT,
class KEY,
class allocator>
605 dTreeNode* parent =
nullptr;
606 dTreeNode* ptr = m_head;
608 while (ptr !=
nullptr)
611 if (key < ptr->m_key)
613 dAssert(CompareKeys(ptr->m_key, key) == -1);
615 ptr = ptr->GetLeft();
617 else if (key > ptr->m_key)
619 dAssert(CompareKeys(ptr->m_key, key) == 1);
621 ptr = ptr->GetRight();
625 dAssert(CompareKeys(ptr->m_key, key) == 0);
633 ptr =
new dTreeNode(key, parent);
642 parent->m_left = ptr;
646 parent->m_right = ptr;
650 dTreeNode**
const headPtr = (dTreeNode**)&m_head;
655 template<
class OBJECT,
class KEY,
class allocator>
660 dTreeNode*
const node = Insert (element, key, foundState);
668 template<
class OBJECT,
class KEY,
class allocator>
672 dTreeNode* ptr = m_head;
673 dTreeNode* parent =
nullptr;
674 while (ptr !=
nullptr)
678 if (key < ptr->m_key)
680 dAssert (CompareKeys (ptr->m_key, key) == -1) ;
682 ptr = ptr->GetLeft();
684 else if (key > ptr->m_key)
686 dAssert (CompareKeys (ptr->m_key, key) == 1) ;
688 ptr = ptr->GetRight();
692 dAssert (CompareKeys (ptr->m_key, key) == 0) ;
701 ptr->Initdata (parent);
711 parent->m_left = ptr;
715 parent->m_right = ptr;
719 dTreeNode**
const headPtr = (dTreeNode**) &m_head;
724 template<
class OBJECT,
class KEY,
class allocator>
727 dTreeNode* parent =
nullptr;
728 dTreeNode* ptr = m_head;
731 while (ptr !=
nullptr)
736 val = CompareKeys (ptr->m_key, key);
739 ptr->m_info = element;
744 ptr = ptr->GetLeft();
748 ptr = ptr->GetRight();
752 dAssert (m_allocator);
753 ptr =
new dTreeNode (element, key, parent);
762 parent->m_left = ptr;
766 parent->m_right = ptr;
770 dTreeNode**
const headPtr = (dTreeNode**) &m_head;
775 template<
class OBJECT,
class KEY,
class allocator>
779 dTreeNode*
const ptr = Insert (node, key);
784 template<
class OBJECT,
class KEY,
class allocator>
787 dTreeNode*
const node = Find (oldKey);
788 return node ? ReplaceKey (node, newKey) : nullptr;
791 template<
class OBJECT,
class KEY,
class allocator>
796 dTreeNode**
const headPtr = (dTreeNode**) &m_head;
798 dAssert (!Find (node->GetKey()));
801 template<
class OBJECT,
class KEY,
class allocator>
805 dTreeNode**
const headPtr = (dTreeNode**) &m_head;
809 template<
class OBJECT,
class KEY,
class allocator>
813 dTreeNode*
const node = Find (key);
820 template<
class OBJECT,
class KEY,
class allocator>
826 m_head->RemoveAll ();
831 template<
class OBJECT,
class KEY,
class allocator>
834 return SanityCheck (m_head, 0);
837 template<
class OBJECT,
class KEY,
class allocator>
845 if (!ptr->IsInTree())
852 if (CompareKeys (ptr->m_key, ptr->GetLeft()->m_key) > 0)
860 if (CompareKeys (ptr->m_key, ptr->GetRight()->m_key) < 0)
866 if (ptr->GetColor() == dTreeNode::BLACK)
870 else if (!((!ptr->m_left || (ptr->m_left->GetColor() == dTreeNode::BLACK)) &&
871 (!ptr->m_right || (ptr->m_right->GetColor() == dTreeNode::BLACK))))
876 if (!ptr->m_left && !ptr->m_right)
879 for (dTreeNode* x = ptr; x; x = x->GetParent())
881 if (x->GetColor() == dTreeNode::BLACK)
892 if (ptr->m_left && !SanityCheck (ptr->GetLeft(), height))
897 if (ptr->m_right && !SanityCheck (ptr->GetRight(), height))
904 template<
class OBJECT,
class KEY,
class allocator>
918 template<
class OBJECT,
class KEY,
class allocator>
921 dSwap (m_head, tree.m_head);
922 dSwap (m_count, tree.m_count);