Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
4.2 KiB

  1. /***
  2. *bintree.cpp - RTC support
  3. *
  4. * Copyright (c) 1998-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *
  7. *Revision History:
  8. * 07-28-98 JWM Module incorporated into CRTs (from KFrei)
  9. * 11-03-98 KBF Removed alloca dependency for CRT independence
  10. * 05-11-99 KBF Error if RTC support define not enabled
  11. * 05-26-99 KBF Everything is now prefixed with _RTC_
  12. *
  13. ****/
  14. #ifndef _RTC
  15. #error RunTime Check support not enabled!
  16. #endif
  17. #include "rtcpriv.h"
  18. #ifdef _RTC_ADVMEM
  19. void
  20. _RTC_BinaryTree::BinaryNode::kill() throw()
  21. {
  22. if (l)
  23. {
  24. l->kill();
  25. delete l;
  26. }
  27. if (r)
  28. {
  29. r->kill();
  30. delete r;
  31. }
  32. delete val;
  33. }
  34. _RTC_Container *
  35. _RTC_BinaryTree::get(_RTC_HeapBlock *data) throw()
  36. {
  37. BinaryNode *t = tree;
  38. while (t)
  39. {
  40. if (t->val->contains(data))
  41. return t->val;
  42. if (*t->val->info() < *data)
  43. t = t->l;
  44. else
  45. t = t->r;
  46. }
  47. return 0;
  48. }
  49. _RTC_Container *
  50. _RTC_BinaryTree::add(_RTC_HeapBlock* data) throw()
  51. {
  52. BinaryNode *t = tree;
  53. if (!tree)
  54. {
  55. tree = new BinaryNode(0,0,new _RTC_Container(data));
  56. return tree->val;
  57. }
  58. for (;;)
  59. {
  60. if (*t->val->info() < *data)
  61. {
  62. // before this one
  63. if (t->l)
  64. t = t->l;
  65. else
  66. {
  67. t->l = new BinaryNode(0,0,new _RTC_Container(data));
  68. return t->l->val;
  69. }
  70. } else
  71. {
  72. if (t->r)
  73. t = t->r;
  74. else
  75. {
  76. t->r = new BinaryNode(0, 0, new _RTC_Container(data));
  77. return t->r->val;
  78. }
  79. }
  80. }
  81. }
  82. _RTC_Container *
  83. _RTC_BinaryTree::del(_RTC_HeapBlock *data) throw()
  84. {
  85. BinaryNode **prv = &tree;
  86. while (*prv && (*prv)->val->info() != data)
  87. {
  88. prv = (*(*prv)->val->info() < *data) ? &(*prv)->l : &(*prv)->r;
  89. }
  90. if (!*prv)
  91. return 0;
  92. BinaryNode *dl = *prv;
  93. if (dl->r)
  94. {
  95. *prv = dl->r;
  96. BinaryNode *left = dl->r;
  97. while (left->l)
  98. left = left->l;
  99. left->l = dl->l;
  100. } else
  101. *prv = dl->l;
  102. _RTC_Container* res = dl->val;
  103. delete dl;
  104. return res;
  105. }
  106. _RTC_Container *
  107. _RTC_BinaryTree::FindNext(_RTC_BinaryTree::iter *i) throw()
  108. {
  109. // Return the next element from the iterator
  110. // If the iterator is done, free up it's memory
  111. if (++i->curSib >= i->totSibs)
  112. {
  113. VirtualFree(i->allSibs, 0, MEM_RELEASE);
  114. i->curSib = i->totSibs = 0;
  115. return 0;
  116. } else
  117. return i->allSibs[i->curSib];
  118. }
  119. _RTC_Container *
  120. _RTC_BinaryTree::FindFirst(_RTC_BinaryTree::iter *i) throw()
  121. {
  122. // Initialize the iterator, and return it's first element
  123. // Flatten the siblings into a nice array..
  124. struct stk {
  125. stk(stk *p, BinaryNode *i) : next(p), cur(i) {}
  126. void *operator new(unsigned) {return _RTC_heap2->alloc();}
  127. void operator delete(void *p) {_RTC_heap2->free(p);}
  128. stk *next;
  129. BinaryNode *cur;
  130. };
  131. stk *stack = new stk(0, this->tree);
  132. stk *list = 0;
  133. stk *tmp;
  134. int count = 0;
  135. // Build a list of all elements (reverse in-order traversal)
  136. while (stack)
  137. {
  138. BinaryNode *cur = stack->cur;
  139. tmp = stack;
  140. stack = stack->next;
  141. delete tmp;
  142. while (cur)
  143. {
  144. list = new stk(list, cur);
  145. count++;
  146. if (cur->l)
  147. stack = new stk(stack, cur->l);
  148. cur = cur->r;
  149. }
  150. }
  151. i->totSibs = 0;
  152. i->curSib = 0;
  153. if (!count)
  154. {
  155. i->allSibs = 0;
  156. return 0;
  157. }
  158. i->allSibs = (_RTC_Container**)VirtualAlloc(0, sizeof(_RTC_Container*) * count,
  159. MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  160. while (list)
  161. {
  162. i->allSibs[i->totSibs++] = list->cur->val;
  163. tmp = list;
  164. list = list->next;
  165. delete tmp;
  166. }
  167. return i->allSibs[0];
  168. }
  169. #endif // _RTC_ADVMEM