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.

666 lines
12 KiB

  1. #ifndef __BasicTREE_CPP
  2. #define __BasicTREE_CPP
  3. /*
  4. * Class:
  5. *
  6. * WmiAllocator
  7. *
  8. * Description:
  9. *
  10. * Provides abstraction above heap allocation functions
  11. *
  12. * Version:
  13. *
  14. * Initial
  15. *
  16. * Last Changed:
  17. *
  18. * See Source Depot for change history
  19. *
  20. */
  21. #if 0
  22. #include <precomp.h>
  23. #include <windows.h>
  24. #include <stdio.h>
  25. #include <BasicTree.h>
  26. #endif
  27. /******************************************************************************
  28. *
  29. * Name:
  30. *
  31. *
  32. * Description:
  33. *
  34. *
  35. *****************************************************************************/
  36. template <class WmiKey,class WmiElement>
  37. WmiBasicTree <WmiKey,WmiElement> :: WmiBasicTree <WmiKey,WmiElement> (
  38. WmiAllocator &a_Allocator
  39. ) : m_Allocator ( a_Allocator ) ,
  40. m_Size ( 0 ) ,
  41. m_Root ( NULL )
  42. {
  43. }
  44. /******************************************************************************
  45. *
  46. * Name:
  47. *
  48. *
  49. * Description:
  50. *
  51. *
  52. *****************************************************************************/
  53. template <class WmiKey,class WmiElement>
  54. WmiBasicTree <WmiKey,WmiElement> :: ~WmiBasicTree <WmiKey,WmiElement> ()
  55. {
  56. WmiStatusCode t_StatusCode = UnInitialize () ;
  57. }
  58. /******************************************************************************
  59. *
  60. * Name:
  61. *
  62. *
  63. * Description:
  64. *
  65. *
  66. *****************************************************************************/
  67. template <class WmiKey,class WmiElement>
  68. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: Initialize ()
  69. {
  70. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  71. return t_StatusCode ;
  72. }
  73. /******************************************************************************
  74. *
  75. * Name:
  76. *
  77. *
  78. * Description:
  79. *
  80. *
  81. *****************************************************************************/
  82. template <class WmiKey,class WmiElement>
  83. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: UnInitialize ()
  84. {
  85. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  86. if ( m_Root )
  87. {
  88. t_StatusCode = RecursiveUnInitialize ( m_Root ) ;
  89. m_Root = NULL ;
  90. }
  91. return t_StatusCode ;
  92. }
  93. /******************************************************************************
  94. *
  95. * Name:
  96. *
  97. *
  98. * Description:
  99. *
  100. *
  101. *****************************************************************************/
  102. template <class WmiKey,class WmiElement>
  103. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: RecursiveUnInitialize ( WmiBasicNode *a_Node )
  104. {
  105. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  106. WmiBasicNode *t_Left = a_Node->m_Left ;
  107. if ( t_Left )
  108. {
  109. t_StatusCode = RecursiveUnInitialize ( t_Left ) ;
  110. t_Left->~WmiBasicNode () ;
  111. WmiStatusCode t_TempStatusCode = m_Allocator.Delete (
  112. ( void * ) t_Left
  113. ) ;
  114. t_Left = NULL ;
  115. }
  116. WmiBasicNode *t_Right = a_Node->m_Right ;
  117. if ( t_Right )
  118. {
  119. t_StatusCode = RecursiveUnInitialize ( t_Right ) ;
  120. t_Right->~WmiBasicNode () ;
  121. WmiStatusCode t_TempStatusCode = m_Allocator.Delete (
  122. ( void * ) t_Right
  123. ) ;
  124. t_Right = NULL ;
  125. }
  126. return t_StatusCode ;
  127. }
  128. /******************************************************************************
  129. *
  130. * Name:
  131. *
  132. *
  133. * Description:
  134. *
  135. *
  136. *****************************************************************************/
  137. template <class WmiKey,class WmiElement>
  138. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: Insert (
  139. const WmiKey &a_Key ,
  140. const WmiElement &a_Element ,
  141. Iterator &a_Iterator
  142. )
  143. {
  144. if ( m_Root )
  145. {
  146. WmiBasicNode *t_Node = m_Root ;
  147. while ( t_Node )
  148. {
  149. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  150. if ( t_Compare == 0 )
  151. {
  152. return e_StatusCode_AlreadyExists ;
  153. }
  154. else
  155. {
  156. if ( t_Compare < 0 )
  157. {
  158. if ( t_Node->m_Left )
  159. {
  160. t_Node = t_Node->m_Left ;
  161. }
  162. else
  163. {
  164. WmiBasicNode *t_AllocNode ;
  165. WmiStatusCode t_StatusCode = m_Allocator.New (
  166. ( void ** ) & t_AllocNode ,
  167. sizeof ( WmiBasicNode )
  168. ) ;
  169. if ( t_StatusCode == e_StatusCode_Success )
  170. {
  171. :: new ( ( void* ) t_AllocNode ) WmiBasicNode () ;
  172. try
  173. {
  174. t_AllocNode->m_Element = a_Element ;
  175. t_AllocNode->m_Key = a_Key ;
  176. }
  177. catch ( Wmi_Heap_Exception &a_Exception )
  178. {
  179. t_AllocNode->~WmiBasicNode () ;
  180. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  181. ( void * ) t_AllocNode
  182. ) ;
  183. return e_StatusCode_OutOfMemory ;
  184. }
  185. catch ( ... )
  186. {
  187. t_AllocNode->~WmiBasicNode () ;
  188. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  189. ( void * ) t_AllocNode
  190. ) ;
  191. return e_StatusCode_Unknown ;
  192. }
  193. a_Iterator = Iterator ( t_AllocNode ) ;
  194. t_AllocNode->m_Parent = t_Node ;
  195. t_Node->m_Left = t_AllocNode ;
  196. m_Size ++ ;
  197. }
  198. return t_StatusCode ;
  199. }
  200. }
  201. else
  202. {
  203. if ( t_Node->m_Right )
  204. {
  205. t_Node = t_Node->m_Right ;
  206. }
  207. else
  208. {
  209. WmiBasicNode *t_AllocNode ;
  210. WmiStatusCode t_StatusCode = m_Allocator.New (
  211. ( void ** ) & t_AllocNode ,
  212. sizeof ( WmiBasicNode )
  213. ) ;
  214. if ( t_StatusCode == e_StatusCode_Success )
  215. {
  216. :: new ( ( void* ) t_AllocNode ) WmiBasicNode () ;
  217. try
  218. {
  219. t_AllocNode->m_Element = a_Element ;
  220. t_AllocNode->m_Key = a_Key ;
  221. }
  222. catch ( Wmi_Heap_Exception &a_Exception )
  223. {
  224. t_AllocNode->~WmiBasicNode () ;
  225. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  226. ( void * ) t_AllocNode
  227. ) ;
  228. return e_StatusCode_OutOfMemory ;
  229. }
  230. catch ( ... )
  231. {
  232. t_AllocNode->~WmiBasicNode () ;
  233. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  234. ( void * ) t_AllocNode
  235. ) ;
  236. return e_StatusCode_Unknown ;
  237. }
  238. a_Iterator = Iterator ( t_AllocNode ) ;
  239. t_AllocNode->m_Parent = t_Node ;
  240. t_Node->m_Right = t_AllocNode ;
  241. m_Size ++ ;
  242. }
  243. return t_StatusCode ;
  244. }
  245. }
  246. }
  247. }
  248. return e_StatusCode_Failed ;
  249. }
  250. else
  251. {
  252. WmiBasicNode *t_AllocNode ;
  253. WmiStatusCode t_StatusCode = m_Allocator.New (
  254. ( void ** ) & t_AllocNode ,
  255. sizeof ( WmiBasicNode )
  256. ) ;
  257. if ( t_StatusCode == e_StatusCode_Success )
  258. {
  259. :: new ( ( void* ) t_AllocNode ) WmiBasicNode () ;
  260. try
  261. {
  262. t_AllocNode->m_Element = a_Element ;
  263. t_AllocNode->m_Key = a_Key ;
  264. }
  265. catch ( Wmi_Heap_Exception &a_Exception )
  266. {
  267. t_AllocNode->~WmiBasicNode () ;
  268. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  269. ( void * ) t_AllocNode
  270. ) ;
  271. return e_StatusCode_OutOfMemory ;
  272. }
  273. catch ( ... )
  274. {
  275. t_AllocNode->~WmiBasicNode () ;
  276. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  277. ( void * ) t_AllocNode
  278. ) ;
  279. return e_StatusCode_Unknown ;
  280. }
  281. a_Iterator = Iterator ( t_AllocNode ) ;
  282. m_Root = t_AllocNode ;
  283. m_Size ++ ;
  284. }
  285. return t_StatusCode ;
  286. }
  287. }
  288. /******************************************************************************
  289. *
  290. * Name:
  291. *
  292. *
  293. * Description:
  294. *
  295. *
  296. *****************************************************************************/
  297. template <class WmiKey,class WmiElement>
  298. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: Delete (
  299. const WmiKey &a_Key
  300. )
  301. {
  302. WmiBasicNode *t_Node = m_Root ;
  303. while ( t_Node )
  304. {
  305. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  306. if ( t_Compare == 0 )
  307. {
  308. m_Size -- ;
  309. return DeleteFixup ( t_Node ) ;
  310. }
  311. else
  312. {
  313. if ( t_Compare < 0 )
  314. {
  315. t_Node = t_Node->m_Left ;
  316. }
  317. else
  318. {
  319. t_Node = t_Node->m_Right ;
  320. }
  321. }
  322. }
  323. return e_StatusCode_NotFound ;
  324. }
  325. /******************************************************************************
  326. *
  327. * Name:
  328. *
  329. *
  330. * Description:
  331. *
  332. *
  333. *****************************************************************************/
  334. template <class WmiKey,class WmiElement>
  335. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: Find (
  336. const WmiKey &a_Key ,
  337. Iterator &a_Iterator
  338. )
  339. {
  340. WmiBasicNode *t_Node = m_Root ;
  341. while ( t_Node )
  342. {
  343. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  344. if ( t_Compare == 0 )
  345. {
  346. a_Iterator = Iterator ( t_Node ) ;
  347. return e_StatusCode_Success ;
  348. }
  349. else
  350. {
  351. if ( t_Compare < 0 )
  352. {
  353. t_Node = t_Node->m_Left ;
  354. }
  355. else
  356. {
  357. t_Node = t_Node->m_Right ;
  358. }
  359. }
  360. }
  361. return e_StatusCode_NotFound ;
  362. }
  363. /******************************************************************************
  364. *
  365. * Name:
  366. *
  367. *
  368. * Description:
  369. *
  370. *
  371. *****************************************************************************/
  372. template <class WmiKey,class WmiElement>
  373. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: FindNext (
  374. const WmiKey &a_Key ,
  375. Iterator &a_Iterator
  376. )
  377. {
  378. WmiBasicNode *t_Node = m_Root ;
  379. while ( t_Node )
  380. {
  381. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  382. if ( t_Compare == 0 )
  383. {
  384. a_Iterator = Iterator ( t_Node ).Increment () ;
  385. return a_Iterator.Null () ? e_StatusCode_NotFound : e_StatusCode_Success ; ;
  386. }
  387. else
  388. {
  389. if ( t_Compare < 0 )
  390. {
  391. if ( t_Node->m_Left )
  392. {
  393. t_Node = t_Node->m_Left ;
  394. }
  395. else
  396. {
  397. a_Iterator = Iterator ( t_Node ) ;
  398. return e_StatusCode_Success ;
  399. }
  400. }
  401. else
  402. {
  403. if ( t_Node->m_Right )
  404. {
  405. t_Node = t_Node->m_Right ;
  406. }
  407. else
  408. {
  409. a_Iterator = Iterator ( t_Node ).Increment () ;
  410. return a_Iterator.Null () ? e_StatusCode_NotFound : e_StatusCode_Success ;
  411. }
  412. }
  413. }
  414. }
  415. return e_StatusCode_NotFound ;
  416. }
  417. /******************************************************************************
  418. *
  419. * Name:
  420. *
  421. *
  422. * Description:
  423. *
  424. *
  425. *****************************************************************************/
  426. template <class WmiKey,class WmiElement>
  427. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: DeleteFixup ( WmiBasicNode *a_Node )
  428. {
  429. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  430. WmiBasicNode *t_Left = a_Node->m_Left ;
  431. WmiBasicNode *t_Right = a_Node->m_Right ;
  432. WmiBasicNode *t_Parent = a_Node->m_Parent ;
  433. if ( t_Left && t_Right )
  434. {
  435. Iterator t_Iterator ( a_Node ) ;
  436. t_Iterator.Increment () ;
  437. WmiBasicNode *t_Successor = t_Iterator.m_Node ;
  438. if ( t_Parent )
  439. {
  440. if ( t_Parent->m_Left == a_Node )
  441. {
  442. t_Parent->m_Left = t_Successor ;
  443. }
  444. else
  445. {
  446. t_Parent->m_Right = t_Successor;
  447. }
  448. }
  449. else
  450. {
  451. m_Root = t_Successor ;
  452. }
  453. if ( t_Successor->m_Parent != a_Node )
  454. {
  455. if ( a_Node->m_Left )
  456. {
  457. a_Node->m_Left->m_Parent = t_Successor ;
  458. }
  459. if ( a_Node->m_Right )
  460. {
  461. a_Node->m_Right->m_Parent = t_Successor ;
  462. }
  463. WmiBasicNode *t_Node = t_Successor->m_Parent ;
  464. t_Successor->m_Parent->m_Left = t_Successor->m_Right ;
  465. if ( t_Successor->m_Left )
  466. {
  467. t_Successor->m_Left->m_Parent = t_Successor->m_Parent ;
  468. }
  469. if ( t_Successor->m_Right )
  470. {
  471. t_Successor->m_Right->m_Parent = t_Successor->m_Parent ;
  472. }
  473. t_Successor->m_Left = a_Node->m_Left ;
  474. t_Successor->m_Right = a_Node->m_Right ;
  475. t_Successor->m_Parent = a_Node->m_Parent ;
  476. }
  477. else
  478. {
  479. if ( a_Node->m_Left )
  480. {
  481. a_Node->m_Left->m_Parent = t_Successor ;
  482. }
  483. if ( a_Node->m_Right )
  484. {
  485. a_Node->m_Right->m_Parent = t_Successor ;
  486. }
  487. t_Successor->m_Left = a_Node->m_Left ;
  488. t_Successor->m_Parent = a_Node->m_Parent ;
  489. }
  490. }
  491. else
  492. {
  493. if ( t_Left )
  494. {
  495. t_Left->m_Parent = a_Node->m_Parent ;
  496. }
  497. else if ( t_Right )
  498. {
  499. t_Right->m_Parent = a_Node->m_Parent ;
  500. }
  501. if ( t_Parent )
  502. {
  503. if ( t_Parent->m_Left == a_Node )
  504. {
  505. t_Parent->m_Left = t_Left ? t_Left : t_Right ;
  506. }
  507. else
  508. {
  509. t_Parent->m_Right = t_Left ? t_Left : t_Right ;
  510. }
  511. }
  512. else
  513. {
  514. m_Root = a_Node->m_Left ? a_Node->m_Left : a_Node->m_Right ;
  515. }
  516. }
  517. a_Node->~WmiBasicNode () ;
  518. t_StatusCode = m_Allocator.Delete (
  519. ( void * ) a_Node
  520. ) ;
  521. return t_StatusCode ;
  522. }
  523. /******************************************************************************
  524. *
  525. * Name:
  526. *
  527. *
  528. * Description:
  529. *
  530. *
  531. *****************************************************************************/
  532. template <class WmiKey,class WmiElement>
  533. WmiStatusCode WmiBasicTree <WmiKey,WmiElement> :: Merge (
  534. WmiBasicTree <WmiKey,WmiElement> &a_Tree
  535. )
  536. {
  537. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  538. Iterator t_Iterator = a_Tree.Root ();
  539. while ( ( ! t_Iterator.Null () ) && ( t_StatusCode == e_StatusCode_Success ) )
  540. {
  541. Iterator t_InsertIterator ;
  542. t_StatusCode = Insert ( t_Iterator.GetKey () , t_Iterator.GetElement () , t_InsertIterator ) ;
  543. if ( t_StatusCode == e_StatusCode_Success )
  544. {
  545. t_StatusCode = a_Tree.Delete ( t_Iterator.GetKey () ) ;
  546. }
  547. t_Iterator = a_Tree.Root () ;
  548. }
  549. return t_StatusCode ;
  550. }
  551. #endif __BasicTREE_CPP