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.

772 lines
14 KiB

  1. #ifndef __REDBLACKTREE_CPP
  2. #define __REDBLACKTREE_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 <RedBlackTree.h>
  26. #endif
  27. /******************************************************************************
  28. *
  29. * Name:
  30. *
  31. *
  32. * Description:
  33. *
  34. *
  35. *****************************************************************************/
  36. template <class WmiKey,class WmiElement>
  37. WmiRedBlackTree <WmiKey,WmiElement> :: WmiRedBlackTree <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. WmiRedBlackTree <WmiKey,WmiElement> :: ~WmiRedBlackTree <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 WmiRedBlackTree <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 WmiRedBlackTree <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 WmiRedBlackTree <WmiKey,WmiElement> :: RecursiveUnInitialize ( WmiRedBlackNode *a_Node )
  104. {
  105. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  106. WmiRedBlackNode *t_Left = a_Node->m_Left ;
  107. if ( t_Left )
  108. {
  109. t_StatusCode = RecursiveUnInitialize ( t_Left ) ;
  110. t_Left->~WmiRedBlackNode () ;
  111. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  112. ( void * ) t_Left
  113. ) ;
  114. t_Left = NULL ;
  115. }
  116. WmiRedBlackNode *t_Right = a_Node->m_Right ;
  117. if ( t_Right )
  118. {
  119. t_StatusCode = RecursiveUnInitialize ( t_Right ) ;
  120. t_Right->~WmiRedBlackNode () ;
  121. WmiStatusCode t_StatusCode = 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 WmiRedBlackTree <WmiKey,WmiElement> :: Insert (
  139. const WmiKey &a_Key ,
  140. const WmiElement &a_Element ,
  141. Iterator &a_Iterator
  142. )
  143. {
  144. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  145. WmiRedBlackNode *t_AllocNode = NULL ;
  146. t_StatusCode = m_Allocator.New (
  147. ( void ** ) & t_AllocNode ,
  148. sizeof ( WmiRedBlackNode )
  149. ) ;
  150. if ( t_StatusCode == e_StatusCode_Success )
  151. {
  152. :: new ( ( void* ) t_AllocNode ) WmiRedBlackNode () ;
  153. try
  154. {
  155. t_AllocNode->m_Element = a_Element ;
  156. t_AllocNode->m_Key = a_Key ;
  157. }
  158. catch ( Wmi_Heap_Exception &a_Exception )
  159. {
  160. t_AllocNode->~WmiRedBlackNode () ;
  161. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  162. ( void * ) t_AllocNode
  163. ) ;
  164. return e_StatusCode_OutOfMemory ;
  165. }
  166. catch ( ... )
  167. {
  168. t_AllocNode->~WmiRedBlackNode () ;
  169. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  170. ( void * ) t_AllocNode
  171. ) ;
  172. return e_StatusCode_Unknown ;
  173. }
  174. a_Iterator = Iterator ( t_AllocNode ) ;
  175. if ( m_Root )
  176. {
  177. t_StatusCode = RecursiveInsert (
  178. m_Root ,
  179. t_AllocNode
  180. ) ;
  181. if ( t_StatusCode == e_StatusCode_Success )
  182. {
  183. m_Size ++ ;
  184. }
  185. else
  186. {
  187. t_AllocNode->~WmiRedBlackNode () ;
  188. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  189. ( void * ) t_AllocNode
  190. ) ;
  191. }
  192. }
  193. else
  194. {
  195. m_Root = t_AllocNode ;
  196. m_Size ++ ;
  197. }
  198. }
  199. else
  200. {
  201. a_Iterator = Iterator () ;
  202. }
  203. return t_StatusCode ;
  204. }
  205. /******************************************************************************
  206. *
  207. * Name:
  208. *
  209. *
  210. * Description:
  211. *
  212. *
  213. *****************************************************************************/
  214. template <class WmiKey,class WmiElement>
  215. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: Delete (
  216. const WmiKey &a_Key
  217. )
  218. {
  219. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  220. if ( m_Root )
  221. {
  222. t_StatusCode = RecursiveDelete ( m_Root , a_Key ) ;
  223. if ( t_StatusCode == e_StatusCode_Success )
  224. {
  225. m_Size -- ;
  226. }
  227. }
  228. else
  229. {
  230. t_StatusCode = e_StatusCode_NotFound ;
  231. }
  232. return t_StatusCode ;
  233. }
  234. /******************************************************************************
  235. *
  236. * Name:
  237. *
  238. *
  239. * Description:
  240. *
  241. *
  242. *****************************************************************************/
  243. template <class WmiKey,class WmiElement>
  244. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: Find (
  245. const WmiKey &a_Key ,
  246. Iterator &a_Iterator
  247. )
  248. {
  249. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  250. if ( m_Root )
  251. {
  252. t_StatusCode = RecursiveFind ( m_Root , a_Key , a_Iterator ) ;
  253. }
  254. else
  255. {
  256. return e_StatusCode_NotFound ;
  257. }
  258. return t_StatusCode ;
  259. }
  260. /******************************************************************************
  261. *
  262. * Name:
  263. *
  264. *
  265. * Description:
  266. *
  267. *
  268. *****************************************************************************/
  269. template <class WmiKey,class WmiElement>
  270. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: FindNext (
  271. const WmiKey &a_Key ,
  272. Iterator &a_Iterator
  273. )
  274. {
  275. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  276. if ( m_Root )
  277. {
  278. t_StatusCode = RecursiveFindNext ( m_Root , a_Key , a_Iterator ) ;
  279. }
  280. else
  281. {
  282. return e_StatusCode_NotFound ;
  283. }
  284. return t_StatusCode ;
  285. }
  286. /******************************************************************************
  287. *
  288. * Name:
  289. *
  290. *
  291. * Description:
  292. *
  293. *
  294. *****************************************************************************/
  295. template <class WmiKey,class WmiElement>
  296. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: RecursiveDelete (
  297. WmiRedBlackNode *a_Node ,
  298. const WmiKey &a_Key
  299. )
  300. {
  301. WmiStatusCode t_StatusCode = e_StatusCode_NotFound ;
  302. LONG t_Compare = CompareElement ( a_Key , a_Node->m_Key ) ;
  303. if ( t_Compare == 0 )
  304. {
  305. t_StatusCode = DeleteFixup ( a_Node ) ;
  306. }
  307. else
  308. {
  309. if ( t_Compare < 0 )
  310. {
  311. WmiRedBlackNode *t_Left = a_Node->m_Left ;
  312. if ( t_Left )
  313. {
  314. t_StatusCode = RecursiveDelete ( t_Left , a_Key ) ;
  315. }
  316. }
  317. else
  318. {
  319. WmiRedBlackNode *t_Right = a_Node->m_Right ;
  320. if ( t_Right )
  321. {
  322. t_StatusCode = RecursiveDelete ( t_Right , a_Key ) ;
  323. }
  324. }
  325. }
  326. return t_StatusCode ;
  327. }
  328. /******************************************************************************
  329. *
  330. * Name:
  331. *
  332. *
  333. * Description:
  334. *
  335. *
  336. *****************************************************************************/
  337. template <class WmiKey,class WmiElement>
  338. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: RecursiveInsert (
  339. WmiRedBlackNode *a_Node ,
  340. WmiRedBlackNode *a_Element
  341. )
  342. {
  343. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  344. LONG t_Compare = CompareElement ( a_Element->m_Key , a_Node->m_Key ) ;
  345. if ( t_Compare == 0 )
  346. {
  347. t_StatusCode = e_StatusCode_AlreadyExists ;
  348. }
  349. else
  350. {
  351. if ( t_Compare < 0 )
  352. {
  353. WmiRedBlackNode *t_Left = a_Node->m_Left ;
  354. if ( t_Left )
  355. {
  356. t_StatusCode = RecursiveInsert ( t_Left , a_Element ) ;
  357. }
  358. else
  359. {
  360. a_Element->m_Parent = a_Node ;
  361. a_Node->m_Left = a_Element ;
  362. }
  363. }
  364. else
  365. {
  366. WmiRedBlackNode *t_Right = a_Node->m_Right ;
  367. if ( t_Right )
  368. {
  369. t_StatusCode = RecursiveInsert ( t_Right , a_Element ) ;
  370. }
  371. else
  372. {
  373. a_Element->m_Parent = a_Node ;
  374. a_Node->m_Right = a_Element ;
  375. }
  376. }
  377. }
  378. return t_StatusCode ;
  379. }
  380. /******************************************************************************
  381. *
  382. * Name:
  383. *
  384. *
  385. * Description:
  386. *
  387. *
  388. *****************************************************************************/
  389. template <class WmiKey,class WmiElement>
  390. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: RecursiveFind (
  391. WmiRedBlackNode *a_Node ,
  392. const WmiKey &a_Key ,
  393. Iterator &a_Iterator
  394. )
  395. {
  396. WmiStatusCode t_StatusCode = e_StatusCode_NotFound ;
  397. LONG t_Compare = CompareElement ( a_Key , a_Node->m_Key ) ;
  398. if ( t_Compare == 0 )
  399. {
  400. a_Iterator = Iterator ( a_Node ) ;
  401. t_StatusCode = e_StatusCode_Success ;
  402. }
  403. else
  404. {
  405. if ( t_Compare < 0 )
  406. {
  407. WmiRedBlackNode *t_Left = a_Node->m_Left ;
  408. if ( t_Left )
  409. {
  410. t_StatusCode = RecursiveFind ( t_Left , a_Key , a_Iterator ) ;
  411. }
  412. }
  413. else
  414. {
  415. WmiRedBlackNode *t_Right = a_Node->m_Right ;
  416. if ( t_Right )
  417. {
  418. t_StatusCode = RecursiveFind ( t_Right , a_Key , a_Iterator ) ;
  419. }
  420. }
  421. }
  422. return t_StatusCode ;
  423. }
  424. /******************************************************************************
  425. *
  426. * Name:
  427. *
  428. *
  429. * Description:
  430. *
  431. *
  432. *****************************************************************************/
  433. template <class WmiKey,class WmiElement>
  434. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: RecursiveFindNext (
  435. WmiRedBlackNode *a_Node ,
  436. const WmiKey &a_Key ,
  437. Iterator &a_Iterator
  438. )
  439. {
  440. WmiStatusCode t_StatusCode = e_StatusCode_NotFound ;
  441. LONG t_Compare = CompareElement ( a_Key , a_Node->m_Key ) ;
  442. if ( t_Compare == 0 )
  443. {
  444. a_Iterator = Iterator ( a_Node ).Increment () ;
  445. t_StatusCode = e_StatusCode_Success ;
  446. }
  447. else
  448. {
  449. if ( t_Compare < 0 )
  450. {
  451. WmiRedBlackNode *t_Left = a_Node->m_Left ;
  452. if ( t_Left )
  453. {
  454. t_StatusCode = RecursiveFindNext ( t_Left , a_Key , a_Iterator ) ;
  455. }
  456. else
  457. {
  458. a_Iterator = Iterator ( a_Node ).Increment () ;
  459. t_StatusCode = e_StatusCode_Success ;
  460. }
  461. }
  462. else
  463. {
  464. WmiRedBlackNode *t_Right = a_Node->m_Right ;
  465. if ( t_Right )
  466. {
  467. t_StatusCode = RecursiveFindNext ( t_Right , a_Key , a_Iterator ) ;
  468. }
  469. else
  470. {
  471. a_Iterator = Iterator ( a_Node ).Increment () ;
  472. t_StatusCode = e_StatusCode_Success ;
  473. }
  474. }
  475. }
  476. return t_StatusCode ;
  477. }
  478. /******************************************************************************
  479. *
  480. * Name:
  481. *
  482. *
  483. * Description:
  484. *
  485. *
  486. *****************************************************************************/
  487. template <class WmiKey,class WmiElement>
  488. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: LeftRotate ( WmiRedBlackNode *a_Node )
  489. {
  490. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  491. return t_StatusCode ;
  492. }
  493. /******************************************************************************
  494. *
  495. * Name:
  496. *
  497. *
  498. * Description:
  499. *
  500. *
  501. *****************************************************************************/
  502. template <class WmiKey,class WmiElement>
  503. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: RightRotate ( WmiRedBlackNode *a_Node )
  504. {
  505. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  506. return t_StatusCode ;
  507. }
  508. /******************************************************************************
  509. *
  510. * Name:
  511. *
  512. *
  513. * Description:
  514. *
  515. *
  516. *****************************************************************************/
  517. template <class WmiKey,class WmiElement>
  518. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: DeleteFixup ( WmiRedBlackNode *a_Node )
  519. {
  520. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  521. WmiRedBlackNode *t_Left = a_Node->m_Left ;
  522. WmiRedBlackNode *t_Right = a_Node->m_Right ;
  523. WmiRedBlackNode *t_Parent = a_Node->m_Parent ;
  524. if ( t_Left && t_Right )
  525. {
  526. Iterator t_Iterator ( a_Node ) ;
  527. t_Iterator.Increment () ;
  528. WmiRedBlackNode *t_Successor = t_Iterator.m_Node ;
  529. if ( t_Parent )
  530. {
  531. if ( t_Parent->m_Left == a_Node )
  532. {
  533. t_Parent->m_Left = t_Successor ;
  534. }
  535. else
  536. {
  537. t_Parent->m_Right = t_Successor;
  538. }
  539. }
  540. else
  541. {
  542. m_Root = t_Successor ;
  543. }
  544. if ( t_Successor->m_Parent != a_Node )
  545. {
  546. if ( a_Node->m_Left )
  547. {
  548. a_Node->m_Left->m_Parent = t_Successor ;
  549. }
  550. if ( a_Node->m_Right )
  551. {
  552. a_Node->m_Right->m_Parent = t_Successor ;
  553. }
  554. WmiRedBlackNode *t_Node = t_Successor->m_Parent ;
  555. t_Successor->m_Parent->m_Left = t_Successor->m_Right ;
  556. if ( t_Successor->m_Left )
  557. {
  558. t_Successor->m_Left->m_Parent = t_Successor->m_Parent ;
  559. }
  560. if ( t_Successor->m_Right )
  561. {
  562. t_Successor->m_Right->m_Parent = t_Successor->m_Parent ;
  563. }
  564. t_Successor->m_Left = a_Node->m_Left ;
  565. t_Successor->m_Right = a_Node->m_Right ;
  566. t_Successor->m_Parent = a_Node->m_Parent ;
  567. }
  568. else
  569. {
  570. if ( a_Node->m_Left )
  571. {
  572. a_Node->m_Left->m_Parent = t_Successor ;
  573. }
  574. if ( a_Node->m_Right )
  575. {
  576. a_Node->m_Right->m_Parent = t_Successor ;
  577. }
  578. t_Successor->m_Left = a_Node->m_Left ;
  579. t_Successor->m_Parent = a_Node->m_Parent ;
  580. }
  581. }
  582. else
  583. {
  584. if ( t_Left )
  585. {
  586. t_Left->m_Parent = a_Node->m_Parent ;
  587. }
  588. else if ( t_Right )
  589. {
  590. t_Right->m_Parent = a_Node->m_Parent ;
  591. }
  592. if ( t_Parent )
  593. {
  594. if ( t_Parent->m_Left == a_Node )
  595. {
  596. t_Parent->m_Left = t_Left ? t_Left : t_Right ;
  597. }
  598. else
  599. {
  600. t_Parent->m_Right = t_Left ? t_Left : t_Right ;
  601. }
  602. }
  603. else
  604. {
  605. m_Root = a_Node->m_Left ? a_Node->m_Left : a_Node->m_Right ;
  606. }
  607. }
  608. a_Node->~WmiRedBlackNode () ;
  609. t_StatusCode = m_Allocator.Delete (
  610. ( void * ) a_Node
  611. ) ;
  612. return t_StatusCode ;
  613. }
  614. /******************************************************************************
  615. *
  616. * Name:
  617. *
  618. *
  619. * Description:
  620. *
  621. *
  622. *****************************************************************************/
  623. template <class WmiKey,class WmiElement>
  624. WmiStatusCode WmiRedBlackTree <WmiKey,WmiElement> :: Merge (
  625. WmiRedBlackTree <WmiKey,WmiElement> &a_Tree
  626. )
  627. {
  628. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  629. Iterator t_Iterator = a_Tree.Root ();
  630. while ( ! t_Iterator.Null () )
  631. {
  632. Iterator t_InsertIterator ;
  633. WmiStatusCode t_StatusCode = Insert ( t_Iterator.GetKey () , t_Iterator.GetElement () , t_InsertIterator ) ;
  634. if ( t_StatusCode )
  635. {
  636. t_StatusCode = a_Tree.Delete ( t_Iterator.GetKey () ) ;
  637. }
  638. t_Iterator = a_Tree.Root () ;
  639. }
  640. return t_StatusCode ;
  641. }
  642. #endif __REDBLACKTREE_CPP