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.

454 lines
9.6 KiB

  1. #ifndef __PRIORITYQUEUE_CPP
  2. #define __PRIORITYQUEUE_CPP
  3. template <class WmiKey,class WmiElement,ULONG ElementSize>
  4. BOOL operator< (
  5. const WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: WmiKeyElementPair &a_Arg1 ,
  6. const WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: WmiKeyElementPair &a_Arg2
  7. )
  8. {
  9. if ( a_Arg1.m_Key < a_Arg2.m_Key )
  10. {
  11. return TRUE ;
  12. }
  13. return FALSE ;
  14. }
  15. template <class WmiKey,class WmiElement,ULONG ElementSize>
  16. BOOL operator== (
  17. const WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: WmiKeyElementPair &a_Arg1 ,
  18. const WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: WmiKeyElementPair &a_Arg2
  19. )
  20. {
  21. if ( a_Arg1.m_Key == a_Arg2.m_Key )
  22. {
  23. return TRUE ;
  24. }
  25. return FALSE ;
  26. }
  27. /******************************************************************************
  28. *
  29. * Name:
  30. *
  31. *
  32. * Description:
  33. *
  34. *
  35. *****************************************************************************/
  36. template <class WmiKey,class WmiElement,ULONG ElementSize>
  37. WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: WmiPriorityQueue (
  38. WmiAllocator &a_Allocator
  39. ) : m_Allocator ( a_Allocator ) ,
  40. m_Size ( 0 ) ,
  41. m_Array ( a_Allocator )
  42. {
  43. }
  44. /******************************************************************************
  45. *
  46. * Name:
  47. *
  48. *
  49. * Description:
  50. *
  51. *
  52. *****************************************************************************/
  53. template <class WmiKey,class WmiElement,ULONG ElementSize>
  54. WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: ~WmiPriorityQueue ()
  55. {
  56. WmiStatusCode t_StatusCode = UnInitialize () ;
  57. }
  58. /******************************************************************************
  59. *
  60. * Name:
  61. *
  62. *
  63. * Description:
  64. *
  65. *
  66. *****************************************************************************/
  67. template <class WmiKey,class WmiElement,ULONG ElementSize>
  68. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: Initialize ()
  69. {
  70. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  71. t_StatusCode = m_Array.Initialize ( 1 << ElementSize ) ;
  72. return t_StatusCode ;
  73. }
  74. /******************************************************************************
  75. *
  76. * Name:
  77. *
  78. *
  79. * Description:
  80. *
  81. *
  82. *****************************************************************************/
  83. template <class WmiKey,class WmiElement,ULONG ElementSize>
  84. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: UnInitialize ()
  85. {
  86. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  87. t_StatusCode = m_Array.UnInitialize () ;
  88. return t_StatusCode ;
  89. }
  90. /******************************************************************************
  91. *
  92. * Name:
  93. *
  94. *
  95. * Description:
  96. *
  97. *
  98. *****************************************************************************/
  99. template <class WmiKey,class WmiElement,ULONG ElementSize>
  100. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: ShuffleDown (
  101. ULONG a_Index
  102. )
  103. {
  104. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  105. if ( m_Size > 1 )
  106. {
  107. WmiKeyElementPair t_KeyElementPair ;
  108. t_StatusCode = m_Array.Get ( t_KeyElementPair , a_Index ) ;
  109. if ( t_StatusCode == e_StatusCode_Success )
  110. {
  111. ULONG t_LargestIndex = a_Index ;
  112. ULONG t_LeftIndex = LEFT ( a_Index ) ;
  113. ULONG t_RightIndex = RIGHT ( a_Index ) ;
  114. if ( t_LeftIndex < m_Size - 1 )
  115. {
  116. WmiKeyElementPair t_Compare ;
  117. t_StatusCode = m_Array.Get ( t_Compare , t_LeftIndex ) ;
  118. if ( CompareElement ( t_Compare.m_Key , t_KeyElementPair.m_Key ) > 0 )
  119. {
  120. t_LargestIndex = t_LeftIndex ;
  121. }
  122. else
  123. {
  124. t_LargestIndex = a_Index ;
  125. }
  126. }
  127. if ( t_RightIndex < m_Size - 1 )
  128. {
  129. WmiKeyElementPair t_CompareKeyElementPair ;
  130. WmiKeyElementPair t_LargestKeyElementPair ;
  131. t_StatusCode = m_Array.Get ( t_CompareKeyElementPair , t_RightIndex ) ;
  132. t_StatusCode = m_Array.Get ( t_LargestKeyElementPair , t_LargestIndex ) ;
  133. if ( CompareElement ( t_CompareKeyElementPair.m_Key , t_LargestKeyElementPair.m_Key ) > 0 )
  134. {
  135. t_LargestIndex = t_RightIndex ;
  136. }
  137. }
  138. if ( t_LargestIndex != a_Index )
  139. {
  140. WmiKeyElementPair t_KeyElementPair ;
  141. WmiKeyElementPair t_LargestKeyElementPair ;
  142. t_StatusCode = m_Array.Get ( t_KeyElementPair , a_Index ) ;
  143. t_StatusCode = m_Array.Get ( t_LargestKeyElementPair , t_LargestIndex ) ;
  144. t_StatusCode = m_Array.Set ( t_KeyElementPair , t_LargestIndex ) ;
  145. t_StatusCode = m_Array.Set ( t_LargestKeyElementPair , a_Index ) ;
  146. t_StatusCode = ShuffleDown ( t_LargestIndex ) ;
  147. }
  148. }
  149. }
  150. return t_StatusCode ;
  151. }
  152. /******************************************************************************
  153. *
  154. * Name:
  155. *
  156. *
  157. * Description:
  158. *
  159. *
  160. *****************************************************************************/
  161. template <class WmiKey,class WmiElement,ULONG ElementSize>
  162. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: ShuffleUp (
  163. const WmiKeyElementPair &a_KeyElementPair ,
  164. ULONG a_Index
  165. )
  166. {
  167. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  168. ULONG t_Index = a_Index ;
  169. do
  170. {
  171. if ( t_Index > 0 )
  172. {
  173. WmiKeyElementPair t_Compare ;
  174. t_StatusCode = m_Array.Get ( t_Compare , PARENT ( t_Index ) ) ;
  175. if ( t_StatusCode == e_StatusCode_Success )
  176. {
  177. if ( CompareElement ( t_Compare.m_Key , a_KeyElementPair.m_Key ) < 0 )
  178. {
  179. t_StatusCode = m_Array.Set ( t_Compare , t_Index ) ;
  180. if ( t_StatusCode == e_StatusCode_Success )
  181. {
  182. t_Index = PARENT ( t_Index ) ;
  183. }
  184. else
  185. {
  186. break ;
  187. }
  188. }
  189. else
  190. {
  191. break ;
  192. }
  193. }
  194. else
  195. {
  196. break ;
  197. }
  198. }
  199. else
  200. {
  201. break ;
  202. }
  203. }
  204. while ( TRUE ) ;
  205. if ( t_StatusCode == e_StatusCode_Success )
  206. {
  207. t_StatusCode = m_Array.Set ( a_KeyElementPair , t_Index ) ;
  208. }
  209. return t_StatusCode ;
  210. }
  211. /******************************************************************************
  212. *
  213. * Name:
  214. *
  215. *
  216. * Description:
  217. *
  218. *
  219. *****************************************************************************/
  220. template <class WmiKey,class WmiElement,ULONG ElementSize>
  221. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: EnQueue (
  222. const WmiKey &a_Key ,
  223. const WmiElement &a_Element
  224. )
  225. {
  226. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  227. if ( m_Size >= m_Array.Size () )
  228. {
  229. t_StatusCode = m_Array.Grow ( m_Size + ( 1 << ElementSize ) ) ;
  230. }
  231. if ( t_StatusCode == e_StatusCode_Success )
  232. {
  233. m_Size ++ ;
  234. WmiKeyElementPair t_KeyElementPair ;
  235. try
  236. {
  237. t_KeyElementPair.m_Key = a_Key ,
  238. t_KeyElementPair.m_Element = a_Element ,
  239. }
  240. catch ( Wmi_Heap_Exception &a_Exception )
  241. {
  242. m_Size -- ;
  243. return e_StatusCode_OutOfMemory ;
  244. }
  245. catch ( ... )
  246. {
  247. m_Size -- ;
  248. return e_StatusCode_Unknown ;
  249. }
  250. t_StatusCode = ShuffleUp ( t_KeyElementPair , m_Size - 1 ) ;
  251. }
  252. return t_StatusCode ;
  253. }
  254. /******************************************************************************
  255. *
  256. * Name:
  257. *
  258. *
  259. * Description:
  260. *
  261. *
  262. *****************************************************************************/
  263. template <class WmiKey,class WmiElement,ULONG ElementSize>
  264. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: Top (
  265. Iterator &a_Iterator
  266. )
  267. {
  268. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  269. if ( m_Size )
  270. {
  271. a_Iterator = Iterator ( this , 0 ) ;
  272. }
  273. else
  274. {
  275. t_StatusCode = e_StatusCode_NotInitialized ;
  276. }
  277. return t_StatusCode ;
  278. }
  279. /******************************************************************************
  280. *
  281. * Name:
  282. *
  283. *
  284. * Description:
  285. *
  286. *
  287. *****************************************************************************/
  288. template <class WmiKey,class WmiElement,ULONG ElementSize>
  289. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: Top (
  290. WmiKey &a_Key ,
  291. WmiElement &a_Element
  292. )
  293. {
  294. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  295. if ( m_Size )
  296. {
  297. WmiArray <WmiKeyElementPair> :: Iterator t_Iterator ;
  298. t_StatusCode = m_Array.Get ( t_Iterator , 0 ) ;
  299. if ( t_StatusCode == e_StatusCode_Success )
  300. {
  301. WmiKeyElementPair &t_KeyElementPair = t_Iterator.GetElement () ;
  302. try
  303. {
  304. a_Key = t_KeyElementPair.m_Key ;
  305. a_Element = t_KeyElementPair.m_Element ;
  306. }
  307. catch ( Wmi_Heap_Exception &a_Exception )
  308. {
  309. return e_StatusCode_OutOfMemory ;
  310. }
  311. catch ( ... )
  312. {
  313. return e_StatusCode_Unknown ;
  314. }
  315. }
  316. }
  317. else
  318. {
  319. t_StatusCode = e_StatusCode_NotInitialized ;
  320. }
  321. return t_StatusCode ;
  322. }
  323. /******************************************************************************
  324. *
  325. * Name:
  326. *
  327. *
  328. * Description:
  329. *
  330. *
  331. *****************************************************************************/
  332. template <class WmiKey,class WmiElement,ULONG ElementSize>
  333. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: DeQueue ()
  334. {
  335. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  336. if ( m_Size )
  337. {
  338. m_Size -- ;
  339. WmiKeyElementPair t_KeyElementPair ;
  340. t_StatusCode = m_Array.Get ( t_KeyElementPair , m_Size ) ;
  341. if t_StatusCode == e_StatusCode_Success )
  342. {
  343. t_StatusCode = m_Array.Set ( t_KeyElementPair , 0 ) ;
  344. }
  345. if t_StatusCode == e_StatusCode_Success )
  346. {
  347. t_StatusCode = ShuffleDown ( 0 ) ;
  348. }
  349. }
  350. else
  351. {
  352. t_StatusCode = e_StatusCode_NotInitialized ;
  353. }
  354. return t_StatusCode ;
  355. }
  356. /******************************************************************************
  357. *
  358. * Name:
  359. *
  360. *
  361. * Description:
  362. *
  363. *
  364. *****************************************************************************/
  365. template <class WmiKey,class WmiElement,ULONG ElementSize>
  366. WmiStatusCode WmiPriorityQueue <WmiKey,WmiElement,ElementSize> :: Sort ()
  367. {
  368. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  369. if ( m_Size )
  370. {
  371. t_StatusCode = QuickSort <WmiArray<WmiKeyElementPair>,WmiKeyElementPair> ( m_Array , m_Size ) ;
  372. }
  373. else
  374. {
  375. t_StatusCode = e_StatusCode_NotInitialized ;
  376. }
  377. return t_StatusCode ;
  378. }
  379. #endif __PRIORITYQUEUE_CPP