Source code of Windows XP (NT5)
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.

276 lines
4.8 KiB

  1. /****************************************************************************************
  2. * NAME: MeritNode.h
  3. *
  4. * OVERVIEW
  5. *
  6. * Helper classes : node with merit value array
  7. *
  8. *
  9. * Copyright (C) Microsoft Corporation, 1998 - 1999 . All Rights Reserved.
  10. *
  11. * History:
  12. * 1/28/98 Created by Byao (using ATL wizard)
  13. *
  14. *****************************************************************************************/
  15. /****************************************************************************************
  16. * CLASS: CMeritNodeArray
  17. *
  18. * OVERVIEW
  19. *
  20. * A template class that implements an array of nodes with merit value.
  21. * This can facilitate the manipulation for policy nodes. The sort is
  22. * assumed to be in ascending order
  23. *
  24. * History:
  25. * 2/9/98 Created by Byao
  26. *
  27. * Comment: 1) The implementation is based on ATL implementation of CSimpleArray
  28. * 2) class T must implement SetMerit() and operator ">"
  29. *
  30. *****************************************************************************************/
  31. template <class T>
  32. class CMeritNodeArray
  33. {
  34. public:
  35. T* m_aT;
  36. int m_nSize;
  37. // Construction/destruction
  38. CMeritNodeArray() : m_aT(NULL), m_nSize(0)
  39. { }
  40. ~CMeritNodeArray()
  41. {
  42. RemoveAll();
  43. }
  44. // Operations
  45. int GetSize() const
  46. {
  47. return m_nSize;
  48. }
  49. //
  50. // add an item into the array while keeping the internal order
  51. //
  52. BOOL NormalizeMerit(T t)
  53. {
  54. // the right position in the array
  55. for(int i = 0; i < m_nSize; i++)
  56. {
  57. m_aT[i]->SetMerit(i+1);
  58. }
  59. return TRUE;
  60. }
  61. //
  62. // add an item into the array while keeping the internal order
  63. //
  64. BOOL Add(T t)
  65. {
  66. int i, j;
  67. T* aT = NULL;
  68. if ( !m_aT)
  69. {
  70. aT = (T*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(T) );
  71. }
  72. else
  73. {
  74. aT = (T*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, m_aT, (m_nSize + 1) * sizeof(T));
  75. }
  76. if(aT == NULL)
  77. return FALSE;
  78. m_aT = aT;
  79. m_nSize++;
  80. //
  81. // search for the right position to insert this item
  82. // Please note: class T needs to implement the operator ">"
  83. //
  84. if (t->GetMerit())
  85. {
  86. // The new node already has a merit value: then search for
  87. // the right position in the array
  88. for(i = 0; i < m_nSize-1; i++)
  89. {
  90. if(m_aT[i]->GetMerit() > t->GetMerit())
  91. break;
  92. }
  93. //
  94. // we've found the right spot, now we move the items downward,
  95. // so we can have a space to insert the new items
  96. //
  97. for (j = m_nSize-1; j > i ; j--)
  98. {
  99. m_aT[j] = m_aT[j-1];
  100. }
  101. }
  102. else
  103. {
  104. // new node: insert at the end
  105. i = m_nSize-1;
  106. }
  107. //
  108. // now insert the item at the spot
  109. //
  110. SetAtIndex(i, t);
  111. return TRUE;
  112. }
  113. //
  114. // remove an item from the array, while keeping the internal order
  115. //
  116. BOOL Remove(T t)
  117. {
  118. int nIndex = Find(t);
  119. if(nIndex == -1)
  120. return FALSE;
  121. if(nIndex != (m_nSize - 1))
  122. {
  123. for (int i=nIndex; i<m_nSize-1; i++)
  124. {
  125. m_aT[i] = m_aT[i+1];
  126. m_aT[i]->SetMerit(i+1);
  127. }
  128. }
  129. T* aT = (T*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, m_aT, (m_nSize - 1) * sizeof(T));
  130. if(aT != NULL || m_nSize == 1)
  131. m_aT = aT;
  132. m_nSize--;
  133. return TRUE;
  134. }
  135. //
  136. // remove all the nodes from the array
  137. //
  138. void RemoveAll()
  139. {
  140. if(m_nSize > 0)
  141. {
  142. HeapFree(GetProcessHeap(), 0, m_aT);
  143. m_aT = NULL;
  144. m_nSize = 0;
  145. }
  146. }
  147. //
  148. // Move up the child one spot
  149. //
  150. BOOL MoveUp(T t)
  151. {
  152. int nIndex = Find(t);
  153. T temp;
  154. if(nIndex == -1)
  155. {
  156. // the item "t" not found in the array
  157. return FALSE;
  158. }
  159. if (nIndex == 0)
  160. {
  161. // "t" is at the top of the array -- do nothing
  162. return TRUE;
  163. }
  164. //
  165. // exchange "t" and the one on top of "t".
  166. //
  167. temp = m_aT[nIndex-1];
  168. m_aT[nIndex-1] = m_aT[nIndex];
  169. m_aT[nIndex] = temp;
  170. m_aT[nIndex-1]->SetMerit(nIndex);
  171. m_aT[nIndex]->SetMerit(nIndex+1);
  172. return TRUE;
  173. }
  174. //
  175. // move down the child one spot
  176. //
  177. BOOL MoveDown(T t)
  178. {
  179. int nIndex = Find(t);
  180. T temp;
  181. if(nIndex == -1)
  182. {
  183. // the item "t" not found in the array
  184. return FALSE;
  185. }
  186. if (nIndex == m_nSize-1)
  187. {
  188. // "t" is at the bottom of the array -- do nothing
  189. return TRUE;
  190. }
  191. //
  192. // exchange "t" and the one below "t".
  193. //
  194. temp = m_aT[nIndex+1];
  195. m_aT[nIndex+1] = m_aT[nIndex];
  196. m_aT[nIndex] = temp;
  197. m_aT[nIndex+1]->SetMerit(nIndex+2);
  198. m_aT[nIndex]->SetMerit(nIndex+1);
  199. return TRUE;
  200. }
  201. T& operator[] (int nIndex) const
  202. {
  203. _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
  204. return m_aT[nIndex];
  205. }
  206. T* GetData() const
  207. {
  208. return m_aT;
  209. }
  210. //
  211. // insert the node at position nIndex
  212. //
  213. void SetAtIndex(int nIndex, T& t)
  214. {
  215. _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
  216. m_aT[nIndex] = t;
  217. if ( !t->GetMerit() )
  218. {
  219. // assign merit value only if it doesn't have one
  220. t->SetMerit(nIndex+1);
  221. }
  222. }
  223. int Find(T& t) const
  224. {
  225. for(int i = 0; i < m_nSize; i++)
  226. {
  227. if(m_aT[i] == t)
  228. return i;
  229. }
  230. return -1; // not found
  231. }
  232. };