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.

2292 lines
41 KiB

  1. #ifndef _AVLTREE_CPP
  2. #define _AVLTREE_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 <AvlTree.h>
  26. #endif
  27. #if 1
  28. #define INLINE_COMPARE
  29. #endif
  30. /******************************************************************************
  31. *
  32. * Name:
  33. *
  34. *
  35. * Description:
  36. *
  37. *
  38. *****************************************************************************/
  39. template <class WmiKey,class WmiElement>
  40. WmiAvlTree <WmiKey,WmiElement> :: WmiAvlTree <WmiKey,WmiElement> (
  41. WmiAllocator &a_Allocator
  42. ) : m_Allocator ( a_Allocator ) ,
  43. m_Size ( 0 ) ,
  44. m_Root ( NULL )
  45. {
  46. }
  47. /******************************************************************************
  48. *
  49. * Name:
  50. *
  51. *
  52. * Description:
  53. *
  54. *
  55. *****************************************************************************/
  56. template <class WmiKey,class WmiElement>
  57. WmiAvlTree <WmiKey,WmiElement> :: ~WmiAvlTree <WmiKey,WmiElement> ()
  58. {
  59. WmiStatusCode t_StatusCode = UnInitialize () ;
  60. }
  61. /******************************************************************************
  62. *
  63. * Name:
  64. *
  65. *
  66. * Description:
  67. *
  68. *
  69. *****************************************************************************/
  70. template <class WmiKey,class WmiElement>
  71. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Initialize ()
  72. {
  73. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  74. return t_StatusCode ;
  75. }
  76. /******************************************************************************
  77. *
  78. * Name:
  79. *
  80. *
  81. * Description:
  82. *
  83. *
  84. *****************************************************************************/
  85. template <class WmiKey,class WmiElement>
  86. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: UnInitialize ()
  87. {
  88. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  89. if ( m_Root )
  90. {
  91. t_StatusCode = RecursiveUnInitialize ( m_Root ) ;
  92. m_Root = NULL;
  93. }
  94. return t_StatusCode ;
  95. }
  96. /******************************************************************************
  97. *
  98. * Name:
  99. *
  100. *
  101. * Description:
  102. *
  103. *
  104. *****************************************************************************/
  105. template <class WmiKey,class WmiElement>
  106. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: RecursiveUnInitialize ( WmiAvlNode *a_Node )
  107. {
  108. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  109. WmiAvlNode *t_Left = a_Node->m_Left ;
  110. if ( t_Left )
  111. {
  112. t_StatusCode = RecursiveUnInitialize ( t_Left ) ;
  113. t_Left->~WmiAvlNode () ;
  114. WmiStatusCode t_TempStatusCode = m_Allocator.Delete (
  115. ( void * ) t_Left
  116. ) ;
  117. t_Left = NULL ;
  118. }
  119. WmiAvlNode *t_Right = a_Node->m_Right ;
  120. if ( t_Right )
  121. {
  122. t_StatusCode = RecursiveUnInitialize ( t_Right ) ;
  123. t_Right->~WmiAvlNode () ;
  124. WmiStatusCode t_TempStatusCode = m_Allocator.Delete (
  125. ( void * ) t_Right
  126. ) ;
  127. t_Right = NULL ;
  128. }
  129. return t_StatusCode ;
  130. }
  131. /******************************************************************************
  132. *
  133. * Name:
  134. *
  135. *
  136. * Description:
  137. *
  138. *
  139. *****************************************************************************/
  140. template <class WmiKey,class WmiElement>
  141. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Insert (
  142. const WmiKey &a_Key ,
  143. const WmiElement &a_Element ,
  144. Iterator &a_Iterator
  145. )
  146. {
  147. if ( m_Root )
  148. {
  149. bool t_Increased ;
  150. WmiAvlNode *t_Node = m_Root ;
  151. while ( t_Node )
  152. {
  153. #ifdef INLINE_COMPARE
  154. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  155. if ( t_Compare == 0 )
  156. #else
  157. if ( a_Key == t_Node->m_Key )
  158. #endif
  159. {
  160. return e_StatusCode_AlreadyExists ;
  161. }
  162. else
  163. {
  164. #ifdef INLINE_COMPARE
  165. if ( t_Compare < 0 )
  166. #else
  167. if ( a_Key < t_Node->m_Key )
  168. #endif
  169. {
  170. if ( t_Node->m_Left )
  171. {
  172. t_Node = t_Node->m_Left ;
  173. }
  174. else
  175. {
  176. WmiAvlNode *t_AllocNode ;
  177. WmiStatusCode t_StatusCode = m_Allocator.New (
  178. ( void ** ) & t_AllocNode ,
  179. sizeof ( WmiAvlNode )
  180. ) ;
  181. if ( t_StatusCode == e_StatusCode_Success )
  182. {
  183. :: new ( ( void* ) t_AllocNode ) WmiAvlNode () ;
  184. try
  185. {
  186. t_AllocNode->m_Element = a_Element ;
  187. t_AllocNode->m_Key = a_Key ;
  188. }
  189. catch ( Wmi_Heap_Exception &a_Exception )
  190. {
  191. t_AllocNode->~WmiAvlNode () ;
  192. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  193. ( void * ) t_AllocNode
  194. ) ;
  195. return e_StatusCode_OutOfMemory ;
  196. }
  197. catch ( ... )
  198. {
  199. t_AllocNode->~WmiAvlNode () ;
  200. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  201. ( void * ) t_AllocNode
  202. ) ;
  203. return e_StatusCode_Unknown ;
  204. }
  205. a_Iterator = Iterator ( t_AllocNode ) ;
  206. m_Size ++ ;
  207. t_Increased = true ;
  208. t_AllocNode->m_Parent = t_Node ;
  209. t_Node->m_Left = t_AllocNode ;
  210. t_StatusCode = Insert_LeftBalance (
  211. t_Node ,
  212. t_Node->m_Left ,
  213. t_Increased
  214. ) ;
  215. while ( t_Increased )
  216. {
  217. WmiAvlNode *t_ParentNode = t_Node->m_Parent ;
  218. if ( t_ParentNode )
  219. {
  220. if ( t_ParentNode->m_Left == t_Node )
  221. {
  222. t_StatusCode = Insert_LeftBalance (
  223. t_ParentNode ,
  224. t_Node ,
  225. t_Increased
  226. ) ;
  227. }
  228. else
  229. {
  230. t_StatusCode = Insert_RightBalance (
  231. t_ParentNode ,
  232. t_Node ,
  233. t_Increased
  234. ) ;
  235. }
  236. t_Node = t_Node->m_Parent ;
  237. }
  238. else
  239. {
  240. return e_StatusCode_Success ;
  241. }
  242. }
  243. return e_StatusCode_Success ;
  244. }
  245. else
  246. {
  247. return t_StatusCode ;
  248. }
  249. }
  250. }
  251. else
  252. {
  253. if ( t_Node->m_Right )
  254. {
  255. t_Node = t_Node->m_Right ;
  256. }
  257. else
  258. {
  259. WmiAvlNode *t_AllocNode ;
  260. WmiStatusCode t_StatusCode = m_Allocator.New (
  261. ( void ** ) & t_AllocNode ,
  262. sizeof ( WmiAvlNode )
  263. ) ;
  264. if ( t_StatusCode == e_StatusCode_Success )
  265. {
  266. :: new ( ( void* ) t_AllocNode ) WmiAvlNode () ;
  267. try
  268. {
  269. t_AllocNode->m_Element = a_Element ;
  270. t_AllocNode->m_Key = a_Key ;
  271. }
  272. catch ( Wmi_Heap_Exception &a_Exception )
  273. {
  274. t_AllocNode->~WmiAvlNode () ;
  275. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  276. ( void * ) t_AllocNode
  277. ) ;
  278. return e_StatusCode_OutOfMemory ;
  279. }
  280. catch ( ... )
  281. {
  282. t_AllocNode->~WmiAvlNode () ;
  283. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  284. ( void * ) t_AllocNode
  285. ) ;
  286. return e_StatusCode_Unknown ;
  287. }
  288. a_Iterator = Iterator ( t_AllocNode ) ;
  289. m_Size ++ ;
  290. t_Increased = true ;
  291. t_AllocNode->m_Parent = t_Node ;
  292. t_Node->m_Right = t_AllocNode ;
  293. t_StatusCode = Insert_RightBalance (
  294. t_Node ,
  295. t_Node->m_Right ,
  296. t_Increased
  297. ) ;
  298. while ( t_Increased )
  299. {
  300. WmiAvlNode *t_ParentNode = t_Node->m_Parent ;
  301. if ( t_ParentNode )
  302. {
  303. if ( t_ParentNode->m_Left == t_Node )
  304. {
  305. t_StatusCode = Insert_LeftBalance (
  306. t_ParentNode ,
  307. t_Node ,
  308. t_Increased
  309. ) ;
  310. }
  311. else
  312. {
  313. t_StatusCode = Insert_RightBalance (
  314. t_ParentNode ,
  315. t_Node ,
  316. t_Increased
  317. ) ;
  318. }
  319. t_Node = t_ParentNode ;
  320. }
  321. else
  322. {
  323. return e_StatusCode_Success ;
  324. }
  325. }
  326. return e_StatusCode_Success ;
  327. }
  328. else
  329. {
  330. return t_StatusCode ;
  331. }
  332. }
  333. }
  334. }
  335. }
  336. return e_StatusCode_Failed ;
  337. }
  338. else
  339. {
  340. WmiAvlNode *t_AllocNode ;
  341. WmiStatusCode t_StatusCode = m_Allocator.New (
  342. ( void ** ) & t_AllocNode ,
  343. sizeof ( WmiAvlNode )
  344. ) ;
  345. if ( t_StatusCode == e_StatusCode_Success )
  346. {
  347. :: new ( ( void* ) t_AllocNode ) WmiAvlNode () ;
  348. try
  349. {
  350. t_AllocNode->m_Element = a_Element ;
  351. t_AllocNode->m_Key = a_Key ;
  352. }
  353. catch ( Wmi_Heap_Exception &a_Exception )
  354. {
  355. t_AllocNode->~WmiAvlNode () ;
  356. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  357. ( void * ) t_AllocNode
  358. ) ;
  359. return e_StatusCode_OutOfMemory ;
  360. }
  361. catch ( ... )
  362. {
  363. t_AllocNode->~WmiAvlNode () ;
  364. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  365. ( void * ) t_AllocNode
  366. ) ;
  367. return e_StatusCode_Unknown ;
  368. }
  369. a_Iterator = Iterator ( t_AllocNode ) ;
  370. m_Root = t_AllocNode ;
  371. m_Size ++ ;
  372. }
  373. return t_StatusCode ;
  374. }
  375. }
  376. /******************************************************************************
  377. *
  378. * Name:
  379. *
  380. *
  381. * Description:
  382. *
  383. *
  384. *****************************************************************************/
  385. template <class WmiKey,class WmiElement>
  386. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Delete (
  387. const WmiKey &a_Key
  388. )
  389. {
  390. if ( m_Root )
  391. {
  392. bool t_Decreased ;
  393. WmiAvlNode *t_Node = m_Root ;
  394. while ( t_Node )
  395. {
  396. #ifdef INLINE_COMPARE
  397. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  398. if ( t_Compare == 0 )
  399. #else
  400. if ( a_Key == t_Node->m_Key )
  401. #endif
  402. {
  403. WmiAvlNode *t_ParentNode = t_Node->m_Parent ;
  404. if ( t_ParentNode )
  405. {
  406. bool t_LeftSide = t_ParentNode->m_Left == t_Node ? true : false ;
  407. WmiStatusCode t_StatusCode = DeleteFixup ( t_Node , t_Decreased ) ;
  408. m_Size -- ;
  409. while ( t_Decreased )
  410. {
  411. if ( t_ParentNode )
  412. {
  413. if ( t_LeftSide )
  414. {
  415. t_StatusCode = Delete_LeftBalance (
  416. t_ParentNode ,
  417. t_ParentNode->m_Right ,
  418. t_Decreased
  419. ) ;
  420. }
  421. else
  422. {
  423. t_StatusCode = Delete_RightBalance (
  424. t_ParentNode ,
  425. t_ParentNode->m_Left ,
  426. t_Decreased
  427. ) ;
  428. }
  429. t_Node = t_ParentNode ;
  430. t_ParentNode = t_Node->m_Parent ;
  431. if ( t_ParentNode )
  432. {
  433. t_LeftSide = t_ParentNode->m_Left == t_Node ? true : false ;
  434. }
  435. }
  436. else
  437. {
  438. return e_StatusCode_Success ;
  439. }
  440. }
  441. return e_StatusCode_Success ;
  442. }
  443. else
  444. {
  445. m_Size -- ;
  446. return DeleteFixup ( t_Node , t_Decreased ) ;
  447. }
  448. }
  449. else
  450. {
  451. #ifdef INLINE_COMPARE
  452. if ( t_Compare < 0 )
  453. #else
  454. if ( a_Key < t_Node->m_Key )
  455. #endif
  456. {
  457. if ( t_Node->m_Left )
  458. {
  459. t_Node = t_Node->m_Left ;
  460. }
  461. else
  462. {
  463. return e_StatusCode_NotFound ;
  464. }
  465. }
  466. else
  467. {
  468. if ( t_Node->m_Right )
  469. {
  470. t_Node = t_Node->m_Right ;
  471. }
  472. else
  473. {
  474. return e_StatusCode_NotFound ;
  475. }
  476. }
  477. }
  478. }
  479. return e_StatusCode_Failed ;
  480. }
  481. else
  482. {
  483. return e_StatusCode_NotFound ;
  484. }
  485. }
  486. /******************************************************************************
  487. *
  488. * Name:
  489. *
  490. *
  491. * Description:
  492. *
  493. *
  494. *****************************************************************************/
  495. template <class WmiKey,class WmiElement>
  496. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Find (
  497. const WmiKey &a_Key ,
  498. Iterator &a_Iterator
  499. )
  500. {
  501. WmiAvlNode *t_Node = m_Root ;
  502. while ( t_Node )
  503. {
  504. #ifdef INLINE_COMPARE
  505. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  506. if ( t_Compare == 0 )
  507. #else
  508. if ( a_Key == t_Node->m_Key )
  509. #endif
  510. {
  511. a_Iterator = Iterator ( t_Node ) ;
  512. return e_StatusCode_Success ;
  513. }
  514. else
  515. {
  516. #ifdef INLINE_COMPARE
  517. if ( t_Compare < 0 )
  518. #else
  519. if ( a_Key < t_Node->m_Key )
  520. #endif
  521. {
  522. t_Node = t_Node->m_Left ;
  523. }
  524. else
  525. {
  526. t_Node = t_Node->m_Right ;
  527. }
  528. }
  529. }
  530. return e_StatusCode_NotFound ;
  531. }
  532. /******************************************************************************
  533. *
  534. * Name:
  535. *
  536. *
  537. * Description:
  538. *
  539. *
  540. *****************************************************************************/
  541. template <class WmiKey,class WmiElement>
  542. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: FindNext (
  543. const WmiKey &a_Key ,
  544. Iterator &a_Iterator
  545. )
  546. {
  547. WmiAvlNode *t_Node = m_Root ;
  548. while ( t_Node )
  549. {
  550. #ifdef INLINE_COMPARE
  551. LONG t_Compare = CompareElement ( a_Key , t_Node->m_Key ) ;
  552. if ( t_Compare == 0 )
  553. #else
  554. if ( a_Key == t_Node->m_Key )
  555. #endif
  556. {
  557. a_Iterator = Iterator ( t_Node ).Increment () ;
  558. return a_Iterator.Null () ? e_StatusCode_NotFound : e_StatusCode_Success ;
  559. }
  560. else
  561. {
  562. #ifdef INLINE_COMPARE
  563. if ( t_Compare < 0 )
  564. #else
  565. if ( a_Key < t_Node->m_Key )
  566. #endif
  567. {
  568. if ( t_Node->m_Left )
  569. {
  570. t_Node = t_Node->m_Left ;
  571. }
  572. else
  573. {
  574. a_Iterator = Iterator ( t_Node ) ;
  575. return e_StatusCode_Success ;
  576. }
  577. }
  578. else
  579. {
  580. if ( t_Node->m_Right )
  581. {
  582. t_Node = t_Node->m_Right ;
  583. }
  584. else
  585. {
  586. a_Iterator = Iterator ( t_Node ).Increment () ;
  587. return a_Iterator.Null () ? e_StatusCode_NotFound : e_StatusCode_Success ;
  588. }
  589. }
  590. }
  591. }
  592. return e_StatusCode_NotFound ;
  593. }
  594. /******************************************************************************
  595. *
  596. * Name:
  597. *
  598. *
  599. * Description:
  600. *
  601. *
  602. *****************************************************************************/
  603. template <class WmiKey,class WmiElement>
  604. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Check ( ULONG & a_MaxHeight )
  605. {
  606. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  607. #if 0
  608. printf ( "\nStart Check ( %ld )" , m_Size ) ;
  609. #endif
  610. if ( m_Root )
  611. {
  612. if ( m_Root->m_Parent == NULL )
  613. {
  614. ULONG t_Count = 1 ;
  615. ULONG t_Height = 0 ;
  616. a_MaxHeight = 0 ;
  617. t_StatusCode = RecursiveCheck ( m_Root , t_Count , t_Height , a_MaxHeight ) ;
  618. if ( t_StatusCode == e_StatusCode_Success )
  619. {
  620. if ( t_Count != m_Size )
  621. {
  622. t_StatusCode = e_StatusCode_Failed ;
  623. }
  624. }
  625. }
  626. else
  627. {
  628. t_StatusCode = e_StatusCode_Failed ;
  629. }
  630. }
  631. #if 0
  632. printf ( "\nEnd Check" ) ;
  633. #endif
  634. return t_StatusCode ;
  635. }
  636. /******************************************************************************
  637. *
  638. * Name:
  639. *
  640. *
  641. * Description:
  642. *
  643. *
  644. *****************************************************************************/
  645. template <class WmiKey,class WmiElement>
  646. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Insert_LeftBalance (
  647. WmiAvlNode *&A ,
  648. WmiAvlNode *B ,
  649. bool &a_Increased
  650. )
  651. {
  652. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  653. if ( a_Increased )
  654. {
  655. switch ( A->m_State )
  656. {
  657. case WmiAvlNode :: e_Equal:
  658. {
  659. A->m_State = WmiAvlNode :: e_LeftHigher ;
  660. }
  661. break ;
  662. case WmiAvlNode :: e_RightHigher:
  663. {
  664. A->m_State = WmiAvlNode :: e_Equal ;
  665. a_Increased = false ;
  666. }
  667. break ;
  668. case WmiAvlNode :: e_LeftHigher:
  669. {
  670. a_Increased = false ;
  671. switch ( B->m_State )
  672. {
  673. case WmiAvlNode :: e_Equal:
  674. {
  675. }
  676. break ;
  677. case WmiAvlNode :: e_LeftHigher:
  678. {
  679. WmiAvlNode *t_Parent = A->m_Parent ;
  680. if ( t_Parent )
  681. {
  682. if ( t_Parent->m_Left == A )
  683. {
  684. t_Parent->m_Left = B ;
  685. }
  686. else
  687. {
  688. t_Parent->m_Right = B ;
  689. }
  690. }
  691. else
  692. {
  693. m_Root = B ;
  694. }
  695. if ( B->m_Right )
  696. {
  697. B->m_Right->m_Parent = A ;
  698. }
  699. A->m_State = WmiAvlNode :: e_Equal ;
  700. A->m_Left = B->m_Right ;
  701. A->m_Parent = B ;
  702. B->m_State = WmiAvlNode :: e_Equal ;
  703. B->m_Right = A ;
  704. B->m_Parent = t_Parent ;
  705. A = B ;
  706. }
  707. break ;
  708. case WmiAvlNode :: e_RightHigher:
  709. {
  710. WmiAvlNode *C = A->m_Left->m_Right ;
  711. WmiAvlNode *t_Parent = A->m_Parent ;
  712. if ( t_Parent )
  713. {
  714. if ( t_Parent->m_Left == A )
  715. {
  716. t_Parent->m_Left = C ;
  717. }
  718. else
  719. {
  720. t_Parent->m_Right = C ;
  721. }
  722. }
  723. else
  724. {
  725. m_Root = C ;
  726. }
  727. A->m_Parent = C ;
  728. B->m_Parent = C ;
  729. if ( C->m_Left )
  730. {
  731. C->m_Left->m_Parent = B ;
  732. }
  733. if ( C->m_Right )
  734. {
  735. C->m_Right->m_Parent = A ;
  736. }
  737. A->m_Left = C->m_Right ;
  738. B->m_Right = C->m_Left ;
  739. C->m_Left = B ;
  740. C->m_Right = A ;
  741. C->m_Parent = t_Parent ;
  742. switch ( C->m_State )
  743. {
  744. case WmiAvlNode :: e_LeftHigher:
  745. {
  746. B->m_State = WmiAvlNode :: e_Equal ;
  747. A->m_State = WmiAvlNode :: e_RightHigher ;
  748. }
  749. break ;
  750. case WmiAvlNode :: e_RightHigher:
  751. {
  752. B->m_State = WmiAvlNode :: e_LeftHigher ;
  753. A->m_State = WmiAvlNode :: e_Equal ;
  754. }
  755. break ;
  756. case WmiAvlNode :: e_Equal:
  757. {
  758. B->m_State = WmiAvlNode :: e_Equal ;
  759. A->m_State = WmiAvlNode :: e_Equal ;
  760. }
  761. break ;
  762. default:
  763. {
  764. t_StatusCode = e_StatusCode_Unknown ;
  765. }
  766. break ;
  767. }
  768. C->m_State = WmiAvlNode :: e_Equal ;
  769. A = C ;
  770. }
  771. break ;
  772. default:
  773. {
  774. t_StatusCode = e_StatusCode_Unknown ;
  775. }
  776. break ;
  777. }
  778. }
  779. break ;
  780. default:
  781. {
  782. t_StatusCode = e_StatusCode_Unknown ;
  783. }
  784. break ;
  785. }
  786. }
  787. return t_StatusCode ;
  788. }
  789. /******************************************************************************
  790. *
  791. * Name:
  792. *
  793. *
  794. * Description:
  795. *
  796. *
  797. *****************************************************************************/
  798. template <class WmiKey,class WmiElement>
  799. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Insert_RightBalance (
  800. WmiAvlNode *&A ,
  801. WmiAvlNode *B ,
  802. bool &a_Increased
  803. )
  804. {
  805. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  806. if ( a_Increased )
  807. {
  808. switch ( A->m_State )
  809. {
  810. case WmiAvlNode :: e_Equal:
  811. {
  812. A->m_State = WmiAvlNode :: e_RightHigher ;
  813. }
  814. break ;
  815. case WmiAvlNode :: e_LeftHigher:
  816. {
  817. A->m_State = WmiAvlNode :: e_Equal ;
  818. a_Increased = false ;
  819. }
  820. break ;
  821. case WmiAvlNode :: e_RightHigher:
  822. {
  823. a_Increased = false ;
  824. switch ( B->m_State )
  825. {
  826. case WmiAvlNode :: e_Equal:
  827. {
  828. }
  829. break ;
  830. case WmiAvlNode :: e_RightHigher:
  831. {
  832. WmiAvlNode *t_Parent = A->m_Parent ;
  833. if ( t_Parent )
  834. {
  835. if ( t_Parent->m_Left == A )
  836. {
  837. t_Parent->m_Left = B ;
  838. }
  839. else
  840. {
  841. t_Parent->m_Right = B ;
  842. }
  843. }
  844. else
  845. {
  846. m_Root = B ;
  847. }
  848. if ( B->m_Left )
  849. {
  850. B->m_Left->m_Parent = A ;
  851. }
  852. A->m_State = WmiAvlNode :: e_Equal ;
  853. A->m_Right = B->m_Left ;
  854. A->m_Parent = B ;
  855. B->m_State = WmiAvlNode :: e_Equal ;
  856. B->m_Left = A ;
  857. B->m_Parent = t_Parent ;
  858. A = B ;
  859. }
  860. break ;
  861. case WmiAvlNode :: e_LeftHigher:
  862. {
  863. WmiAvlNode *C = A->m_Right->m_Left ;
  864. WmiAvlNode *t_Parent = A->m_Parent ;
  865. if ( t_Parent )
  866. {
  867. if ( t_Parent->m_Left == A )
  868. {
  869. t_Parent->m_Left = C ;
  870. }
  871. else
  872. {
  873. t_Parent->m_Right = C ;
  874. }
  875. }
  876. else
  877. {
  878. m_Root = C ;
  879. }
  880. A->m_Parent = C ;
  881. B->m_Parent = C ;
  882. if ( C->m_Right )
  883. {
  884. C->m_Right->m_Parent = B ;
  885. }
  886. if ( C->m_Left )
  887. {
  888. C->m_Left->m_Parent = A ;
  889. }
  890. B->m_Left = C->m_Right ;
  891. A->m_Right = C->m_Left ;
  892. C->m_Right = B ;
  893. C->m_Left = A ;
  894. C->m_Parent = t_Parent ;
  895. switch ( C->m_State )
  896. {
  897. case WmiAvlNode :: e_LeftHigher:
  898. {
  899. B->m_State = WmiAvlNode :: e_RightHigher ;
  900. A->m_State = WmiAvlNode :: e_Equal ;
  901. }
  902. break ;
  903. case WmiAvlNode :: e_RightHigher:
  904. {
  905. B->m_State = WmiAvlNode :: e_Equal ;
  906. A->m_State = WmiAvlNode :: e_LeftHigher ;
  907. }
  908. break ;
  909. case WmiAvlNode :: e_Equal:
  910. {
  911. B->m_State = WmiAvlNode :: e_Equal ;
  912. A->m_State = WmiAvlNode :: e_Equal ;
  913. }
  914. break ;
  915. default:
  916. {
  917. t_StatusCode = e_StatusCode_Unknown ;
  918. }
  919. break ;
  920. }
  921. C->m_State = WmiAvlNode :: e_Equal ;
  922. A = C ;
  923. }
  924. break ;
  925. default:
  926. {
  927. t_StatusCode = e_StatusCode_Unknown ;
  928. }
  929. break ;
  930. }
  931. }
  932. break ;
  933. default:
  934. {
  935. t_StatusCode = e_StatusCode_Unknown ;
  936. }
  937. break ;
  938. }
  939. }
  940. return t_StatusCode ;
  941. }
  942. /******************************************************************************
  943. *
  944. * Name:
  945. *
  946. *
  947. * Description:
  948. *
  949. *
  950. *****************************************************************************/
  951. template <class WmiKey,class WmiElement>
  952. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Delete_LeftBalance (
  953. WmiAvlNode *&A ,
  954. WmiAvlNode *B ,
  955. bool &a_Decreased
  956. )
  957. {
  958. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  959. if ( a_Decreased )
  960. {
  961. switch ( A->m_State )
  962. {
  963. case WmiAvlNode :: e_Equal:
  964. {
  965. A->m_State = WmiAvlNode :: e_RightHigher ;
  966. a_Decreased = false ;
  967. }
  968. break ;
  969. case WmiAvlNode :: e_LeftHigher:
  970. {
  971. A->m_State = WmiAvlNode :: e_Equal ;
  972. }
  973. break ;
  974. case WmiAvlNode :: e_RightHigher:
  975. {
  976. switch ( B->m_State )
  977. {
  978. case WmiAvlNode :: e_Equal:
  979. {
  980. a_Decreased = false ;
  981. WmiAvlNode *t_Parent = A->m_Parent ;
  982. if ( t_Parent )
  983. {
  984. if ( t_Parent->m_Left == A )
  985. {
  986. t_Parent->m_Left = B ;
  987. }
  988. else
  989. {
  990. t_Parent->m_Right = B ;
  991. }
  992. }
  993. else
  994. {
  995. m_Root = B ;
  996. }
  997. if ( B->m_Left )
  998. {
  999. B->m_Left->m_Parent = A ;
  1000. }
  1001. A->m_State = WmiAvlNode :: e_RightHigher ;
  1002. A->m_Right = B->m_Left ;
  1003. A->m_Parent = B ;
  1004. B->m_State = WmiAvlNode :: e_LeftHigher ;
  1005. B->m_Left = A ;
  1006. B->m_Parent = t_Parent ;
  1007. A = B ;
  1008. }
  1009. break ;
  1010. case WmiAvlNode :: e_RightHigher:
  1011. {
  1012. WmiAvlNode *t_Parent = A->m_Parent ;
  1013. if ( t_Parent )
  1014. {
  1015. if ( t_Parent->m_Left == A )
  1016. {
  1017. t_Parent->m_Left = B ;
  1018. }
  1019. else
  1020. {
  1021. t_Parent->m_Right = B ;
  1022. }
  1023. }
  1024. else
  1025. {
  1026. m_Root = B ;
  1027. }
  1028. if ( B->m_Left )
  1029. {
  1030. B->m_Left->m_Parent = A ;
  1031. }
  1032. A->m_State = WmiAvlNode :: e_Equal ;
  1033. A->m_Right = B->m_Left ;
  1034. A->m_Parent = B ;
  1035. B->m_State = WmiAvlNode :: e_Equal ;
  1036. B->m_Left = A ;
  1037. B->m_Parent = t_Parent ;
  1038. A = B ;
  1039. }
  1040. break ;
  1041. case WmiAvlNode :: e_LeftHigher:
  1042. {
  1043. WmiAvlNode *C = A->m_Right->m_Left ;
  1044. WmiAvlNode *t_Parent = A->m_Parent ;
  1045. if ( t_Parent )
  1046. {
  1047. if ( t_Parent->m_Left == A )
  1048. {
  1049. t_Parent->m_Left = C ;
  1050. }
  1051. else
  1052. {
  1053. t_Parent->m_Right = C ;
  1054. }
  1055. }
  1056. else
  1057. {
  1058. m_Root = C ;
  1059. }
  1060. A->m_Parent = C ;
  1061. B->m_Parent = C ;
  1062. if ( C->m_Left )
  1063. {
  1064. C->m_Left->m_Parent = A ;
  1065. }
  1066. if ( C->m_Right )
  1067. {
  1068. C->m_Right->m_Parent = B ;
  1069. }
  1070. A->m_Right = C->m_Left ;
  1071. B->m_Left = C->m_Right ;
  1072. C->m_Left = A ;
  1073. C->m_Right = B ;
  1074. C->m_Parent = t_Parent ;
  1075. switch ( C->m_State )
  1076. {
  1077. case WmiAvlNode :: e_LeftHigher:
  1078. {
  1079. A->m_State = WmiAvlNode :: e_Equal ;
  1080. B->m_State = WmiAvlNode :: e_RightHigher ;
  1081. }
  1082. break ;
  1083. case WmiAvlNode :: e_RightHigher:
  1084. {
  1085. B->m_State = WmiAvlNode :: e_Equal ;
  1086. A->m_State = WmiAvlNode :: e_LeftHigher ;
  1087. }
  1088. break ;
  1089. case WmiAvlNode :: e_Equal:
  1090. {
  1091. B->m_State = WmiAvlNode :: e_Equal ;
  1092. A->m_State = WmiAvlNode :: e_Equal ;
  1093. }
  1094. break ;
  1095. default:
  1096. {
  1097. t_StatusCode = e_StatusCode_Unknown ;
  1098. }
  1099. break ;
  1100. }
  1101. C->m_State = WmiAvlNode :: e_Equal ;
  1102. A = C ;
  1103. }
  1104. break ;
  1105. default:
  1106. {
  1107. t_StatusCode = e_StatusCode_Unknown ;
  1108. }
  1109. break ;
  1110. }
  1111. }
  1112. break ;
  1113. default:
  1114. {
  1115. t_StatusCode = e_StatusCode_Unknown ;
  1116. }
  1117. break ;
  1118. }
  1119. }
  1120. return t_StatusCode ;
  1121. }
  1122. /******************************************************************************
  1123. *
  1124. * Name:
  1125. *
  1126. *
  1127. * Description:
  1128. *
  1129. *
  1130. *****************************************************************************/
  1131. template <class WmiKey,class WmiElement>
  1132. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Delete_RightBalance (
  1133. WmiAvlNode *&A ,
  1134. WmiAvlNode *B ,
  1135. bool &a_Decreased
  1136. )
  1137. {
  1138. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1139. if ( a_Decreased )
  1140. {
  1141. switch ( A->m_State )
  1142. {
  1143. case WmiAvlNode :: e_Equal:
  1144. {
  1145. A->m_State = WmiAvlNode :: e_LeftHigher ;
  1146. a_Decreased = false ;
  1147. }
  1148. break ;
  1149. case WmiAvlNode :: e_RightHigher:
  1150. {
  1151. A->m_State = WmiAvlNode :: e_Equal ;
  1152. }
  1153. break ;
  1154. case WmiAvlNode :: e_LeftHigher:
  1155. {
  1156. switch ( B->m_State )
  1157. {
  1158. case WmiAvlNode :: e_Equal:
  1159. {
  1160. a_Decreased = false ;
  1161. WmiAvlNode *t_Parent = A->m_Parent ;
  1162. if ( t_Parent )
  1163. {
  1164. if ( t_Parent->m_Left == A )
  1165. {
  1166. t_Parent->m_Left = B ;
  1167. }
  1168. else
  1169. {
  1170. t_Parent->m_Right = B ;
  1171. }
  1172. }
  1173. else
  1174. {
  1175. m_Root = B ;
  1176. }
  1177. if ( B->m_Right )
  1178. {
  1179. B->m_Right->m_Parent = A ;
  1180. }
  1181. A->m_State = WmiAvlNode :: e_LeftHigher ;
  1182. A->m_Left = B->m_Right ;
  1183. A->m_Parent = B ;
  1184. B->m_State = WmiAvlNode :: e_RightHigher ;
  1185. B->m_Right = A ;
  1186. B->m_Parent = t_Parent ;
  1187. A = B ;
  1188. }
  1189. break ;
  1190. case WmiAvlNode :: e_LeftHigher:
  1191. {
  1192. WmiAvlNode *t_Parent = A->m_Parent ;
  1193. if ( t_Parent )
  1194. {
  1195. if ( t_Parent->m_Left == A )
  1196. {
  1197. t_Parent->m_Left = B ;
  1198. }
  1199. else
  1200. {
  1201. t_Parent->m_Right = B ;
  1202. }
  1203. }
  1204. else
  1205. {
  1206. m_Root = B ;
  1207. }
  1208. if ( B->m_Right )
  1209. {
  1210. B->m_Right->m_Parent = A ;
  1211. }
  1212. A->m_State = WmiAvlNode :: e_Equal ;
  1213. A->m_Left = B->m_Right ;
  1214. A->m_Parent = B ;
  1215. B->m_State = WmiAvlNode :: e_Equal ;
  1216. B->m_Right = A ;
  1217. B->m_Parent = t_Parent ;
  1218. A = B ;
  1219. }
  1220. break ;
  1221. case WmiAvlNode :: e_RightHigher:
  1222. {
  1223. WmiAvlNode *C = A->m_Left->m_Right ;
  1224. WmiAvlNode *t_Parent = A->m_Parent ;
  1225. if ( t_Parent )
  1226. {
  1227. if ( t_Parent->m_Left == A )
  1228. {
  1229. t_Parent->m_Left = C ;
  1230. }
  1231. else
  1232. {
  1233. t_Parent->m_Right = C ;
  1234. }
  1235. }
  1236. else
  1237. {
  1238. m_Root = C ;
  1239. }
  1240. A->m_Parent = C ;
  1241. B->m_Parent = C ;
  1242. if ( C->m_Left )
  1243. {
  1244. C->m_Left->m_Parent = B ;
  1245. }
  1246. if ( C->m_Right )
  1247. {
  1248. C->m_Right->m_Parent = A ;
  1249. }
  1250. A->m_Left = C->m_Right ;
  1251. B->m_Right = C->m_Left ;
  1252. C->m_Left = B ;
  1253. C->m_Right = A ;
  1254. C->m_Parent = t_Parent ;
  1255. switch ( C->m_State )
  1256. {
  1257. case WmiAvlNode :: e_LeftHigher:
  1258. {
  1259. B->m_State = WmiAvlNode :: e_Equal ;
  1260. A->m_State = WmiAvlNode :: e_RightHigher ;
  1261. }
  1262. break ;
  1263. case WmiAvlNode :: e_RightHigher:
  1264. {
  1265. A->m_State = WmiAvlNode :: e_Equal ;
  1266. B->m_State = WmiAvlNode :: e_LeftHigher ;
  1267. }
  1268. break ;
  1269. case WmiAvlNode :: e_Equal:
  1270. {
  1271. B->m_State = WmiAvlNode :: e_Equal ;
  1272. A->m_State = WmiAvlNode :: e_Equal ;
  1273. }
  1274. break ;
  1275. default:
  1276. {
  1277. t_StatusCode = e_StatusCode_Unknown ;
  1278. }
  1279. break ;
  1280. }
  1281. C->m_State = WmiAvlNode :: e_Equal ;
  1282. A = C ;
  1283. }
  1284. break ;
  1285. default:
  1286. {
  1287. t_StatusCode = e_StatusCode_Unknown ;
  1288. }
  1289. break ;
  1290. }
  1291. }
  1292. break ;
  1293. default:
  1294. {
  1295. t_StatusCode = e_StatusCode_Unknown ;
  1296. }
  1297. break ;
  1298. }
  1299. }
  1300. return t_StatusCode ;
  1301. }
  1302. /******************************************************************************
  1303. *
  1304. * Name:
  1305. *
  1306. *
  1307. * Description:
  1308. *
  1309. *
  1310. *****************************************************************************/
  1311. template <class WmiKey,class WmiElement>
  1312. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: RecursiveCheck (
  1313. WmiAvlNode *a_Node ,
  1314. ULONG &a_Count ,
  1315. ULONG a_Height ,
  1316. ULONG &a_MaxHeight
  1317. )
  1318. {
  1319. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1320. a_Height ++ ;
  1321. #if 0
  1322. printf ( "\n" ) ;
  1323. for ( ULONG t_TabIndex = 0 ; t_TabIndex < a_Height ; t_TabIndex ++ )
  1324. {
  1325. printf ( "++++" ) ;
  1326. }
  1327. printf ( "%ld" , a_Node->m_Key ) ;
  1328. switch ( a_Node->m_State )
  1329. {
  1330. case WmiAvlNode :: e_LeftHigher:
  1331. {
  1332. printf ( "\t LH" ) ;
  1333. }
  1334. break ;
  1335. case WmiAvlNode :: e_RightHigher:
  1336. {
  1337. printf ( "\t RH" ) ;
  1338. }
  1339. break ;
  1340. case WmiAvlNode :: e_Equal:
  1341. {
  1342. printf ( "\t E" ) ;
  1343. }
  1344. break ;
  1345. }
  1346. #endif
  1347. if ( t_StatusCode == e_StatusCode_Success )
  1348. {
  1349. ULONG t_LeftHeight = a_Height ;
  1350. WmiAvlNode *t_Left = a_Node->m_Left ;
  1351. if ( t_Left )
  1352. {
  1353. if ( t_Left->m_Parent == a_Node )
  1354. {
  1355. a_Count ++ ;
  1356. t_StatusCode = RecursiveCheck ( t_Left , a_Count , a_Height , t_LeftHeight ) ;
  1357. }
  1358. else
  1359. {
  1360. t_StatusCode = e_StatusCode_Failed ;
  1361. }
  1362. }
  1363. else
  1364. {
  1365. #if 0
  1366. printf ( "\n" ) ;
  1367. for ( ULONG t_TabIndex = 0 ; t_TabIndex <= a_Height ; t_TabIndex ++ )
  1368. {
  1369. printf ( "++++" ) ;
  1370. }
  1371. printf ( "NULL" ) ;
  1372. printf ( "\t E" ) ;
  1373. #endif
  1374. }
  1375. ULONG t_RightHeight = a_Height ;
  1376. WmiAvlNode *t_Right = a_Node->m_Right ;
  1377. if ( t_Right )
  1378. {
  1379. if ( t_Right->m_Parent == a_Node )
  1380. {
  1381. a_Count ++ ;
  1382. t_StatusCode = RecursiveCheck ( t_Right , a_Count , a_Height , t_RightHeight ) ;
  1383. }
  1384. else
  1385. {
  1386. t_StatusCode = e_StatusCode_Failed ;
  1387. }
  1388. }
  1389. else
  1390. {
  1391. #if 0
  1392. printf ( "\n" ) ;
  1393. for ( ULONG t_TabIndex = 0 ; t_TabIndex <= a_Height ; t_TabIndex ++ )
  1394. {
  1395. printf ( "++++" ) ;
  1396. }
  1397. printf ( "NULL" ) ;
  1398. printf ( "\t E" ) ;
  1399. #endif
  1400. }
  1401. switch ( a_Node->m_State )
  1402. {
  1403. case WmiAvlNode :: e_LeftHigher:
  1404. {
  1405. if ( t_LeftHeight <= t_RightHeight )
  1406. {
  1407. t_StatusCode = e_StatusCode_Failed ;
  1408. }
  1409. }
  1410. break ;
  1411. case WmiAvlNode :: e_RightHigher:
  1412. {
  1413. if ( t_LeftHeight >= t_RightHeight )
  1414. {
  1415. t_StatusCode = e_StatusCode_Failed ;
  1416. }
  1417. }
  1418. break ;
  1419. case WmiAvlNode :: e_Equal:
  1420. {
  1421. if ( t_LeftHeight != t_RightHeight )
  1422. {
  1423. t_StatusCode = e_StatusCode_Failed ;
  1424. }
  1425. }
  1426. break ;
  1427. }
  1428. if ( t_LeftHeight < t_RightHeight )
  1429. {
  1430. a_MaxHeight = t_RightHeight ;
  1431. }
  1432. else
  1433. {
  1434. a_MaxHeight = t_LeftHeight ;
  1435. }
  1436. }
  1437. if ( t_StatusCode == e_StatusCode_Success )
  1438. {
  1439. if ( a_Node->m_State == WmiAvlNode :: e_Equal )
  1440. {
  1441. if ( ( ( a_Node->m_Left == 0 ) && ( a_Node->m_Right == 0 ) ) )
  1442. {
  1443. }
  1444. else if ( ! ( a_Node->m_Left && a_Node->m_Right ) )
  1445. {
  1446. t_StatusCode = e_StatusCode_Failed ;
  1447. }
  1448. }
  1449. if ( a_Node->m_State == WmiAvlNode :: e_LeftHigher )
  1450. {
  1451. if ( a_Node->m_Left == NULL )
  1452. {
  1453. t_StatusCode = e_StatusCode_Failed ;
  1454. }
  1455. }
  1456. if ( a_Node->m_State == WmiAvlNode :: e_RightHigher )
  1457. {
  1458. if ( a_Node->m_Right == NULL )
  1459. {
  1460. t_StatusCode = e_StatusCode_Failed ;
  1461. }
  1462. }
  1463. }
  1464. return t_StatusCode ;
  1465. }
  1466. /******************************************************************************
  1467. *
  1468. * Name:
  1469. *
  1470. *
  1471. * Description:
  1472. *
  1473. *
  1474. * case 1:
  1475. *
  1476. * N A
  1477. * / \
  1478. * A ->
  1479. *
  1480. * Parent Decreased,on side based on recursion step
  1481. *
  1482. * case 2:
  1483. *
  1484. * N A
  1485. * / \
  1486. * A ->
  1487. *
  1488. * Parent Decreased,on side based on recursion step
  1489. *
  1490. * case 3:
  1491. * N B
  1492. * / \ / \
  1493. * A B -> A Y
  1494. * / \
  1495. * Y
  1496. *
  1497. * B decreased on Right
  1498. *
  1499. * case 4:
  1500. *
  1501. * N B
  1502. * / \ / \
  1503. * A C -> A C
  1504. * / \ / \
  1505. * B Y X Y
  1506. * \
  1507. * X
  1508. *
  1509. * C decreased on Left, Apply LeftBalance on C
  1510. * Apply RightBalance on B
  1511. *
  1512. * N D
  1513. * / \ / \
  1514. * A C -> A C
  1515. * / \ / \
  1516. * B Y B Y
  1517. * / \ / \
  1518. * D X E X
  1519. * \
  1520. * E
  1521. *
  1522. *****************************************************************************/
  1523. template <class WmiKey,class WmiElement>
  1524. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: DeleteFixup ( WmiAvlNode *a_Node , bool &a_Decreased )
  1525. {
  1526. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1527. a_Decreased = true ;
  1528. WmiAvlNode *t_Left = a_Node->m_Left ;
  1529. WmiAvlNode *t_Right = a_Node->m_Right ;
  1530. WmiAvlNode *t_Parent = a_Node->m_Parent ;
  1531. if ( t_Left && t_Right )
  1532. {
  1533. Iterator t_Iterator ( a_Node ) ;
  1534. t_Iterator.Increment () ;
  1535. WmiAvlNode *t_Successor = t_Iterator.m_Node ;
  1536. t_Successor->m_State = a_Node->m_State ;
  1537. if ( t_Parent )
  1538. {
  1539. if ( t_Parent->m_Left == a_Node )
  1540. {
  1541. t_Parent->m_Left = t_Successor ;
  1542. }
  1543. else
  1544. {
  1545. t_Parent->m_Right = t_Successor;
  1546. }
  1547. }
  1548. else
  1549. {
  1550. m_Root = t_Successor ;
  1551. }
  1552. if ( t_Successor->m_Parent != a_Node )
  1553. {
  1554. /* case 4 */
  1555. if ( a_Node->m_Left )
  1556. {
  1557. a_Node->m_Left->m_Parent = t_Successor ;
  1558. }
  1559. if ( a_Node->m_Right )
  1560. {
  1561. a_Node->m_Right->m_Parent = t_Successor ;
  1562. }
  1563. WmiAvlNode *t_Node = t_Successor->m_Parent ;
  1564. t_Successor->m_Parent->m_Left = t_Successor->m_Right ;
  1565. if ( t_Successor->m_Left )
  1566. {
  1567. t_Successor->m_Left->m_Parent = t_Successor->m_Parent ;
  1568. }
  1569. if ( t_Successor->m_Right )
  1570. {
  1571. t_Successor->m_Right->m_Parent = t_Successor->m_Parent ;
  1572. }
  1573. t_Successor->m_Left = a_Node->m_Left ;
  1574. t_Successor->m_Right = a_Node->m_Right ;
  1575. t_Successor->m_Parent = a_Node->m_Parent ;
  1576. do
  1577. {
  1578. t_StatusCode = Delete_LeftBalance ( t_Node , t_Node->m_Right , a_Decreased ) ;
  1579. #if 0
  1580. ULONG t_Count = 1 ;
  1581. ULONG t_Height = 0 ;
  1582. ULONG t_MaxHeight = 0 ;
  1583. t_StatusCode = RecursiveCheck ( t_Node , t_Count , t_Height , t_MaxHeight ) ;
  1584. if ( t_StatusCode == e_StatusCode_Success )
  1585. {
  1586. }
  1587. #endif
  1588. t_Node = t_Node->m_Parent ;
  1589. }
  1590. while ( ( t_StatusCode == e_StatusCode_Success ) && ( t_Node != t_Successor ) ) ;
  1591. if ( t_StatusCode == e_StatusCode_Success )
  1592. {
  1593. t_StatusCode = Delete_RightBalance ( t_Node , t_Node->m_Left , a_Decreased ) ;
  1594. #if 0
  1595. ULONG t_Count = 1 ;
  1596. ULONG t_Height = 0 ;
  1597. ULONG t_MaxHeight = 0 ;
  1598. t_StatusCode = RecursiveCheck ( t_Node , t_Count , t_Height , t_MaxHeight ) ;
  1599. if ( t_StatusCode == e_StatusCode_Success )
  1600. {
  1601. }
  1602. #endif
  1603. }
  1604. }
  1605. else
  1606. {
  1607. /* case 3 */
  1608. if ( a_Node->m_Left )
  1609. {
  1610. a_Node->m_Left->m_Parent = t_Successor ;
  1611. }
  1612. if ( a_Node->m_Right )
  1613. {
  1614. a_Node->m_Right->m_Parent = t_Successor ;
  1615. }
  1616. t_Successor->m_Left = a_Node->m_Left ;
  1617. t_Successor->m_Parent = a_Node->m_Parent ;
  1618. t_StatusCode = Delete_RightBalance ( t_Successor , t_Successor->m_Left , a_Decreased ) ;
  1619. }
  1620. }
  1621. else
  1622. {
  1623. if ( t_Parent )
  1624. {
  1625. if ( t_Parent->m_Left == a_Node )
  1626. {
  1627. t_Parent->m_Left = t_Left ? t_Left : t_Right ;
  1628. }
  1629. else
  1630. {
  1631. t_Parent->m_Right = t_Left ? t_Left : t_Right ;
  1632. }
  1633. }
  1634. else
  1635. {
  1636. m_Root = a_Node->m_Left ? a_Node->m_Left : a_Node->m_Right ;
  1637. }
  1638. if ( t_Left )
  1639. {
  1640. /* case 1 */
  1641. t_Left->m_Parent = a_Node->m_Parent ;
  1642. t_Left->m_State = a_Node->m_State ;
  1643. t_StatusCode = Delete_LeftBalance ( t_Left , t_Left->m_Right , a_Decreased ) ;
  1644. }
  1645. else if ( t_Right )
  1646. {
  1647. /* case 2 */
  1648. t_Right->m_Parent = a_Node->m_Parent ;
  1649. t_Right->m_State = a_Node->m_State ;
  1650. t_StatusCode = Delete_RightBalance ( t_Right , t_Right->m_Left , a_Decreased ) ;
  1651. }
  1652. }
  1653. a_Node->~WmiAvlNode () ;
  1654. t_StatusCode = m_Allocator.Delete (
  1655. ( void * ) a_Node
  1656. ) ;
  1657. return t_StatusCode ;
  1658. }
  1659. /******************************************************************************
  1660. *
  1661. * Name:
  1662. *
  1663. *
  1664. * Description:
  1665. *
  1666. *
  1667. *****************************************************************************/
  1668. template <class WmiKey,class WmiElement>
  1669. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Merge (
  1670. WmiAvlTree <WmiKey,WmiElement> &a_Tree
  1671. )
  1672. {
  1673. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1674. Iterator t_Iterator = a_Tree.Root ();
  1675. while ( ( ! t_Iterator.Null () ) && ( t_StatusCode == e_StatusCode_Success ) )
  1676. {
  1677. Iterator t_InsertIterator ;
  1678. t_StatusCode = Insert ( t_Iterator.GetKey () , t_Iterator.GetElement () , t_InsertIterator ) ;
  1679. if ( t_StatusCode == e_StatusCode_Success )
  1680. {
  1681. t_StatusCode = a_Tree.Delete ( t_Iterator.GetKey () ) ;
  1682. }
  1683. t_Iterator = a_Tree.Root () ;
  1684. }
  1685. return t_StatusCode ;
  1686. }
  1687. #if 0
  1688. /******************************************************************************
  1689. *
  1690. * Name:
  1691. *
  1692. *
  1693. * Description:
  1694. *
  1695. *
  1696. *****************************************************************************/
  1697. template <class WmiKey,class WmiElement>
  1698. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Insert (
  1699. const WmiKey &a_Key ,
  1700. const WmiElement &a_Element ,
  1701. Iterator &a_Iterator
  1702. )
  1703. {
  1704. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1705. WmiAvlNode *t_AllocNode = NULL ;
  1706. t_StatusCode = m_Allocator.New (
  1707. ( void ** ) & t_AllocNode ,
  1708. sizeof ( WmiAvlNode )
  1709. ) ;
  1710. if ( t_StatusCode == e_StatusCode_Success )
  1711. {
  1712. :: new ( ( void* ) t_AllocNode ) WmiAvlNode () ;
  1713. try
  1714. {
  1715. t_AllocNode->m_Element = a_Element ;
  1716. t_AllocNode->m_Key = a_Key ;
  1717. }
  1718. catch ( Wmi_Heap_Exception &a_Exception )
  1719. {
  1720. t_AllocNode->~WmiAvlNode () ;
  1721. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  1722. ( void * ) t_AllocNode
  1723. ) ;
  1724. return e_StatusCode_OutOfMemory ;
  1725. }
  1726. catch ( ... )
  1727. {
  1728. t_AllocNode->~WmiAvlNode () ;
  1729. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  1730. ( void * ) t_AllocNode
  1731. ) ;
  1732. return e_StatusCode_Unknown
  1733. }
  1734. a_Iterator = Iterator ( t_Node ) ;
  1735. if ( m_Root )
  1736. {
  1737. bool a_Increased ;
  1738. t_StatusCode = RecursiveInsert (
  1739. m_Root ,
  1740. t_AllocNode ,
  1741. a_Increased
  1742. ) ;
  1743. if ( t_StatusCode == e_StatusCode_Success )
  1744. {
  1745. m_Size ++ ;
  1746. }
  1747. else
  1748. {
  1749. t_AllocNode->~WmiAvlNode () ;
  1750. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  1751. ( void * ) t_AllocNode
  1752. ) ;
  1753. }
  1754. }
  1755. else
  1756. {
  1757. m_Root = t_Node ;
  1758. m_Size ++ ;
  1759. }
  1760. }
  1761. else
  1762. {
  1763. a_Iterator = Iterator () ;
  1764. }
  1765. return t_StatusCode ;
  1766. }
  1767. /******************************************************************************
  1768. *
  1769. * Name:
  1770. *
  1771. *
  1772. * Description:
  1773. *
  1774. *
  1775. *****************************************************************************/
  1776. template <class WmiKey,class WmiElement>
  1777. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: RecursiveInsert (
  1778. WmiAvlNode *a_Node ,
  1779. WmiAvlNode *a_Element ,
  1780. bool &a_Increased
  1781. )
  1782. {
  1783. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1784. a_Increased = false ;
  1785. #ifdef INLINE_COMPARE
  1786. LONG t_Compare = CompareElement ( a_Element->m_Key , a_Node->m_Key ) ;
  1787. if ( t_Compare == 0 )
  1788. #else
  1789. if ( a_Key == t_Node->m_Key )
  1790. #endif
  1791. {
  1792. t_StatusCode = e_StatusCode_AlreadyExists ;
  1793. }
  1794. else
  1795. {
  1796. #ifdef INLINE_COMPARE
  1797. if ( t_Compare < 0 )
  1798. #else
  1799. if ( a_Key < t_Node->m_Key )
  1800. #endif
  1801. {
  1802. if ( a_Node->m_Left )
  1803. {
  1804. t_StatusCode = RecursiveInsert ( a_Node->m_Left , a_Element , a_Increased ) ;
  1805. if ( t_StatusCode == e_StatusCode_Success )
  1806. {
  1807. t_StatusCode = Insert_LeftBalance (
  1808. a_Node ,
  1809. a_Node->m_Left ,
  1810. a_Increased
  1811. ) ;
  1812. }
  1813. }
  1814. else
  1815. {
  1816. a_Increased = true ;
  1817. a_Element->m_Parent = a_Node ;
  1818. a_Node->m_Left = a_Element ;
  1819. t_StatusCode = Insert_LeftBalance (
  1820. a_Node ,
  1821. a_Node->m_Left ,
  1822. a_Increased
  1823. ) ;
  1824. }
  1825. }
  1826. else
  1827. {
  1828. if ( a_Node->m_Right )
  1829. {
  1830. t_StatusCode = RecursiveInsert ( a_Node->m_Right , a_Element , a_Increased ) ;
  1831. if ( t_StatusCode == e_StatusCode_Success )
  1832. {
  1833. t_StatusCode = Insert_RightBalance (
  1834. a_Node ,
  1835. a_Node->m_Right ,
  1836. a_Increased
  1837. ) ;
  1838. }
  1839. }
  1840. else
  1841. {
  1842. a_Increased = true ;
  1843. a_Element->m_Parent = a_Node ;
  1844. a_Node->m_Right = a_Element ;
  1845. t_StatusCode = Insert_RightBalance (
  1846. a_Node ,
  1847. a_Node->m_Right ,
  1848. a_Increased
  1849. ) ;
  1850. }
  1851. }
  1852. }
  1853. return t_StatusCode ;
  1854. }
  1855. /******************************************************************************
  1856. *
  1857. * Name:
  1858. *
  1859. *
  1860. * Description:
  1861. *
  1862. *
  1863. *****************************************************************************/
  1864. template <class WmiKey,class WmiElement>
  1865. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: Delete (
  1866. const WmiKey &a_Key
  1867. )
  1868. {
  1869. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1870. if ( m_Root )
  1871. {
  1872. bool t_Decreased = false ;
  1873. t_StatusCode = RecursiveDelete ( m_Root , a_Key , t_Decreased ) ;
  1874. if ( t_StatusCode == e_StatusCode_Success )
  1875. {
  1876. m_Size -- ;
  1877. }
  1878. }
  1879. else
  1880. {
  1881. t_StatusCode = e_StatusCode_NotFound ;
  1882. }
  1883. return t_StatusCode ;
  1884. }
  1885. /******************************************************************************
  1886. *
  1887. * Name:
  1888. *
  1889. *
  1890. * Description:
  1891. *
  1892. *
  1893. *****************************************************************************/
  1894. template <class WmiKey,class WmiElement>
  1895. WmiStatusCode WmiAvlTree <WmiKey,WmiElement> :: RecursiveDelete (
  1896. WmiAvlNode *a_Node ,
  1897. const WmiKey &a_Key ,
  1898. bool &a_Decreased
  1899. )
  1900. {
  1901. WmiStatusCode t_StatusCode = e_StatusCode_NotFound ;
  1902. #ifdef INLINE_COMPARE
  1903. LONG t_Compare = CompareElement ( a_Key , a_Node->m_Key ) ;
  1904. if ( t_Compare == 0 )
  1905. #else
  1906. if ( a_Key == t_Node->m_Key )
  1907. #endif
  1908. {
  1909. t_StatusCode = DeleteFixup ( a_Node , a_Decreased ) ;
  1910. }
  1911. else
  1912. {
  1913. #ifdef INLINE_COMPARE
  1914. if ( t_Compare < 0 )
  1915. #else
  1916. if ( a_Key < t_Node->m_Key )
  1917. #endif
  1918. {
  1919. if ( a_Node->m_Left )
  1920. {
  1921. t_StatusCode = RecursiveDelete ( a_Node->m_Left , a_Key , a_Decreased ) ;
  1922. if ( t_StatusCode == e_StatusCode_Success )
  1923. {
  1924. t_StatusCode = Delete_LeftBalance ( a_Node , a_Node->m_Right , a_Decreased ) ;
  1925. }
  1926. }
  1927. }
  1928. else
  1929. {
  1930. if ( a_Node->m_Right )
  1931. {
  1932. t_StatusCode = RecursiveDelete ( a_Node->m_Right , a_Key , a_Decreased ) ;
  1933. if ( t_StatusCode == e_StatusCode_Success )
  1934. {
  1935. t_StatusCode = Delete_RightBalance ( a_Node , a_Node->m_Left , a_Decreased ) ;
  1936. }
  1937. }
  1938. }
  1939. }
  1940. return t_StatusCode ;
  1941. }
  1942. #endif
  1943. #endif _AVLTREE_CPP