windows-nt/Source/XPSP1/NT/base/crts/crtw32/rtc/bintree.cpp
2020-09-26 16:20:57 +08:00

198 lines
4 KiB
C++

/***
*bintree.cpp - RTC support
*
* Copyright (c) 1998-2001, Microsoft Corporation. All rights reserved.
*
*
*Revision History:
* 07-28-98 JWM Module incorporated into CRTs (from KFrei)
* 11-03-98 KBF Removed alloca dependency for CRT independence
* 05-11-99 KBF Error if RTC support define not enabled
* 05-26-99 KBF Everything is now prefixed with _RTC_
*
****/
#ifndef _RTC
#error RunTime Check support not enabled!
#endif
#include "rtcpriv.h"
#ifdef _RTC_ADVMEM
void
_RTC_BinaryTree::BinaryNode::kill() throw()
{
if (l)
{
l->kill();
delete l;
}
if (r)
{
r->kill();
delete r;
}
delete val;
}
_RTC_Container *
_RTC_BinaryTree::get(_RTC_HeapBlock *data) throw()
{
BinaryNode *t = tree;
while (t)
{
if (t->val->contains(data))
return t->val;
if (*t->val->info() < *data)
t = t->l;
else
t = t->r;
}
return 0;
}
_RTC_Container *
_RTC_BinaryTree::add(_RTC_HeapBlock* data) throw()
{
BinaryNode *t = tree;
if (!tree)
{
tree = new BinaryNode(0,0,new _RTC_Container(data));
return tree->val;
}
for (;;)
{
if (*t->val->info() < *data)
{
// before this one
if (t->l)
t = t->l;
else
{
t->l = new BinaryNode(0,0,new _RTC_Container(data));
return t->l->val;
}
} else
{
if (t->r)
t = t->r;
else
{
t->r = new BinaryNode(0, 0, new _RTC_Container(data));
return t->r->val;
}
}
}
}
_RTC_Container *
_RTC_BinaryTree::del(_RTC_HeapBlock *data) throw()
{
BinaryNode **prv = &tree;
while (*prv && (*prv)->val->info() != data)
{
prv = (*(*prv)->val->info() < *data) ? &(*prv)->l : &(*prv)->r;
}
if (!*prv)
return 0;
BinaryNode *dl = *prv;
if (dl->r)
{
*prv = dl->r;
BinaryNode *left = dl->r;
while (left->l)
left = left->l;
left->l = dl->l;
} else
*prv = dl->l;
_RTC_Container* res = dl->val;
delete dl;
return res;
}
_RTC_Container *
_RTC_BinaryTree::FindNext(_RTC_BinaryTree::iter *i) throw()
{
// Return the next element from the iterator
// If the iterator is done, free up it's memory
if (++i->curSib >= i->totSibs)
{
VirtualFree(i->allSibs, 0, MEM_RELEASE);
i->curSib = i->totSibs = 0;
return 0;
} else
return i->allSibs[i->curSib];
}
_RTC_Container *
_RTC_BinaryTree::FindFirst(_RTC_BinaryTree::iter *i) throw()
{
// Initialize the iterator, and return it's first element
// Flatten the siblings into a nice array..
struct stk {
stk(stk *p, BinaryNode *i) : next(p), cur(i) {}
void *operator new(unsigned) {return _RTC_heap2->alloc();}
void operator delete(void *p) {_RTC_heap2->free(p);}
stk *next;
BinaryNode *cur;
};
stk *stack = new stk(0, this->tree);
stk *list = 0;
stk *tmp;
int count = 0;
// Build a list of all elements (reverse in-order traversal)
while (stack)
{
BinaryNode *cur = stack->cur;
tmp = stack;
stack = stack->next;
delete tmp;
while (cur)
{
list = new stk(list, cur);
count++;
if (cur->l)
stack = new stk(stack, cur->l);
cur = cur->r;
}
}
i->totSibs = 0;
i->curSib = 0;
if (!count)
{
i->allSibs = 0;
return 0;
}
i->allSibs = (_RTC_Container**)VirtualAlloc(0, sizeof(_RTC_Container*) * count,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
while (list)
{
i->allSibs[i->totSibs++] = list->cur->val;
tmp = list;
list = list->next;
delete tmp;
}
return i->allSibs[0];
}
#endif // _RTC_ADVMEM