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.

3793 lines
88 KiB

  1. #ifndef _BPLUSTREE_CPP
  2. #define _BPLUSTREE_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 <BPTree.h>
  26. #endif
  27. #if 0
  28. #define INSERT_DEBUG
  29. #define DELETE_DEBUG
  30. #define FIND_DEBUG
  31. #define COMMON_DEBUG
  32. #endif
  33. /******************************************************************************
  34. *
  35. * Name:
  36. *
  37. *
  38. * Description:
  39. *
  40. *
  41. *****************************************************************************/
  42. WmiBPlusTree :: WmiBPlusTree (
  43. WmiAllocator &a_Allocator ,
  44. WmiBlockInterface &a_BlockAllocator ,
  45. GUID &a_Identifier ,
  46. ULONG a_BlockSize ,
  47. ULONG a_KeyType ,
  48. ULONG a_KeyTypeLength ,
  49. ComparatorFunction a_ComparatorFunction ,
  50. void *a_ComparatorOperand
  51. ) : m_Allocator ( a_Allocator ) ,
  52. m_BlockAllocator ( a_BlockAllocator ) ,
  53. m_Size ( 0 ) ,
  54. m_Root ( 0 ) ,
  55. m_Identifier ( a_Identifier ) ,
  56. m_BlockSize ( a_BlockSize ) ,
  57. m_KeyType ( a_KeyType ) ,
  58. m_KeyTypeLength ( a_KeyTypeLength ) ,
  59. m_ComparatorFunction ( a_ComparatorFunction ) ,
  60. m_ComparatorOperand ( a_ComparatorOperand )
  61. {
  62. }
  63. /******************************************************************************
  64. *
  65. * Name:
  66. *
  67. *
  68. * Description:
  69. *
  70. *
  71. *****************************************************************************/
  72. WmiBPlusTree :: ~WmiBPlusTree ()
  73. {
  74. WmiStatusCode t_StatusCode = UnInitialize () ;
  75. }
  76. /******************************************************************************
  77. *
  78. * Name:
  79. *
  80. *
  81. * Description:
  82. *
  83. *
  84. *****************************************************************************/
  85. WmiStatusCode WmiBPlusTree :: Initialize ()
  86. {
  87. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  88. return t_StatusCode ;
  89. }
  90. /******************************************************************************
  91. *
  92. * Name:
  93. *
  94. *
  95. * Description:
  96. *
  97. *
  98. *****************************************************************************/
  99. WmiStatusCode WmiBPlusTree :: UnInitialize ()
  100. {
  101. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  102. if ( m_Root )
  103. {
  104. t_StatusCode = RecursiveUnInitialize ( m_Root ) ;
  105. m_Root = NULL ;
  106. }
  107. return t_StatusCode ;
  108. }
  109. /******************************************************************************
  110. *
  111. * Name:
  112. *
  113. *
  114. * Description:
  115. *
  116. *
  117. *****************************************************************************/
  118. WmiStatusCode WmiBPlusTree :: RecursiveUnInitialize ( WmiAbsoluteBlockOffSet &a_BlockOffSet )
  119. {
  120. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  121. return t_StatusCode ;
  122. }
  123. /******************************************************************************
  124. *
  125. * Name:
  126. *
  127. *
  128. * Description:
  129. *
  130. *
  131. *****************************************************************************/
  132. void WmiBPlusTree :: Recurse ()
  133. {
  134. OutputDebugString ( L"\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ;
  135. if ( m_Root )
  136. {
  137. BYTE *t_Block = NULL ;
  138. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ;
  139. if ( t_StatusCode == e_StatusCode_Success )
  140. {
  141. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  142. Recurse ( t_Node , m_Root ) ;
  143. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  144. }
  145. }
  146. OutputDebugString ( L"\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ;
  147. }
  148. /******************************************************************************
  149. *
  150. * Name:
  151. *
  152. *
  153. * Description:
  154. *
  155. *
  156. *****************************************************************************/
  157. void WmiBPlusTree :: Recurse (
  158. WmiBPKeyNode *a_Node ,
  159. WmiAbsoluteBlockOffSet &a_BlockOffSet
  160. )
  161. {
  162. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  163. wchar_t t_StringBuffer [ 1024 ] ;
  164. swprintf ( t_StringBuffer , L"\n(%I64x)" , a_BlockOffSet ) ;
  165. OutputDebugString ( t_StringBuffer ) ;
  166. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  167. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  168. ULONG t_KeyOffSet ;
  169. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  170. if ( t_Leaf )
  171. {
  172. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  173. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  174. }
  175. else
  176. {
  177. t_KeyOffSet = WmiBlockKeyOffSet ;
  178. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  179. }
  180. ULONG t_NodeStart = a_Node->GetNodeStart () ;
  181. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  182. if ( t_Leaf )
  183. {
  184. if ( a_BlockOffSet == m_Root )
  185. {
  186. }
  187. else
  188. {
  189. if ( a_Node->GetNodeSize () < ( MaxLeafKeys () >> 1 ) )
  190. {
  191. OutputDebugString ( L"\nInvalid Leaf Balance" ) ;
  192. }
  193. }
  194. for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ )
  195. {
  196. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
  197. WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ;
  198. #if 0
  199. wchar_t t_StringBuffer [ 1024 ] ;
  200. swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) t_Key.GetConstData () ) ;
  201. OutputDebugString ( t_StringBuffer ) ;
  202. #endif
  203. t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ;
  204. }
  205. }
  206. else
  207. {
  208. if ( a_BlockOffSet == m_Root )
  209. {
  210. }
  211. else
  212. {
  213. if ( a_Node->GetNodeSize () < ( MaxKeys () >> 1 ) )
  214. {
  215. OutputDebugString ( L"\nInvalid Balance" ) ;
  216. }
  217. }
  218. for ( ULONG t_Index = t_NodeStart ; t_Index <= t_NodeSize ; t_Index ++ )
  219. {
  220. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
  221. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  222. CopyMemory (
  223. ( BYTE * ) & t_ChildOffSet ,
  224. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet ,
  225. sizeof ( WmiAbsoluteBlockOffSet )
  226. ) ;
  227. wchar_t t_StringBuffer [ 1024 ] ;
  228. swprintf ( t_StringBuffer , L"\t(%I64x)" , t_ChildOffSet ) ;
  229. OutputDebugString ( t_StringBuffer ) ;
  230. t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ;
  231. }
  232. t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  233. for ( t_Index = t_NodeStart ; t_Index <= t_NodeSize ; t_Index ++ )
  234. {
  235. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
  236. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  237. CopyMemory (
  238. ( BYTE * ) & t_ChildOffSet ,
  239. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet ,
  240. sizeof ( WmiAbsoluteBlockOffSet )
  241. ) ;
  242. BYTE *t_Block = NULL ;
  243. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ;
  244. if ( t_StatusCode == e_StatusCode_Success )
  245. {
  246. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  247. Recurse (
  248. t_Node ,
  249. t_ChildOffSet
  250. ) ;
  251. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  252. }
  253. if ( t_Index < t_NodeSize )
  254. {
  255. #if 0
  256. WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ;
  257. wchar_t t_StringBuffer [ 1024 ] ;
  258. swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) t_Key.GetConstData () ) ;
  259. OutputDebugString ( t_StringBuffer ) ;
  260. #endif
  261. }
  262. t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ;
  263. }
  264. }
  265. }
  266. /******************************************************************************
  267. *
  268. * Name:
  269. *
  270. *
  271. * Description:
  272. *
  273. *
  274. *****************************************************************************/
  275. void WmiBPlusTree :: PrintNode (
  276. wchar_t *a_Prefix ,
  277. WmiBPKeyNode *a_Node ,
  278. WmiAbsoluteBlockOffSet &a_BlockOffSet
  279. )
  280. {
  281. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  282. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  283. ULONG t_KeyOffSet ;
  284. ULONG t_KeyPtrOffSet ;
  285. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  286. if ( t_Leaf )
  287. {
  288. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  289. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  290. }
  291. else
  292. {
  293. t_KeyOffSet = WmiBlockKeyOffSet ;
  294. t_KeyPtrOffSet = WmiBlockKeyPointerOffSet ;
  295. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  296. }
  297. ULONG t_NodeStart = a_Node->GetNodeStart () ;
  298. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  299. OutputDebugString ( L"\n======================================" ) ;
  300. OutputDebugString ( a_Prefix ) ;
  301. if ( t_Leaf )
  302. {
  303. OutputDebugString ( L"\nLeaf" ) ;
  304. if ( a_BlockOffSet == m_Root )
  305. {
  306. OutputDebugString ( L"\nRoot" ) ;
  307. }
  308. else
  309. {
  310. if ( a_Node->GetNodeSize () < ( MaxLeafKeys () >> 1 ) )
  311. {
  312. OutputDebugString ( L"\nInvalid Balance" ) ;
  313. }
  314. }
  315. }
  316. else
  317. {
  318. OutputDebugString ( L"\nInternal" ) ;
  319. if ( a_BlockOffSet == m_Root )
  320. {
  321. OutputDebugString ( L"\nRoot" ) ;
  322. }
  323. else
  324. {
  325. if ( a_Node->GetNodeSize () < ( MaxKeys () >> 1 ) )
  326. {
  327. OutputDebugString ( L"\nInvalid Balance" ) ;
  328. }
  329. }
  330. }
  331. wchar_t t_StringBuffer [ 1024 ] ;
  332. swprintf ( t_StringBuffer , L"\n%I64x" , a_BlockOffSet ) ;
  333. OutputDebugString ( t_StringBuffer ) ;
  334. OutputDebugString ( L"\n--------------------------------------" ) ;
  335. for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ )
  336. {
  337. BYTE *t_KeyBuffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
  338. if ( t_Leaf )
  339. {
  340. WmiBPElement t_Element = 0 ;
  341. CopyMemory (
  342. ( BYTE * ) & t_Element ,
  343. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet ,
  344. sizeof ( WmiAbsoluteBlockOffSet )
  345. ) ;
  346. swprintf (
  347. t_StringBuffer ,
  348. L"\n(%I64x,%I64x)" ,
  349. * ( UINT64 * ) t_KeyBuffer ,
  350. t_Element
  351. ) ;
  352. }
  353. else
  354. {
  355. BYTE *t_LeftPointerBuffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyPtrOffSet ;
  356. BYTE *t_RightPointerBuffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyPtrOffSet + t_InternalKeySize ;
  357. WmiBPElement t_Element = 0 ;
  358. CopyMemory (
  359. ( BYTE * ) & t_Element ,
  360. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet ,
  361. sizeof ( WmiAbsoluteBlockOffSet )
  362. ) ;
  363. swprintf (
  364. t_StringBuffer ,
  365. L"\n(%I64x),(%I64x,%I64x),(%I64x)" ,
  366. * ( UINT64 * ) t_LeftPointerBuffer ,
  367. * ( UINT64 * ) t_KeyBuffer ,
  368. t_Element ,
  369. * ( UINT64 * ) t_RightPointerBuffer
  370. ) ;
  371. }
  372. OutputDebugString ( t_StringBuffer ) ;
  373. t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ;
  374. }
  375. OutputDebugString ( L"\n======================================" ) ;
  376. }
  377. /******************************************************************************
  378. *
  379. * Name:
  380. *
  381. *
  382. * Description:
  383. *
  384. *
  385. *****************************************************************************/
  386. WmiStatusCode WmiBPlusTree :: PositionInBlock (
  387. WmiBPKeyNode *a_Node ,
  388. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  389. ULONG &a_NodeIndex ,
  390. WmiRelativeBlockOffSet &a_NodeOffSet ,
  391. WmiAbsoluteBlockOffSet &a_ChildOffSet
  392. )
  393. {
  394. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  395. #ifdef COMMON_DEBUG
  396. PrintNode ( L"\nFindNextInBlock" , a_Node , a_BlockOffSet ) ;
  397. #endif
  398. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  399. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  400. if ( t_Leaf )
  401. {
  402. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  403. }
  404. else
  405. {
  406. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  407. }
  408. ULONG t_NodeStart = a_Node->GetNodeStart () ;
  409. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  410. WmiRelativeBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  411. t_BlockOffSet = t_BlockOffSet + t_NodeStart * t_InternalKeySize + a_NodeIndex * t_InternalKeySize ;
  412. if ( t_Leaf )
  413. {
  414. if ( a_NodeIndex < t_NodeSize )
  415. {
  416. a_NodeOffSet = t_BlockOffSet ;
  417. a_ChildOffSet = 0 ;
  418. }
  419. else
  420. {
  421. t_StatusCode = e_StatusCode_NotFound ;
  422. }
  423. }
  424. else
  425. {
  426. if ( a_NodeIndex <= t_NodeSize )
  427. {
  428. CopyMemory (
  429. ( BYTE * ) & a_ChildOffSet ,
  430. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet ,
  431. sizeof ( WmiAbsoluteBlockOffSet )
  432. ) ;
  433. if ( a_NodeIndex < t_NodeSize )
  434. {
  435. a_NodeOffSet = t_BlockOffSet ;
  436. }
  437. else
  438. {
  439. a_NodeOffSet = 0 ;
  440. }
  441. }
  442. else
  443. {
  444. t_StatusCode = e_StatusCode_NotFound ;
  445. }
  446. }
  447. return t_StatusCode ;
  448. }
  449. /******************************************************************************
  450. *
  451. * Name:
  452. *
  453. *
  454. * Description:
  455. *
  456. *
  457. *****************************************************************************/
  458. WmiStatusCode WmiBPlusTree :: GetKeyElement (
  459. WmiBPKeyNode *a_Node ,
  460. const WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  461. const ULONG &a_NodeIndex ,
  462. Iterator &a_Iterator
  463. )
  464. {
  465. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  466. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  467. if ( t_Leaf )
  468. {
  469. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  470. }
  471. else
  472. {
  473. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  474. }
  475. ULONG t_NodeStart = a_Node->GetNodeStart () ;
  476. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  477. WmiRelativeBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  478. t_BlockOffSet = t_BlockOffSet + t_NodeStart * t_InternalKeySize + a_NodeIndex * t_InternalKeySize ;
  479. if ( t_Leaf )
  480. {
  481. CopyMemory (
  482. ( BYTE * ) & a_Iterator.GetElement () ,
  483. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet ,
  484. sizeof ( WmiAbsoluteBlockOffSet )
  485. ) ;
  486. CopyMemory (
  487. ( BYTE * ) a_Iterator.GetKey ().GetData () ,
  488. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyOffSet ,
  489. GetKeyTypeLength ()
  490. ) ;
  491. }
  492. else
  493. {
  494. CopyMemory (
  495. ( BYTE * ) & a_Iterator.GetElement () ,
  496. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet ,
  497. sizeof ( WmiAbsoluteBlockOffSet )
  498. ) ;
  499. CopyMemory (
  500. ( BYTE * ) a_Iterator.GetKey ().GetData () ,
  501. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyOffSet ,
  502. GetKeyTypeLength ()
  503. ) ;
  504. }
  505. return e_StatusCode_Success ;
  506. }
  507. /******************************************************************************
  508. *
  509. * Name:
  510. *
  511. *
  512. * Description:
  513. *
  514. *
  515. *****************************************************************************/
  516. WmiStatusCode WmiBPlusTree :: LeftMost (
  517. Iterator &a_Iterator
  518. )
  519. {
  520. WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ;
  521. ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ;
  522. WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
  523. WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
  524. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  525. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  526. do
  527. {
  528. BYTE *t_Block = NULL ;
  529. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ;
  530. if ( t_StatusCode == e_StatusCode_Success )
  531. {
  532. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  533. t_StatusCode = PositionInBlock (
  534. t_Node ,
  535. t_BlockOffSet ,
  536. t_NodeIndex ,
  537. t_NodeOffSet ,
  538. t_ChildOffSet
  539. ) ;
  540. if ( t_StatusCode == e_StatusCode_Success )
  541. {
  542. if ( t_ChildOffSet )
  543. {
  544. t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ;
  545. }
  546. else
  547. {
  548. a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
  549. a_Iterator.SetNodeOffSet ( t_BlockOffSet ) ;
  550. t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ;
  551. }
  552. }
  553. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  554. t_NodeIndex = 0 ;
  555. t_BlockOffSet = t_ChildOffSet ;
  556. }
  557. } while ( ( t_StatusCode == e_StatusCode_Success ) && t_ChildOffSet ) ;
  558. return t_StatusCode ;
  559. }
  560. /******************************************************************************
  561. *
  562. * Name:
  563. *
  564. *
  565. * Description:
  566. *
  567. *
  568. *****************************************************************************/
  569. WmiStatusCode WmiBPlusTree :: RightMost (
  570. Iterator &a_Iterator
  571. )
  572. {
  573. WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ;
  574. ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ;
  575. WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
  576. WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
  577. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  578. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  579. do
  580. {
  581. BYTE *t_Block = NULL ;
  582. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ;
  583. if ( t_StatusCode == e_StatusCode_Success )
  584. {
  585. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  586. BOOL t_Leaf = ( ( t_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  587. if ( t_Leaf )
  588. {
  589. t_NodeIndex = t_Node->GetNodeSize () - t_Node->GetNodeStart () - 1 ;
  590. }
  591. else
  592. {
  593. t_NodeIndex = t_Node->GetNodeSize () - t_Node->GetNodeStart () ;
  594. }
  595. t_StatusCode = PositionInBlock (
  596. t_Node ,
  597. t_BlockOffSet ,
  598. t_NodeIndex ,
  599. t_NodeOffSet ,
  600. t_ChildOffSet
  601. ) ;
  602. if ( t_StatusCode == e_StatusCode_Success )
  603. {
  604. if ( t_ChildOffSet )
  605. {
  606. t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ;
  607. }
  608. else
  609. {
  610. a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
  611. a_Iterator.SetNodeOffSet ( t_BlockOffSet ) ;
  612. t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ;
  613. }
  614. }
  615. t_NodeIndex = 0 ;
  616. t_BlockOffSet = t_ChildOffSet ;
  617. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  618. }
  619. } while ( ( t_StatusCode == e_StatusCode_Success ) && t_ChildOffSet ) ;
  620. return t_StatusCode ;
  621. }
  622. /******************************************************************************
  623. *
  624. * Name:
  625. *
  626. *
  627. * Description:
  628. *
  629. *
  630. *****************************************************************************/
  631. WmiStatusCode WmiBPlusTree :: Increment (
  632. Iterator &a_Iterator
  633. )
  634. {
  635. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  636. WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ;
  637. ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ;
  638. WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
  639. if ( t_BlockOffSet )
  640. {
  641. BYTE *t_Block = NULL ;
  642. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ;
  643. if ( t_StatusCode == e_StatusCode_Success )
  644. {
  645. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  646. t_NodeIndex ++ ;
  647. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  648. WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
  649. WmiStatusCode t_TempStatusCode = PositionInBlock (
  650. t_Node ,
  651. t_BlockOffSet ,
  652. t_NodeIndex ,
  653. t_NodeOffSet ,
  654. t_ChildOffSet
  655. ) ;
  656. if ( t_TempStatusCode == e_StatusCode_Success )
  657. {
  658. if ( t_ChildOffSet )
  659. {
  660. t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ;
  661. if ( t_StatusCode == e_StatusCode_Success )
  662. {
  663. BYTE *t_Block = NULL ;
  664. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ;
  665. if ( t_StatusCode == e_StatusCode_Success )
  666. {
  667. WmiBPKeyNode *t_ChildNode = ( WmiBPKeyNode * ) t_Block ;
  668. a_Iterator.SetNodeOffSet ( t_ChildOffSet ) ;
  669. a_Iterator.SetNodeIndex ( t_ChildNode->GetNodeStart () ) ;
  670. t_StatusCode = LeftMost ( a_Iterator ) ;
  671. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  672. }
  673. }
  674. }
  675. else
  676. {
  677. a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
  678. t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ;
  679. }
  680. }
  681. else
  682. {
  683. IteratorPosition t_Position ;
  684. while ( ( t_TempStatusCode = t_Stack.Top ( t_Position ) ) == e_StatusCode_Success )
  685. {
  686. t_Stack.Pop () ;
  687. BYTE *t_Block = NULL ;
  688. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_Position.GetNodeOffSet () , t_Block ) ;
  689. if ( t_StatusCode == e_StatusCode_Success )
  690. {
  691. WmiBPKeyNode *t_ParentNode = ( WmiBPKeyNode * ) t_Block ;
  692. if ( t_Position.GetNodeIndex () < ( t_ParentNode->GetNodeSize () - t_ParentNode->GetNodeStart () ) )
  693. {
  694. a_Iterator.SetNodeIndex ( t_Position.GetNodeIndex () ) ;
  695. a_Iterator.SetNodeOffSet ( t_Position.GetNodeOffSet () ) ;
  696. t_StatusCode = GetKeyElement ( t_ParentNode , t_Position.GetNodeOffSet () , t_Position.GetNodeIndex () , a_Iterator ) ;
  697. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  698. break ;
  699. }
  700. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  701. }
  702. }
  703. if ( t_TempStatusCode != e_StatusCode_Success )
  704. {
  705. a_Iterator.SetNodeIndex ( 0 ) ;
  706. a_Iterator.SetNodeOffSet ( 0 ) ;
  707. }
  708. }
  709. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  710. }
  711. }
  712. else
  713. {
  714. t_StatusCode = e_StatusCode_Failed ;
  715. }
  716. return t_StatusCode ;
  717. }
  718. /******************************************************************************
  719. *
  720. * Name:
  721. *
  722. *
  723. * Description:
  724. *
  725. *
  726. *****************************************************************************/
  727. WmiStatusCode WmiBPlusTree :: Decrement (
  728. Iterator &a_Iterator
  729. )
  730. {
  731. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  732. WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ;
  733. ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ;
  734. WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
  735. if ( t_BlockOffSet )
  736. {
  737. BYTE *t_Block = NULL ;
  738. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ;
  739. if ( t_StatusCode == e_StatusCode_Success )
  740. {
  741. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  742. t_NodeIndex -- ;
  743. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  744. WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
  745. WmiStatusCode t_TempStatusCode = PositionInBlock (
  746. t_Node ,
  747. t_BlockOffSet ,
  748. t_NodeIndex ,
  749. t_NodeOffSet ,
  750. t_ChildOffSet
  751. ) ;
  752. if ( t_TempStatusCode == e_StatusCode_Success )
  753. {
  754. if ( t_ChildOffSet )
  755. {
  756. t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ;
  757. if ( t_StatusCode == e_StatusCode_Success )
  758. {
  759. BYTE *t_Block = NULL ;
  760. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ;
  761. if ( t_StatusCode == e_StatusCode_Success )
  762. {
  763. WmiBPKeyNode *t_ChildNode = ( WmiBPKeyNode * ) t_Block ;
  764. a_Iterator.SetNodeOffSet ( t_ChildOffSet ) ;
  765. a_Iterator.SetNodeIndex ( t_ChildNode->GetNodeStart () + t_ChildNode->GetNodeSize () - 1 ) ;
  766. t_StatusCode = RightMost ( a_Iterator ) ;
  767. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  768. }
  769. }
  770. }
  771. else
  772. {
  773. a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
  774. t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ;
  775. }
  776. }
  777. else
  778. {
  779. IteratorPosition t_Position ;
  780. while ( ( t_TempStatusCode = t_Stack.Top ( t_Position ) ) == e_StatusCode_Success )
  781. {
  782. t_Stack.Pop () ;
  783. BYTE *t_Block = NULL ;
  784. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_Position.GetNodeOffSet () , t_Block ) ;
  785. if ( t_StatusCode == e_StatusCode_Success )
  786. {
  787. WmiBPKeyNode *t_ParentNode = ( WmiBPKeyNode * ) t_Block ;
  788. if ( t_Position.GetNodeIndex () > t_ParentNode->GetNodeStart () )
  789. {
  790. a_Iterator.SetNodeIndex ( t_Position.GetNodeIndex () ) ;
  791. a_Iterator.SetNodeOffSet ( t_Position.GetNodeOffSet () ) ;
  792. t_StatusCode = GetKeyElement ( t_ParentNode , t_Position.GetNodeOffSet () , t_Position.GetNodeIndex () - 1 , a_Iterator ) ;
  793. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  794. break ;
  795. }
  796. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  797. }
  798. }
  799. if ( t_TempStatusCode != e_StatusCode_Success )
  800. {
  801. a_Iterator.SetNodeIndex ( 0 ) ;
  802. a_Iterator.SetNodeOffSet ( 0 ) ;
  803. }
  804. }
  805. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  806. }
  807. }
  808. else
  809. {
  810. t_StatusCode = e_StatusCode_Failed ;
  811. }
  812. return t_StatusCode ;
  813. }
  814. /******************************************************************************
  815. *
  816. * Name:
  817. *
  818. *
  819. * Description:
  820. *
  821. *
  822. *****************************************************************************/
  823. WmiBPlusTree :: Iterator &WmiBPlusTree :: Begin (
  824. Iterator &a_Iterator
  825. )
  826. {
  827. if ( m_Root )
  828. {
  829. BYTE *t_Block = NULL ;
  830. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ;
  831. if ( t_StatusCode == e_StatusCode_Success )
  832. {
  833. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  834. a_Iterator.SetNodeOffSet ( m_Root ) ;
  835. a_Iterator.SetNodeIndex ( t_Node->GetNodeStart () ) ;
  836. t_StatusCode = LeftMost ( a_Iterator ) ;
  837. if ( t_StatusCode != e_StatusCode_Success )
  838. {
  839. a_Iterator.SetNodeOffSet ( 0 ) ;
  840. a_Iterator.SetNodeIndex ( 0 ) ;
  841. }
  842. }
  843. else
  844. {
  845. a_Iterator.SetNodeOffSet ( 0 ) ;
  846. a_Iterator.SetNodeIndex ( 0 ) ;
  847. }
  848. }
  849. else
  850. {
  851. a_Iterator.SetNodeOffSet ( 0 ) ;
  852. a_Iterator.SetNodeIndex ( 0 ) ;
  853. }
  854. return a_Iterator ;
  855. }
  856. /******************************************************************************
  857. *
  858. * Name:
  859. *
  860. *
  861. * Description:
  862. *
  863. *
  864. *****************************************************************************/
  865. WmiBPlusTree :: Iterator &WmiBPlusTree :: End (
  866. Iterator &a_Iterator
  867. )
  868. {
  869. if ( m_Root )
  870. {
  871. BYTE *t_Block = NULL ;
  872. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ;
  873. if ( t_StatusCode == e_StatusCode_Success )
  874. {
  875. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  876. a_Iterator.SetNodeOffSet ( m_Root ) ;
  877. a_Iterator.SetNodeIndex ( t_Node->GetNodeStart () + t_Node->GetNodeSize () - 1 ) ;
  878. t_StatusCode = RightMost ( a_Iterator ) ;
  879. if ( t_StatusCode != e_StatusCode_Success )
  880. {
  881. a_Iterator.SetNodeOffSet ( 0 ) ;
  882. a_Iterator.SetNodeIndex ( 0 ) ;
  883. }
  884. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  885. }
  886. else
  887. {
  888. a_Iterator.SetNodeOffSet ( 0 ) ;
  889. a_Iterator.SetNodeIndex ( 0 ) ;
  890. }
  891. }
  892. else
  893. {
  894. a_Iterator.SetNodeOffSet ( 0 ) ;
  895. a_Iterator.SetNodeIndex ( 0 ) ;
  896. }
  897. return a_Iterator ;
  898. }
  899. /******************************************************************************
  900. *
  901. * Name:
  902. *
  903. *
  904. * Description:
  905. *
  906. *
  907. *****************************************************************************/
  908. WmiBPlusTree :: Iterator &WmiBPlusTree :: Root (
  909. Iterator &a_Iterator
  910. )
  911. {
  912. if ( m_Root )
  913. {
  914. BYTE *t_Block = NULL ;
  915. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ;
  916. if ( t_StatusCode == e_StatusCode_Success )
  917. {
  918. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  919. a_Iterator.SetNodeOffSet ( m_Root ) ;
  920. a_Iterator.SetNodeIndex ( t_Node->GetNodeStart () ) ;
  921. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  922. }
  923. else
  924. {
  925. a_Iterator.SetNodeOffSet ( 0 ) ;
  926. a_Iterator.SetNodeIndex ( 0 ) ;
  927. }
  928. }
  929. else
  930. {
  931. a_Iterator.SetNodeOffSet ( 0 ) ;
  932. a_Iterator.SetNodeIndex ( 0 ) ;
  933. }
  934. return a_Iterator ;
  935. }
  936. /******************************************************************************
  937. *
  938. * Name:
  939. *
  940. *
  941. * Description:
  942. *
  943. *
  944. *****************************************************************************/
  945. WmiStatusCode WmiBPlusTree :: FindInBlock (
  946. WmiBPKeyNode *a_Node ,
  947. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  948. const WmiBPKey &a_Key ,
  949. WmiAbsoluteBlockOffSet &a_ChildOffSet ,
  950. WmiBPElement &a_Element ,
  951. WmiRelativeBlockOffSet &a_NodeOffSet ,
  952. ULONG &a_NodeIndex
  953. )
  954. {
  955. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  956. #ifdef COMMON_DEBUG
  957. PrintNode ( L"\nFindInBlock" , a_Node , a_BlockOffSet ) ;
  958. #endif
  959. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  960. ULONG t_KeyOffSet ;
  961. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  962. if ( t_Leaf )
  963. {
  964. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  965. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  966. }
  967. else
  968. {
  969. t_KeyOffSet = WmiBlockKeyOffSet ;
  970. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  971. }
  972. ULONG t_LowerIndex = a_Node->GetNodeStart () ;
  973. ULONG t_UpperIndex = a_Node->GetNodeSize () ;
  974. while ( t_LowerIndex < t_UpperIndex )
  975. {
  976. ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
  977. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_Index * t_InternalKeySize ) ;
  978. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
  979. WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ;
  980. LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ;
  981. if ( t_Compare == 0 )
  982. {
  983. if ( t_Leaf )
  984. {
  985. CopyMemory (
  986. ( BYTE * ) & a_Element ,
  987. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet ,
  988. sizeof ( WmiAbsoluteBlockOffSet )
  989. ) ;
  990. a_NodeOffSet = t_BlockOffSet ;
  991. }
  992. else
  993. {
  994. CopyMemory (
  995. ( BYTE * ) & a_Element ,
  996. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet ,
  997. sizeof ( WmiAbsoluteBlockOffSet )
  998. ) ;
  999. a_NodeOffSet = t_BlockOffSet ;
  1000. }
  1001. a_NodeIndex = t_Index ;
  1002. return t_StatusCode ;
  1003. }
  1004. else
  1005. {
  1006. if ( t_Compare < 0 )
  1007. {
  1008. t_UpperIndex = t_Index ;
  1009. }
  1010. else
  1011. {
  1012. t_LowerIndex = t_Index + 1 ;
  1013. }
  1014. }
  1015. }
  1016. if ( t_Leaf )
  1017. {
  1018. t_StatusCode = e_StatusCode_NotFound ;
  1019. }
  1020. else
  1021. {
  1022. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_UpperIndex * t_InternalKeySize ) ;
  1023. CopyMemory (
  1024. ( BYTE * ) & a_ChildOffSet ,
  1025. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet ,
  1026. sizeof ( WmiAbsoluteBlockOffSet )
  1027. ) ;
  1028. a_NodeIndex = t_UpperIndex ;
  1029. }
  1030. return t_StatusCode ;
  1031. }
  1032. #if 0
  1033. /******************************************************************************
  1034. *
  1035. * Name:
  1036. *
  1037. *
  1038. * Description:
  1039. *
  1040. *
  1041. *****************************************************************************/
  1042. WmiStatusCode WmiBPlusTree :: FindInBlock (
  1043. WmiBPKeyNode *a_Node ,
  1044. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  1045. const WmiBPKey &a_Key ,
  1046. WmiAbsoluteBlockOffSet &a_ChildOffSet ,
  1047. WmiBPElement &a_Element ,
  1048. WmiRelativeBlockOffSet &a_NodeOffSet ,
  1049. ULONG &a_NodeIndex
  1050. )
  1051. {
  1052. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1053. #ifdef COMMON_DEBUG
  1054. PrintNode ( L"\nFindInBlock" , a_Node , a_BlockOffSet ) ;
  1055. #endif
  1056. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  1057. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  1058. ULONG t_KeyOffSet ;
  1059. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  1060. if ( t_Leaf )
  1061. {
  1062. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  1063. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  1064. }
  1065. else
  1066. {
  1067. t_KeyOffSet = WmiBlockKeyOffSet ;
  1068. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  1069. }
  1070. ULONG t_NodeStart = a_Node->GetNodeStart () ;
  1071. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  1072. for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ )
  1073. {
  1074. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
  1075. WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ;
  1076. LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ;
  1077. if ( t_Compare == 0 )
  1078. {
  1079. if ( t_Leaf )
  1080. {
  1081. CopyMemory (
  1082. ( BYTE * ) & a_Element ,
  1083. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet ,
  1084. sizeof ( WmiAbsoluteBlockOffSet )
  1085. ) ;
  1086. a_NodeOffSet = t_BlockOffSet ;
  1087. }
  1088. else
  1089. {
  1090. CopyMemory (
  1091. ( BYTE * ) & a_Element ,
  1092. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet ,
  1093. sizeof ( WmiAbsoluteBlockOffSet )
  1094. ) ;
  1095. a_NodeOffSet = t_BlockOffSet ;
  1096. }
  1097. a_NodeIndex = t_Index ;
  1098. return t_StatusCode ;
  1099. }
  1100. else if ( t_Compare < 0 )
  1101. {
  1102. if ( t_Leaf )
  1103. {
  1104. t_StatusCode = e_StatusCode_NotFound ;
  1105. }
  1106. else
  1107. {
  1108. CopyMemory (
  1109. ( BYTE * ) & a_ChildOffSet ,
  1110. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet ,
  1111. sizeof ( WmiAbsoluteBlockOffSet )
  1112. ) ;
  1113. a_NodeIndex = t_Index ;
  1114. }
  1115. return t_StatusCode ;
  1116. }
  1117. t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ;
  1118. }
  1119. if ( t_Leaf )
  1120. {
  1121. t_StatusCode = e_StatusCode_NotFound ;
  1122. }
  1123. else
  1124. {
  1125. CopyMemory (
  1126. ( BYTE * ) & a_ChildOffSet ,
  1127. ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet ,
  1128. sizeof ( WmiAbsoluteBlockOffSet )
  1129. ) ;
  1130. a_NodeIndex = t_Index ;
  1131. }
  1132. return t_StatusCode ;
  1133. }
  1134. #endif
  1135. /******************************************************************************
  1136. *
  1137. * Name:
  1138. *
  1139. *
  1140. * Description:
  1141. *
  1142. *
  1143. *****************************************************************************/
  1144. WmiStatusCode WmiBPlusTree :: Find (
  1145. const WmiBPKey &a_Key ,
  1146. Iterator &a_Iterator
  1147. )
  1148. {
  1149. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1150. if ( m_Root )
  1151. {
  1152. t_StatusCode = RecursiveFind ( m_Root , a_Key , a_Iterator ) ;
  1153. }
  1154. else
  1155. {
  1156. return e_StatusCode_NotFound ;
  1157. }
  1158. return t_StatusCode ;
  1159. }
  1160. /******************************************************************************
  1161. *
  1162. * Name:
  1163. *
  1164. *
  1165. * Description:
  1166. *
  1167. *
  1168. *****************************************************************************/
  1169. WmiStatusCode WmiBPlusTree :: RecursiveFind (
  1170. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  1171. const WmiBPKey &a_Key ,
  1172. Iterator &a_Iterator
  1173. )
  1174. {
  1175. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  1176. WmiBPElement t_Element = 0 ;
  1177. BYTE *t_Block = NULL ;
  1178. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , a_BlockOffSet , t_Block ) ;
  1179. if ( t_StatusCode == e_StatusCode_Success )
  1180. {
  1181. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  1182. WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
  1183. ULONG t_NodeIndex = 0 ;
  1184. t_StatusCode = FindInBlock (
  1185. t_Node ,
  1186. a_BlockOffSet ,
  1187. a_Key ,
  1188. t_ChildOffSet ,
  1189. t_Element ,
  1190. t_NodeOffSet ,
  1191. t_NodeIndex
  1192. ) ;
  1193. if ( t_StatusCode == e_StatusCode_Success )
  1194. {
  1195. if ( t_ChildOffSet )
  1196. {
  1197. WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ;
  1198. t_StatusCode = t_Stack.Push ( IteratorPosition ( a_BlockOffSet , t_NodeIndex ) ) ;
  1199. if ( t_StatusCode == e_StatusCode_Success )
  1200. {
  1201. t_StatusCode = RecursiveFind ( t_ChildOffSet , a_Key , a_Iterator ) ;
  1202. }
  1203. }
  1204. else
  1205. {
  1206. a_Iterator.SetNodeOffSet ( a_BlockOffSet ) ;
  1207. a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
  1208. a_Iterator.GetElement () = t_Element ;
  1209. CopyMemory (
  1210. a_Iterator.GetKey ().GetData () ,
  1211. a_Key.GetConstData () ,
  1212. GetKeyTypeLength ()
  1213. ) ;
  1214. }
  1215. }
  1216. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  1217. }
  1218. return t_StatusCode ;
  1219. }
  1220. /******************************************************************************
  1221. *
  1222. * Name:
  1223. *
  1224. *
  1225. * Description:
  1226. *
  1227. *
  1228. *****************************************************************************/
  1229. WmiStatusCode WmiBPlusTree :: SetLeafNode (
  1230. WmiBPKeyNode *a_Node ,
  1231. const WmiRelativeBlockOffSet &a_NodeDeltaOffSet ,
  1232. const WmiBPKey &a_Key ,
  1233. const WmiBPElement &a_Element
  1234. )
  1235. {
  1236. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1237. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockLeafKeyOffSet ;
  1238. CopyMemory (
  1239. t_Buffer ,
  1240. ( BYTE * ) a_Key.GetConstData () ,
  1241. a_Key.GetConstDataSize () ,
  1242. ) ;
  1243. t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockLeafKeyElementOffSet ;
  1244. CopyMemory (
  1245. t_Buffer ,
  1246. ( BYTE * ) & ( a_Element ) ,
  1247. sizeof ( a_Element )
  1248. ) ;
  1249. return t_StatusCode ;
  1250. }
  1251. /******************************************************************************
  1252. *
  1253. * Name:
  1254. *
  1255. *
  1256. * Description:
  1257. *
  1258. *
  1259. *****************************************************************************/
  1260. WmiStatusCode WmiBPlusTree :: SetNode (
  1261. WmiBPKeyNode *a_Node ,
  1262. const WmiRelativeBlockOffSet &a_NodeDeltaOffSet ,
  1263. const WmiBPKey &a_Key ,
  1264. const WmiBPElement &a_Element ,
  1265. WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet ,
  1266. WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet
  1267. )
  1268. {
  1269. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1270. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyOffSet ;
  1271. CopyMemory (
  1272. t_Buffer ,
  1273. ( BYTE * ) a_Key.GetConstData () ,
  1274. a_Key.GetConstDataSize () ,
  1275. ) ;
  1276. t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyElementOffSet ;
  1277. CopyMemory (
  1278. t_Buffer ,
  1279. ( BYTE * ) & ( a_Element ) ,
  1280. sizeof ( a_Element )
  1281. ) ;
  1282. t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyPointerOffSet ;
  1283. CopyMemory (
  1284. t_Buffer ,
  1285. ( BYTE * ) & ( a_LeftCutBlockOffSet ) ,
  1286. sizeof ( WmiAbsoluteBlockOffSet )
  1287. ) ;
  1288. t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyOffSet + a_Key.GetConstDataSize () + WmiBlockKeyPointerOffSet ;
  1289. CopyMemory (
  1290. t_Buffer ,
  1291. ( BYTE * ) & ( a_RightCutBlockOffSet ) ,
  1292. sizeof ( WmiAbsoluteBlockOffSet )
  1293. ) ;
  1294. return t_StatusCode ;
  1295. }
  1296. /******************************************************************************
  1297. *
  1298. * Name:
  1299. *
  1300. *
  1301. * Description:
  1302. *
  1303. *
  1304. *****************************************************************************/
  1305. WmiStatusCode WmiBPlusTree :: PerformInsertion (
  1306. WmiBPKeyNode *a_Node ,
  1307. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  1308. const WmiBPKey &a_Key ,
  1309. WmiBPElement &a_Element ,
  1310. WmiBPKey &a_ReBalanceKey ,
  1311. WmiBPElement &a_ReBalanceElement ,
  1312. WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet ,
  1313. WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet ,
  1314. WmiRelativeBlockOffSet &a_PositionBlockOffSet
  1315. )
  1316. {
  1317. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1318. #ifdef INSERT_DEBUG
  1319. OutputDebugString ( L"\n/**************************************" ) ;
  1320. wchar_t t_StringBuffer [ 1024 ] ;
  1321. swprintf ( t_StringBuffer , L"\nInsertion Key = %I64x" , * ( UINT64 * ) a_Key.GetConstData () ) ;
  1322. OutputDebugString ( t_StringBuffer ) ;
  1323. #endif
  1324. WmiRelativeBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
  1325. BOOL t_ReBalance ;
  1326. ULONG t_PartitionPoint ;
  1327. WmiRelativeBlockOffSet t_KeyOffSet ;
  1328. WmiRelativeBlockOffSet t_KeyElementOffSet ;
  1329. WmiRelativeBlockOffSet t_KeyPosition ;
  1330. WmiRelativeBlockOffSet t_KeyPositionIncrement ;
  1331. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  1332. if ( t_Leaf )
  1333. {
  1334. t_KeyPositionIncrement = WmiBlockLeafKeyOffSet + GetKeyTypeLength () ;
  1335. t_ReBalance = ( a_Node->GetNodeSize () >= MaxLeafKeys () ) ? TRUE : FALSE ;
  1336. if ( t_ReBalance )
  1337. {
  1338. t_PartitionPoint = MaxLeafKeys () >> 1 ;
  1339. t_KeyPosition = t_StartBlockOffSet + ( t_PartitionPoint * t_KeyPositionIncrement ) ;
  1340. t_KeyOffSet = t_KeyPosition + WmiBlockLeafKeyOffSet ;
  1341. t_KeyElementOffSet = t_KeyPosition + WmiBlockLeafKeyElementOffSet ;
  1342. }
  1343. }
  1344. else
  1345. {
  1346. t_KeyPositionIncrement = WmiBlockKeyOffSet + GetKeyTypeLength () ;
  1347. t_ReBalance = ( a_Node->GetNodeSize () >= MaxKeys () ) ? TRUE : FALSE ;
  1348. if ( t_ReBalance )
  1349. {
  1350. t_PartitionPoint = MaxKeys () >> 1 ;
  1351. t_KeyPosition = t_StartBlockOffSet + ( t_PartitionPoint * t_KeyPositionIncrement ) ;
  1352. t_KeyOffSet = t_KeyPosition + WmiBlockKeyOffSet ;
  1353. t_KeyElementOffSet = t_KeyPosition + WmiBlockKeyElementOffSet;
  1354. }
  1355. }
  1356. if ( t_ReBalance )
  1357. {
  1358. BYTE *t_PartitionData = NULL ;
  1359. t_StatusCode = m_Allocator.New ( ( void ** ) & t_PartitionData , GetKeyTypeLength () ) ;
  1360. if ( t_StatusCode == e_StatusCode_Success )
  1361. {
  1362. WmiAbsoluteBlockOffSet t_BlockOffSet = 0 ;
  1363. BYTE *t_Block = NULL ;
  1364. WmiStatusCode t_StatusCode = m_BlockAllocator.AllocateBlock (
  1365. 1 ,
  1366. t_BlockOffSet ,
  1367. t_Block
  1368. ) ;
  1369. if ( t_StatusCode == e_StatusCode_Success )
  1370. {
  1371. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  1372. #ifdef INSERT_DEBUG
  1373. PrintNode ( L"\nPre Re Balanced a_Node" , a_Node , a_BlockOffSet ) ;
  1374. PrintNode ( L"\nPre Re Balanced t_Node" , t_Node , t_BlockOffSet ) ;
  1375. #endif
  1376. if ( a_PositionBlockOffSet < t_KeyPosition )
  1377. {
  1378. /*
  1379. * Copy key to trickle up.
  1380. */
  1381. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyOffSet - t_KeyPositionIncrement ;
  1382. CopyMemory (
  1383. ( BYTE * ) t_PartitionData ,
  1384. t_Buffer ,
  1385. GetKeyTypeLength () ,
  1386. ) ;
  1387. a_ReBalanceKey = WmiBPKey ( t_PartitionData , GetKeyTypeLength () , TRUE ) ;
  1388. t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyElementOffSet - t_KeyPositionIncrement ;
  1389. CopyMemory (
  1390. ( BYTE * ) & ( a_ReBalanceElement ) ,
  1391. t_Buffer ,
  1392. sizeof ( a_ReBalanceElement )
  1393. ) ;
  1394. t_Node->SetNodeSize ( t_PartitionPoint ) ;
  1395. t_Node->SetNodeOffSet ( t_BlockOffSet ) ;
  1396. t_Node->SetNodeStart ( 0 ) ;
  1397. a_Node->SetNodeSize ( t_PartitionPoint ) ;
  1398. /*
  1399. * Copy Right partition to new node
  1400. */
  1401. CopyMemory (
  1402. ( ( BYTE * ) t_Node ) + t_StartBlockOffSet ,
  1403. ( ( BYTE * ) a_Node ) + t_KeyPosition ,
  1404. ( ULONG ) ( t_PartitionPoint * t_KeyPositionIncrement ) + ( t_Leaf ? 0 : t_KeyPositionIncrement )
  1405. ) ;
  1406. /*
  1407. * Shuffle memory for key insertion
  1408. */
  1409. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_KeyPositionIncrement ;
  1410. WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ;
  1411. MoveMemory (
  1412. ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet + t_KeyPositionIncrement ,
  1413. ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet ,
  1414. ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement )
  1415. ) ;
  1416. if ( t_Leaf )
  1417. {
  1418. t_StatusCode = SetLeafNode (
  1419. a_Node ,
  1420. a_PositionBlockOffSet ,
  1421. a_Key ,
  1422. a_Element
  1423. ) ;
  1424. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ;
  1425. }
  1426. else
  1427. {
  1428. t_StatusCode = SetNode (
  1429. a_Node ,
  1430. a_PositionBlockOffSet ,
  1431. a_Key ,
  1432. a_Element ,
  1433. a_LeftCutBlockOffSet ,
  1434. a_RightCutBlockOffSet
  1435. ) ;
  1436. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ;
  1437. }
  1438. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
  1439. if ( t_StatusCode == e_StatusCode_Success )
  1440. {
  1441. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ;
  1442. if ( t_StatusCode == e_StatusCode_Success )
  1443. {
  1444. a_LeftCutBlockOffSet = a_BlockOffSet ;
  1445. a_RightCutBlockOffSet = t_BlockOffSet ;
  1446. }
  1447. }
  1448. }
  1449. else if ( a_PositionBlockOffSet > t_KeyPosition )
  1450. {
  1451. /*
  1452. * Copy key to trickle up.
  1453. */
  1454. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyOffSet ;
  1455. CopyMemory (
  1456. ( BYTE * ) t_PartitionData ,
  1457. t_Buffer ,
  1458. GetKeyTypeLength () ,
  1459. ) ;
  1460. a_ReBalanceKey = WmiBPKey ( t_PartitionData , GetKeyTypeLength () , TRUE ) ;
  1461. t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyElementOffSet ;
  1462. CopyMemory (
  1463. ( BYTE * ) & ( a_ReBalanceElement ) ,
  1464. t_Buffer ,
  1465. sizeof ( a_ReBalanceElement )
  1466. ) ;
  1467. t_Node->SetNodeSize ( t_PartitionPoint ) ;
  1468. t_Node->SetNodeOffSet ( t_BlockOffSet ) ;
  1469. t_Node->SetNodeStart ( 0 ) ;
  1470. a_Node->SetNodeSize ( t_PartitionPoint ) ;
  1471. CopyMemory (
  1472. ( ( BYTE * ) t_Node ) + t_StartBlockOffSet ,
  1473. ( ( BYTE * ) a_Node ) + t_KeyPosition + t_KeyPositionIncrement ,
  1474. ( ULONG ) ( ( t_PartitionPoint - 1 ) * t_KeyPositionIncrement ) + ( t_Leaf ? 0 : t_KeyPositionIncrement )
  1475. ) ;
  1476. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + t_Node->GetNodeSize () * t_KeyPositionIncrement ;
  1477. WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) ;
  1478. MoveMemory (
  1479. ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) ,
  1480. ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) - t_KeyPositionIncrement ,
  1481. ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement )
  1482. ) ;
  1483. if ( t_Leaf )
  1484. {
  1485. t_StatusCode = SetLeafNode (
  1486. t_Node ,
  1487. ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) - t_KeyPositionIncrement ,
  1488. a_Key ,
  1489. a_Element
  1490. ) ;
  1491. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ;
  1492. }
  1493. else
  1494. {
  1495. t_StatusCode = SetNode (
  1496. t_Node ,
  1497. ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) - t_KeyPositionIncrement ,
  1498. a_Key ,
  1499. a_Element ,
  1500. a_LeftCutBlockOffSet ,
  1501. a_RightCutBlockOffSet
  1502. ) ;
  1503. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ;
  1504. }
  1505. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
  1506. if ( t_StatusCode == e_StatusCode_Success )
  1507. {
  1508. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ;
  1509. if ( t_StatusCode == e_StatusCode_Success )
  1510. {
  1511. a_LeftCutBlockOffSet = a_BlockOffSet ;
  1512. a_RightCutBlockOffSet = t_BlockOffSet ;
  1513. }
  1514. }
  1515. }
  1516. else
  1517. {
  1518. /*
  1519. * Copy key to trickle up.
  1520. */
  1521. BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyOffSet ;
  1522. CopyMemory (
  1523. ( BYTE * ) t_PartitionData ,
  1524. t_Buffer ,
  1525. GetKeyTypeLength () ,
  1526. ) ;
  1527. WmiBPKey t_TempKey = WmiBPKey ( t_PartitionData , GetKeyTypeLength () , TRUE ) ;
  1528. WmiBPElement t_TempElement ;
  1529. t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyElementOffSet ;
  1530. CopyMemory (
  1531. ( BYTE * ) & ( t_TempElement ) ,
  1532. t_Buffer ,
  1533. sizeof ( t_TempElement )
  1534. ) ;
  1535. a_ReBalanceKey = t_TempKey ;
  1536. a_ReBalanceElement = t_TempElement ;
  1537. t_Node->SetNodeSize ( t_PartitionPoint ) ;
  1538. t_Node->SetNodeOffSet ( t_BlockOffSet ) ;
  1539. t_Node->SetNodeStart ( 0 ) ;
  1540. a_Node->SetNodeSize ( t_PartitionPoint ) ;
  1541. CopyMemory (
  1542. ( ( BYTE * ) t_Node ) + t_StartBlockOffSet ,
  1543. ( ( BYTE * ) a_Node ) + t_KeyPosition + t_KeyPositionIncrement ,
  1544. ( ULONG ) ( ( t_PartitionPoint - 1 ) * t_KeyPositionIncrement ) + ( t_Leaf ? 0 : t_KeyPositionIncrement )
  1545. ) ;
  1546. WmiAbsoluteBlockOffSet t_LeftPointerBlockOffSet = 0 ;
  1547. CopyMemory (
  1548. ( BYTE * ) & t_LeftPointerBlockOffSet ,
  1549. ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) ,
  1550. sizeof ( WmiAbsoluteBlockOffSet )
  1551. ) ;
  1552. WmiAbsoluteBlockOffSet t_RightPointerBlockOffSet = 0 ;
  1553. CopyMemory (
  1554. ( BYTE * ) & t_RightPointerBlockOffSet ,
  1555. ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) + t_KeyPositionIncrement ,
  1556. sizeof ( WmiAbsoluteBlockOffSet )
  1557. ) ;
  1558. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + t_Node->GetNodeSize () * t_KeyPositionIncrement ;
  1559. WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) ;
  1560. MoveMemory (
  1561. ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) + t_KeyPositionIncrement ,
  1562. ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) ,
  1563. ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement )
  1564. ) ;
  1565. LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_TempKey ) ;
  1566. if ( t_Leaf )
  1567. {
  1568. if ( t_Compare < 0 )
  1569. {
  1570. t_StatusCode = SetLeafNode (
  1571. t_Node ,
  1572. ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) ,
  1573. t_TempKey ,
  1574. t_TempElement
  1575. ) ;
  1576. CopyMemory (
  1577. ( BYTE * ) t_PartitionData ,
  1578. a_Key.GetConstData () ,
  1579. GetKeyTypeLength () ,
  1580. ) ;
  1581. CopyMemory (
  1582. ( BYTE * ) & ( a_ReBalanceElement ) ,
  1583. ( BYTE * ) & a_Element ,
  1584. sizeof ( a_ReBalanceElement )
  1585. ) ;
  1586. }
  1587. else
  1588. {
  1589. t_StatusCode = SetLeafNode (
  1590. t_Node ,
  1591. ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) ,
  1592. a_Key ,
  1593. a_Element
  1594. ) ;
  1595. }
  1596. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ;
  1597. }
  1598. else
  1599. {
  1600. if ( t_Compare < 0 )
  1601. {
  1602. t_StatusCode = SetNode (
  1603. t_Node ,
  1604. ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) ,
  1605. t_TempKey ,
  1606. t_TempElement ,
  1607. a_RightCutBlockOffSet ,
  1608. t_LeftPointerBlockOffSet
  1609. ) ;
  1610. CopyMemory (
  1611. ( BYTE * ) t_PartitionData ,
  1612. a_Key.GetConstData () ,
  1613. GetKeyTypeLength () ,
  1614. ) ;
  1615. CopyMemory (
  1616. ( BYTE * ) & ( a_ReBalanceElement ) ,
  1617. ( BYTE * ) & a_Element ,
  1618. sizeof ( a_ReBalanceElement )
  1619. ) ;
  1620. a_RightCutBlockOffSet = t_BlockOffSet ;
  1621. }
  1622. else
  1623. {
  1624. t_StatusCode = SetNode (
  1625. t_Node ,
  1626. ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) ,
  1627. a_Key ,
  1628. a_Element ,
  1629. a_RightCutBlockOffSet ,
  1630. t_RightPointerBlockOffSet
  1631. ) ;
  1632. a_RightCutBlockOffSet = a_BlockOffSet ;
  1633. }
  1634. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ;
  1635. }
  1636. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
  1637. if ( t_StatusCode == e_StatusCode_Success )
  1638. {
  1639. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ;
  1640. if ( t_StatusCode == e_StatusCode_Success )
  1641. {
  1642. a_LeftCutBlockOffSet = a_BlockOffSet ;
  1643. a_RightCutBlockOffSet = t_BlockOffSet ;
  1644. }
  1645. }
  1646. }
  1647. #ifdef INSERT_DEBUG
  1648. OutputDebugString ( L"\n/**************************************" ) ;
  1649. wchar_t t_StringBuffer [ 1024 ] ;
  1650. swprintf ( t_StringBuffer , L"\nReBalance Key = %I64x" , * ( UINT64 * ) a_ReBalanceKey.GetConstData () ) ;
  1651. OutputDebugString ( t_StringBuffer ) ;
  1652. PrintNode ( L"\nRe Balanced a_Node" , a_Node , a_BlockOffSet ) ;
  1653. PrintNode ( L"\nRe Balanced t_Node" , t_Node , t_BlockOffSet ) ;
  1654. #endif
  1655. }
  1656. }
  1657. }
  1658. else
  1659. {
  1660. /*
  1661. * Shuffle memory for insertion
  1662. */
  1663. #ifdef INSERT_DEBUG
  1664. PrintNode ( L"\nPre Shuffled a_Node" , a_Node , a_BlockOffSet ) ;
  1665. #endif
  1666. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_KeyPositionIncrement ;
  1667. WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ;
  1668. MoveMemory (
  1669. ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet + t_KeyPositionIncrement ,
  1670. ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet ,
  1671. ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement )
  1672. ) ;
  1673. if ( t_Leaf )
  1674. {
  1675. t_StatusCode = SetLeafNode (
  1676. a_Node ,
  1677. a_PositionBlockOffSet ,
  1678. a_Key ,
  1679. a_Element
  1680. ) ;
  1681. }
  1682. else
  1683. {
  1684. t_StatusCode = SetNode (
  1685. a_Node ,
  1686. a_PositionBlockOffSet ,
  1687. a_Key ,
  1688. a_Element ,
  1689. a_LeftCutBlockOffSet ,
  1690. a_RightCutBlockOffSet
  1691. ) ;
  1692. }
  1693. a_Node->SetNodeSize ( a_Node->GetNodeSize () + 1 ) ;
  1694. #ifdef INSERT_DEBUG
  1695. PrintNode ( L"\nShuffled a_Node" , a_Node , a_BlockOffSet ) ;
  1696. #endif
  1697. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
  1698. a_ReBalanceElement = 0 ;
  1699. a_LeftCutBlockOffSet = 0 ;
  1700. a_RightCutBlockOffSet = 0 ;
  1701. }
  1702. return t_StatusCode ;
  1703. }
  1704. #if 1
  1705. /******************************************************************************
  1706. *
  1707. * Name:
  1708. *
  1709. *
  1710. * Description:
  1711. *
  1712. *
  1713. *****************************************************************************/
  1714. WmiStatusCode WmiBPlusTree :: InsertInBlock (
  1715. WmiBPKeyNode *a_Node ,
  1716. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  1717. const WmiBPKey &a_Key ,
  1718. WmiBPElement &a_Element ,
  1719. WmiBPKey &a_ReBalanceKey ,
  1720. WmiBPElement &a_ReBalanceElement ,
  1721. WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet ,
  1722. WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet
  1723. )
  1724. {
  1725. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1726. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  1727. ULONG t_KeyOffSet ;
  1728. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  1729. if ( t_Leaf )
  1730. {
  1731. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  1732. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  1733. }
  1734. else
  1735. {
  1736. t_KeyOffSet = WmiBlockKeyOffSet ;
  1737. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  1738. }
  1739. ULONG t_LowerIndex = a_Node->GetNodeStart () ;
  1740. ULONG t_UpperIndex = a_Node->GetNodeSize () ;
  1741. while ( t_LowerIndex < t_UpperIndex )
  1742. {
  1743. ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
  1744. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_Index * t_InternalKeySize ) ;
  1745. WmiBPKey t_Key ( ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet , GetKeyTypeLength () ) ;
  1746. LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ;
  1747. if ( t_Compare == 0 )
  1748. {
  1749. /*
  1750. * Can not happen at this juncture
  1751. */
  1752. return e_StatusCode_AlreadyExists ;
  1753. }
  1754. else
  1755. {
  1756. if ( t_Compare < 0 )
  1757. {
  1758. t_UpperIndex = t_Index ;
  1759. }
  1760. else
  1761. {
  1762. t_LowerIndex = t_Index + 1 ;
  1763. }
  1764. }
  1765. }
  1766. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_UpperIndex * t_InternalKeySize ) ;
  1767. t_StatusCode = PerformInsertion (
  1768. a_Node ,
  1769. a_BlockOffSet ,
  1770. a_Key ,
  1771. a_Element ,
  1772. a_ReBalanceKey ,
  1773. a_ReBalanceElement ,
  1774. a_LeftCutBlockOffSet ,
  1775. a_RightCutBlockOffSet ,
  1776. t_BlockOffSet
  1777. ) ;
  1778. return t_StatusCode ;
  1779. }
  1780. #else
  1781. /******************************************************************************
  1782. *
  1783. * Name:
  1784. *
  1785. *
  1786. * Description:
  1787. *
  1788. *
  1789. *****************************************************************************/
  1790. WmiStatusCode WmiBPlusTree :: InsertInBlock (
  1791. WmiBPKeyNode *a_Node ,
  1792. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  1793. const WmiBPKey &a_Key ,
  1794. WmiBPElement &a_Element ,
  1795. WmiBPKey &a_ReBalanceKey ,
  1796. WmiBPElement &a_ReBalanceElement ,
  1797. WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet ,
  1798. WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet
  1799. )
  1800. {
  1801. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1802. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  1803. ULONG t_KeyOffSet ;
  1804. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  1805. if ( t_Leaf )
  1806. {
  1807. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  1808. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  1809. }
  1810. else
  1811. {
  1812. t_KeyOffSet = WmiBlockKeyOffSet ;
  1813. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  1814. }
  1815. ULONG t_NodeStart = a_Node->GetNodeStart () ;
  1816. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  1817. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  1818. for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ )
  1819. {
  1820. WmiBPKey t_Key ( ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet , GetKeyTypeLength () ) ;
  1821. LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ;
  1822. if ( t_Compare == 0 )
  1823. {
  1824. /*
  1825. * Can not happen at this juncture
  1826. */
  1827. return e_StatusCode_AlreadyExists ;
  1828. }
  1829. else if ( t_Compare < 0 )
  1830. {
  1831. /*
  1832. * Found slot position to insert at.
  1833. */
  1834. t_StatusCode = PerformInsertion (
  1835. a_Node ,
  1836. a_BlockOffSet ,
  1837. a_Key ,
  1838. a_Element ,
  1839. a_ReBalanceKey ,
  1840. a_ReBalanceElement ,
  1841. a_LeftCutBlockOffSet ,
  1842. a_RightCutBlockOffSet ,
  1843. t_BlockOffSet
  1844. ) ;
  1845. return t_StatusCode ;
  1846. }
  1847. t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ;
  1848. }
  1849. /*
  1850. * Found slot at end
  1851. */
  1852. t_StatusCode = PerformInsertion (
  1853. a_Node ,
  1854. a_BlockOffSet ,
  1855. a_Key ,
  1856. a_Element ,
  1857. a_ReBalanceKey ,
  1858. a_ReBalanceElement ,
  1859. a_LeftCutBlockOffSet ,
  1860. a_RightCutBlockOffSet ,
  1861. t_BlockOffSet
  1862. ) ;
  1863. return t_StatusCode ;
  1864. }
  1865. #endif
  1866. /******************************************************************************
  1867. *
  1868. * Name:
  1869. *
  1870. *
  1871. * Description:
  1872. *
  1873. *
  1874. *****************************************************************************/
  1875. WmiStatusCode WmiBPlusTree :: RecursiveInsert (
  1876. WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack ,
  1877. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  1878. const WmiBPKey &a_Key ,
  1879. const WmiBPElement &a_Element
  1880. )
  1881. {
  1882. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  1883. WmiBPElement t_Element = 0 ;
  1884. BYTE *t_Block = NULL ;
  1885. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , a_BlockOffSet , t_Block ) ;
  1886. if ( t_StatusCode == e_StatusCode_Success )
  1887. {
  1888. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  1889. WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
  1890. ULONG t_NodeIndex = 0 ;
  1891. t_StatusCode = FindInBlock (
  1892. t_Node ,
  1893. a_BlockOffSet ,
  1894. a_Key ,
  1895. t_ChildOffSet ,
  1896. t_Element ,
  1897. t_NodeOffSet ,
  1898. t_NodeIndex
  1899. ) ;
  1900. if ( t_StatusCode == e_StatusCode_Success )
  1901. {
  1902. if ( t_Element )
  1903. {
  1904. t_StatusCode = e_StatusCode_AlreadyExists ;
  1905. }
  1906. else
  1907. {
  1908. t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ;
  1909. if ( t_StatusCode == e_StatusCode_Success )
  1910. {
  1911. t_StatusCode = RecursiveInsert (
  1912. a_Stack ,
  1913. t_ChildOffSet ,
  1914. a_Key ,
  1915. a_Element
  1916. ) ;
  1917. }
  1918. }
  1919. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  1920. }
  1921. else
  1922. {
  1923. WmiAbsoluteBlockOffSet t_OffSet = a_BlockOffSet ;
  1924. WmiBPKey t_Key = a_Key ;
  1925. WmiBPElement t_Element = a_Element ;
  1926. WmiBPKey t_ReBalanceKey ;
  1927. WmiBPElement t_ReBalanceElement = a_Element ;
  1928. WmiAbsoluteBlockOffSet t_LeftCutBlockOffSet = 0 ;
  1929. WmiAbsoluteBlockOffSet t_RightCutBlockOffSet = 0 ;
  1930. do
  1931. {
  1932. if ( t_ReBalanceElement )
  1933. {
  1934. t_Node = ( WmiBPKeyNode * ) t_Block ;
  1935. t_StatusCode = InsertInBlock (
  1936. t_Node ,
  1937. t_OffSet ,
  1938. t_Key ,
  1939. t_Element ,
  1940. t_ReBalanceKey ,
  1941. t_ReBalanceElement ,
  1942. t_LeftCutBlockOffSet ,
  1943. t_RightCutBlockOffSet
  1944. ) ;
  1945. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  1946. if ( t_StatusCode == e_StatusCode_Success )
  1947. {
  1948. WmiStatusCode t_TempStatusCode = a_Stack.Top ( t_OffSet ) ;
  1949. if ( t_TempStatusCode != e_StatusCode_Success )
  1950. {
  1951. if ( t_ReBalanceElement )
  1952. {
  1953. t_OffSet = 0 ;
  1954. t_Block = NULL ;
  1955. t_StatusCode = m_BlockAllocator.AllocateBlock (
  1956. 1 ,
  1957. t_OffSet ,
  1958. t_Block
  1959. ) ;
  1960. if ( t_StatusCode == e_StatusCode_Success )
  1961. {
  1962. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  1963. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ;
  1964. t_Node->SetNodeSize ( 1 ) ;
  1965. t_Node->SetNodeOffSet ( t_OffSet ) ;
  1966. t_Node->SetNodeStart ( 0 ) ;
  1967. t_StatusCode = SetNode (
  1968. t_Node ,
  1969. sizeof ( WmiBPKeyNode ) ,
  1970. t_ReBalanceKey ,
  1971. t_ReBalanceElement ,
  1972. t_LeftCutBlockOffSet ,
  1973. t_RightCutBlockOffSet
  1974. ) ;
  1975. if ( t_StatusCode == e_StatusCode_Success )
  1976. {
  1977. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ;
  1978. if ( t_StatusCode == e_StatusCode_Success )
  1979. {
  1980. SetRoot ( t_OffSet ) ;
  1981. #ifdef INSERT_DEBUG
  1982. PrintNode ( L"\nRoot Creation" , t_Node , t_OffSet ) ;
  1983. #endif
  1984. }
  1985. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  1986. }
  1987. else
  1988. {
  1989. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  1990. m_BlockAllocator.FreeBlock (
  1991. 1 ,
  1992. t_OffSet
  1993. ) ;
  1994. }
  1995. }
  1996. }
  1997. if ( t_ReBalanceKey.GetAllocated () )
  1998. {
  1999. m_Allocator.Delete ( t_ReBalanceKey.GetData () ) ;
  2000. }
  2001. return t_StatusCode ;
  2002. }
  2003. else
  2004. {
  2005. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  2006. if ( t_ReBalanceElement )
  2007. {
  2008. t_Block = NULL ;
  2009. t_StatusCode = m_BlockAllocator.ReadBlock (
  2010. 1 ,
  2011. t_OffSet ,
  2012. t_Block
  2013. ) ;
  2014. if ( t_Key.GetAllocated () )
  2015. {
  2016. m_Allocator.Delete ( t_Key.GetData () ) ;
  2017. }
  2018. t_Key = t_ReBalanceKey ;
  2019. t_Element = t_ReBalanceElement ;
  2020. }
  2021. a_Stack.Pop () ;
  2022. }
  2023. }
  2024. }
  2025. else
  2026. {
  2027. if ( t_Key.GetAllocated () )
  2028. {
  2029. m_Allocator.Delete ( t_Key.GetData () ) ;
  2030. }
  2031. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  2032. return e_StatusCode_Success ;
  2033. }
  2034. } while ( t_StatusCode == e_StatusCode_Success ) ;
  2035. if ( t_Key.GetAllocated () )
  2036. {
  2037. m_Allocator.Delete ( t_Key.GetData () ) ;
  2038. }
  2039. }
  2040. }
  2041. return t_StatusCode ;
  2042. }
  2043. /******************************************************************************
  2044. *
  2045. * Name:
  2046. *
  2047. *
  2048. * Description:
  2049. *
  2050. *
  2051. *****************************************************************************/
  2052. WmiStatusCode WmiBPlusTree :: Insert (
  2053. const WmiBPKey &a_Key ,
  2054. const WmiBPElement &a_Element
  2055. )
  2056. {
  2057. #ifdef INSERT_DEBUG
  2058. OutputDebugString ( L"\n/**************************************" ) ;
  2059. wchar_t t_StringBuffer [ 1024 ] ;
  2060. swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) a_Key.GetConstData () ) ;
  2061. OutputDebugString ( t_StringBuffer ) ;
  2062. OutputDebugString ( L"\n======================================" ) ;
  2063. #endif
  2064. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  2065. if ( m_Root )
  2066. {
  2067. WmiStack <WmiAbsoluteBlockOffSet,8> t_Stack ( m_Allocator ) ;
  2068. t_StatusCode = t_Stack.Initialize () ;
  2069. if ( t_StatusCode == e_StatusCode_Success )
  2070. {
  2071. t_StatusCode = RecursiveInsert (
  2072. t_Stack ,
  2073. m_Root ,
  2074. a_Key ,
  2075. a_Element
  2076. ) ;
  2077. }
  2078. }
  2079. else
  2080. {
  2081. WmiAbsoluteBlockOffSet t_BlockOffSet = 0 ;
  2082. BYTE *t_Block = NULL ;
  2083. WmiStatusCode t_StatusCode = m_BlockAllocator.AllocateBlock (
  2084. 1 ,
  2085. t_BlockOffSet ,
  2086. t_Block
  2087. ) ;
  2088. if ( t_StatusCode == e_StatusCode_Success )
  2089. {
  2090. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  2091. t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ;
  2092. t_Node->SetNodeSize ( 1 ) ;
  2093. t_Node->SetNodeOffSet ( t_BlockOffSet ) ;
  2094. t_Node->SetNodeStart ( 0 ) ;
  2095. t_StatusCode = SetLeafNode (
  2096. t_Node ,
  2097. sizeof ( WmiBPKeyNode ) ,
  2098. a_Key ,
  2099. a_Element
  2100. ) ;
  2101. if ( t_StatusCode == e_StatusCode_Success )
  2102. {
  2103. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ;
  2104. if ( t_StatusCode == e_StatusCode_Success )
  2105. {
  2106. SetRoot ( t_BlockOffSet ) ;
  2107. }
  2108. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  2109. }
  2110. else
  2111. {
  2112. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  2113. m_BlockAllocator.FreeBlock (
  2114. 1 ,
  2115. t_BlockOffSet
  2116. ) ;
  2117. }
  2118. }
  2119. }
  2120. if ( t_StatusCode == e_StatusCode_Success )
  2121. {
  2122. m_Size ++ ;
  2123. }
  2124. #ifdef INSERT_DEBUG
  2125. OutputDebugString ( L"\n**************************************\\" ) ;
  2126. #endif
  2127. return t_StatusCode ;
  2128. }
  2129. /******************************************************************************
  2130. *
  2131. * Name:
  2132. *
  2133. *
  2134. * Description:
  2135. *
  2136. *
  2137. *****************************************************************************/
  2138. WmiStatusCode WmiBPlusTree :: StealSiblingNode (
  2139. WmiBPKeyNode *a_ParentNode ,
  2140. WmiAbsoluteBlockOffSet &a_ParentBlockOffSet ,
  2141. WmiBPKeyNode *a_Node ,
  2142. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  2143. WmiRelativeBlockOffSet &a_PositionBlockOffSet ,
  2144. WmiBPKeyNode *a_SiblingNode ,
  2145. WmiAbsoluteBlockOffSet &a_SiblingBlockOffSet ,
  2146. WmiAbsoluteBlockOffSet &a_LeftSiblingBlockOffSet ,
  2147. WmiAbsoluteBlockOffSet &a_RightSiblingBlockOffSet
  2148. )
  2149. {
  2150. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  2151. ULONG t_InternalKeySize ;
  2152. ULONG t_KeyOffSet ;
  2153. ULONG t_ElementOffSet ;
  2154. ULONG t_PointerOffSet ;
  2155. #ifdef DELETE_DEBUG
  2156. OutputDebugString ( L"\nSteal Sibling" ) ;
  2157. PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ;
  2158. PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ;
  2159. PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ;
  2160. #endif
  2161. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  2162. if ( t_Leaf )
  2163. {
  2164. t_InternalKeySize = GetKeyTypeLength () + WmiBlockLeafKeyOffSet ;
  2165. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  2166. t_ElementOffSet = WmiBlockLeafKeyElementOffSet ;
  2167. }
  2168. else
  2169. {
  2170. t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ;
  2171. t_KeyOffSet = WmiBlockKeyOffSet ;
  2172. t_ElementOffSet = WmiBlockKeyElementOffSet ;
  2173. t_PointerOffSet = WmiBlockKeyPointerOffSet ;
  2174. }
  2175. WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
  2176. if ( a_LeftSiblingBlockOffSet )
  2177. {
  2178. /*
  2179. * Shuffle node for insertion
  2180. */
  2181. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize ;
  2182. MoveMemory (
  2183. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_InternalKeySize ,
  2184. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet ,
  2185. ( ULONG ) t_TotalSize + t_InternalKeySize
  2186. ) ;
  2187. /*
  2188. * Copy parent key down
  2189. */
  2190. BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
  2191. BYTE *t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_KeyOffSet ;
  2192. CopyMemory (
  2193. t_ToBuffer ,
  2194. t_FromBuffer ,
  2195. GetKeyTypeLength () ,
  2196. ) ;
  2197. t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
  2198. t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_ElementOffSet ;
  2199. CopyMemory (
  2200. t_ToBuffer ,
  2201. t_FromBuffer ,
  2202. sizeof ( WmiBPElement )
  2203. ) ;
  2204. /*
  2205. * Copy from left
  2206. */
  2207. t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + ( a_SiblingNode->GetNodeSize () - 1 ) * t_InternalKeySize + t_KeyOffSet ;
  2208. t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
  2209. CopyMemory (
  2210. t_ToBuffer ,
  2211. t_FromBuffer ,
  2212. GetKeyTypeLength () ,
  2213. ) ;
  2214. t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + ( a_SiblingNode->GetNodeSize () - 1 ) * t_InternalKeySize + t_ElementOffSet ;
  2215. t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
  2216. CopyMemory (
  2217. t_ToBuffer ,
  2218. t_FromBuffer ,
  2219. sizeof ( WmiBPElement )
  2220. ) ;
  2221. /*
  2222. * Copy pointers from sibling to node
  2223. */
  2224. if ( t_Leaf == FALSE )
  2225. {
  2226. t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_PointerOffSet ;
  2227. t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_PointerOffSet ;
  2228. CopyMemory (
  2229. t_ToBuffer ,
  2230. t_FromBuffer ,
  2231. sizeof ( WmiAbsoluteBlockOffSet )
  2232. ) ;
  2233. }
  2234. }
  2235. else
  2236. {
  2237. /*
  2238. * Copy parent key down
  2239. */
  2240. BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
  2241. BYTE *t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_KeyOffSet ;
  2242. CopyMemory (
  2243. t_ToBuffer ,
  2244. t_FromBuffer ,
  2245. GetKeyTypeLength () ,
  2246. ) ;
  2247. t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
  2248. t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_ElementOffSet ;
  2249. CopyMemory (
  2250. t_ToBuffer ,
  2251. t_FromBuffer ,
  2252. sizeof ( WmiBPElement )
  2253. ) ;
  2254. /*
  2255. * Copy from right
  2256. */
  2257. t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_KeyOffSet ;
  2258. t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
  2259. CopyMemory (
  2260. t_ToBuffer ,
  2261. t_FromBuffer ,
  2262. GetKeyTypeLength () ,
  2263. ) ;
  2264. t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_ElementOffSet ;
  2265. t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
  2266. CopyMemory (
  2267. t_ToBuffer ,
  2268. t_FromBuffer ,
  2269. sizeof ( WmiBPElement )
  2270. ) ;
  2271. if ( t_Leaf == FALSE )
  2272. {
  2273. t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_PointerOffSet ;
  2274. t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_InternalKeySize + WmiBlockKeyPointerOffSet ;
  2275. CopyMemory (
  2276. t_ToBuffer ,
  2277. t_FromBuffer ,
  2278. sizeof ( WmiAbsoluteBlockOffSet )
  2279. ) ;
  2280. }
  2281. /*
  2282. * Shuffle memory due to deletion
  2283. */
  2284. WmiRelativeBlockOffSet t_TotalSize = a_SiblingNode->GetNodeSize () * t_InternalKeySize - t_InternalKeySize ;
  2285. MoveMemory (
  2286. ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet ,
  2287. ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_InternalKeySize ,
  2288. ( ULONG ) t_TotalSize + ( t_Leaf ? 0 : t_InternalKeySize )
  2289. ) ;
  2290. }
  2291. a_Node->SetNodeSize ( a_Node->GetNodeSize () + 1 ) ;
  2292. a_SiblingNode->SetNodeSize ( a_SiblingNode->GetNodeSize () - 1 ) ;
  2293. #ifdef DELETE_DEBUG
  2294. PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ;
  2295. PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ;
  2296. PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ;
  2297. #endif
  2298. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
  2299. if ( t_StatusCode == e_StatusCode_Success )
  2300. {
  2301. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_SiblingNode ) ;
  2302. if ( t_StatusCode == e_StatusCode_Success )
  2303. {
  2304. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_ParentNode ) ;
  2305. }
  2306. }
  2307. return t_StatusCode ;
  2308. }
  2309. /******************************************************************************
  2310. *
  2311. * Name:
  2312. *
  2313. *
  2314. * Description:
  2315. *
  2316. *
  2317. *****************************************************************************/
  2318. WmiStatusCode WmiBPlusTree :: MergeSiblingNode (
  2319. WmiBPKeyNode *a_ParentNode ,
  2320. WmiAbsoluteBlockOffSet &a_ParentBlockOffSet ,
  2321. WmiBPKeyNode *a_Node ,
  2322. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  2323. WmiRelativeBlockOffSet &a_PositionBlockOffSet ,
  2324. WmiBPKeyNode *a_SiblingNode ,
  2325. WmiAbsoluteBlockOffSet &a_SiblingBlockOffSet ,
  2326. WmiAbsoluteBlockOffSet &a_LeftSiblingBlockOffSet ,
  2327. WmiAbsoluteBlockOffSet &a_RightSiblingBlockOffSet
  2328. )
  2329. {
  2330. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  2331. #ifdef DELETE_DEBUG
  2332. OutputDebugString ( L"\nMerging Node and Sibling" ) ;
  2333. PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ;
  2334. PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ;
  2335. PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ;
  2336. #endif
  2337. ULONG t_InternalKeySize ;
  2338. ULONG t_KeyOffSet ;
  2339. ULONG t_ElementOffSet ;
  2340. ULONG t_PointerOffSet ;
  2341. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  2342. if ( t_Leaf )
  2343. {
  2344. t_InternalKeySize = GetKeyTypeLength () + WmiBlockLeafKeyOffSet ;
  2345. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  2346. t_ElementOffSet = WmiBlockLeafKeyElementOffSet ;
  2347. }
  2348. else
  2349. {
  2350. t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ;
  2351. t_KeyOffSet = WmiBlockKeyOffSet ;
  2352. t_ElementOffSet = WmiBlockKeyElementOffSet ;
  2353. t_PointerOffSet = WmiBlockKeyPointerOffSet ;
  2354. }
  2355. WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
  2356. /*
  2357. * Copy sibling key up to parent
  2358. */
  2359. if ( a_LeftSiblingBlockOffSet )
  2360. {
  2361. /*
  2362. * Copy parent key down
  2363. */
  2364. BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
  2365. BYTE *t_ToBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_KeyOffSet ;
  2366. CopyMemory (
  2367. t_ToBuffer ,
  2368. t_FromBuffer ,
  2369. GetKeyTypeLength () ,
  2370. ) ;
  2371. t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
  2372. t_ToBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_ElementOffSet ;
  2373. CopyMemory (
  2374. t_ToBuffer ,
  2375. t_FromBuffer ,
  2376. sizeof ( WmiBPElement )
  2377. ) ;
  2378. /*
  2379. * Copy node into sibling
  2380. */
  2381. if ( t_Leaf )
  2382. {
  2383. WmiRelativeBlockOffSet t_TotalSize = a_Node->GetNodeSize () * t_InternalKeySize ;
  2384. CopyMemory (
  2385. ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_InternalKeySize ,
  2386. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet ,
  2387. ( ULONG ) t_TotalSize
  2388. ) ;
  2389. }
  2390. else
  2391. {
  2392. WmiRelativeBlockOffSet t_TotalSize = a_Node->GetNodeSize () * t_InternalKeySize ;
  2393. CopyMemory (
  2394. ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_InternalKeySize ,
  2395. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet ,
  2396. ( ULONG ) t_TotalSize + t_InternalKeySize
  2397. ) ;
  2398. }
  2399. /*
  2400. * Shuffle memory due to deletion
  2401. */
  2402. ULONG t_ParentInternalKeySize = WmiBlockKeyOffSet + GetKeyTypeLength () ;
  2403. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + ( a_ParentNode->GetNodeSize () * t_ParentInternalKeySize ) ;
  2404. WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ;
  2405. MoveMemory (
  2406. ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet ,
  2407. ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + t_ParentInternalKeySize ,
  2408. ( ULONG ) t_MoveSize
  2409. ) ;
  2410. CopyMemory (
  2411. ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyPointerOffSet ,
  2412. ( BYTE * ) & a_SiblingBlockOffSet ,
  2413. sizeof ( WmiAbsoluteBlockOffSet )
  2414. ) ;
  2415. a_ParentNode->SetNodeSize ( a_ParentNode->GetNodeSize () - 1 ) ;
  2416. a_SiblingNode->SetNodeSize ( a_SiblingNode->GetNodeSize () + a_Node->GetNodeSize () + 1 ) ;
  2417. #ifdef DELETE_DEBUG
  2418. PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ;
  2419. PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ;
  2420. #endif
  2421. t_StatusCode = m_BlockAllocator.FreeBlock ( 1 , a_BlockOffSet ) ;
  2422. if ( t_StatusCode == e_StatusCode_Success )
  2423. {
  2424. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_SiblingNode ) ;
  2425. if ( t_StatusCode == e_StatusCode_Success )
  2426. {
  2427. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_ParentNode ) ;
  2428. }
  2429. }
  2430. }
  2431. else
  2432. {
  2433. /*
  2434. * Copy parent key down
  2435. */
  2436. BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
  2437. BYTE *t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_KeyOffSet ;
  2438. CopyMemory (
  2439. t_ToBuffer ,
  2440. t_FromBuffer ,
  2441. GetKeyTypeLength () ,
  2442. ) ;
  2443. t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
  2444. t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_ElementOffSet ;
  2445. CopyMemory (
  2446. t_ToBuffer ,
  2447. t_FromBuffer ,
  2448. sizeof ( WmiBPElement )
  2449. ) ;
  2450. /*
  2451. * Copy sibling into node
  2452. */
  2453. if ( t_Leaf )
  2454. {
  2455. WmiRelativeBlockOffSet t_TotalSize = a_SiblingNode->GetNodeSize () * t_InternalKeySize ;
  2456. CopyMemory (
  2457. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_InternalKeySize ,
  2458. ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet ,
  2459. ( ULONG ) t_TotalSize
  2460. ) ;
  2461. }
  2462. else
  2463. {
  2464. WmiRelativeBlockOffSet t_TotalSize = a_SiblingNode->GetNodeSize () * t_InternalKeySize ;
  2465. CopyMemory (
  2466. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_InternalKeySize ,
  2467. ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet ,
  2468. ( ULONG ) t_TotalSize + t_InternalKeySize
  2469. ) ;
  2470. }
  2471. /*
  2472. * Shuffle memory due to deletion
  2473. */
  2474. ULONG t_ParentInternalKeySize = WmiBlockKeyOffSet + GetKeyTypeLength () ;
  2475. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_ParentNode->GetNodeSize () * t_ParentInternalKeySize ;
  2476. WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ;
  2477. MoveMemory (
  2478. ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet ,
  2479. ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + t_ParentInternalKeySize ,
  2480. ( ULONG ) t_MoveSize
  2481. ) ;
  2482. CopyMemory (
  2483. ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyPointerOffSet ,
  2484. ( BYTE * ) & a_BlockOffSet ,
  2485. sizeof ( WmiAbsoluteBlockOffSet )
  2486. ) ;
  2487. a_ParentNode->SetNodeSize ( a_ParentNode->GetNodeSize () - 1 ) ;
  2488. a_Node->SetNodeSize ( a_Node->GetNodeSize () + a_SiblingNode->GetNodeSize () + 1 ) ;
  2489. #ifdef DELETE_DEBUG
  2490. PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ;
  2491. PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ;
  2492. #endif
  2493. t_StatusCode = m_BlockAllocator.FreeBlock ( 1 , a_SiblingBlockOffSet ) ;
  2494. if ( t_StatusCode == e_StatusCode_Success )
  2495. {
  2496. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
  2497. if ( t_StatusCode == e_StatusCode_Success )
  2498. {
  2499. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_ParentNode ) ;
  2500. }
  2501. }
  2502. }
  2503. return t_StatusCode ;
  2504. }
  2505. /******************************************************************************
  2506. *
  2507. * Name:
  2508. *
  2509. *
  2510. * Description:
  2511. *
  2512. *
  2513. *****************************************************************************/
  2514. WmiStatusCode WmiBPlusTree :: LocateSuitableSibling (
  2515. WmiBPKeyNode *a_ParentNode ,
  2516. WmiAbsoluteBlockOffSet &a_ParentBlockOffSet ,
  2517. WmiBPKeyNode *a_Node ,
  2518. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  2519. WmiRelativeBlockOffSet &a_PositionBlockOffSet ,
  2520. WmiAbsoluteBlockOffSet &a_LeftSiblingBlockOffSet ,
  2521. WmiAbsoluteBlockOffSet &a_RightSiblingBlockOffSet
  2522. )
  2523. {
  2524. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  2525. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  2526. ULONG t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ;
  2527. ULONG t_NodeStart = a_ParentNode->GetNodeStart () ;
  2528. ULONG t_NodeSize = a_ParentNode->GetNodeSize () ;
  2529. for ( ULONG t_Index = t_NodeStart ; t_Index <= t_NodeSize ; t_Index ++ )
  2530. {
  2531. WmiAbsoluteBlockOffSet t_PointerBlockOffSet ;
  2532. CopyMemory (
  2533. ( BYTE * ) & t_PointerBlockOffSet ,
  2534. ( ( BYTE * ) ( a_ParentNode ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet ,
  2535. sizeof ( WmiAbsoluteBlockOffSet )
  2536. ) ;
  2537. if ( t_PointerBlockOffSet == a_BlockOffSet )
  2538. {
  2539. if ( t_Index )
  2540. {
  2541. a_PositionBlockOffSet = t_BlockOffSet - t_InternalKeySize ;
  2542. CopyMemory (
  2543. ( BYTE * ) & a_LeftSiblingBlockOffSet ,
  2544. ( ( BYTE * ) ( a_ParentNode ) ) + t_BlockOffSet - t_InternalKeySize + WmiBlockKeyPointerOffSet ,
  2545. sizeof ( WmiAbsoluteBlockOffSet )
  2546. ) ;
  2547. a_RightSiblingBlockOffSet = 0 ;
  2548. }
  2549. else
  2550. {
  2551. a_PositionBlockOffSet = t_BlockOffSet ;
  2552. a_LeftSiblingBlockOffSet = 0 ;
  2553. CopyMemory (
  2554. ( BYTE * ) & a_RightSiblingBlockOffSet ,
  2555. ( ( BYTE * ) ( a_ParentNode ) ) + t_BlockOffSet + t_InternalKeySize + WmiBlockKeyPointerOffSet ,
  2556. sizeof ( WmiAbsoluteBlockOffSet )
  2557. ) ;
  2558. }
  2559. return t_StatusCode ;
  2560. }
  2561. t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ;
  2562. }
  2563. t_StatusCode = e_StatusCode_NotFound ;
  2564. return t_StatusCode ;
  2565. }
  2566. /******************************************************************************
  2567. *
  2568. * Name:
  2569. *
  2570. *
  2571. * Description:
  2572. *
  2573. *
  2574. *****************************************************************************/
  2575. WmiStatusCode WmiBPlusTree :: DeleteReBalance (
  2576. WmiBPKeyNode *a_ParentNode ,
  2577. WmiAbsoluteBlockOffSet &a_ParentBlockOffSet ,
  2578. WmiBPKeyNode *a_Node ,
  2579. WmiAbsoluteBlockOffSet &a_BlockOffSet
  2580. )
  2581. {
  2582. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  2583. WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
  2584. ULONG t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ;
  2585. WmiRelativeBlockOffSet t_PositionBlockOffSet ;
  2586. WmiAbsoluteBlockOffSet t_LeftSiblingBlockOffSet ;
  2587. WmiAbsoluteBlockOffSet t_RightSiblingBlockOffSet ;
  2588. t_StatusCode = LocateSuitableSibling (
  2589. a_ParentNode ,
  2590. a_ParentBlockOffSet ,
  2591. a_Node ,
  2592. a_BlockOffSet ,
  2593. t_PositionBlockOffSet ,
  2594. t_LeftSiblingBlockOffSet ,
  2595. t_RightSiblingBlockOffSet
  2596. ) ;
  2597. if ( t_StatusCode == e_StatusCode_Success )
  2598. {
  2599. BYTE *t_Block = NULL ;
  2600. if ( t_LeftSiblingBlockOffSet )
  2601. {
  2602. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_LeftSiblingBlockOffSet , t_Block ) ;
  2603. }
  2604. else
  2605. {
  2606. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_RightSiblingBlockOffSet , t_Block ) ;
  2607. }
  2608. if ( t_StatusCode == e_StatusCode_Success )
  2609. {
  2610. WmiBPKeyNode *t_SiblingNode = ( WmiBPKeyNode * ) t_Block ;
  2611. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  2612. ULONG t_Balance = t_Leaf ? MaxLeafKeys () : MaxKeys () ;
  2613. if ( t_SiblingNode->GetNodeSize () > ( t_Balance >> 1 ) )
  2614. {
  2615. /*
  2616. * Steal a key
  2617. */
  2618. t_StatusCode = StealSiblingNode (
  2619. a_ParentNode ,
  2620. a_ParentBlockOffSet ,
  2621. a_Node ,
  2622. a_BlockOffSet ,
  2623. t_PositionBlockOffSet ,
  2624. t_SiblingNode ,
  2625. t_LeftSiblingBlockOffSet ? t_LeftSiblingBlockOffSet : t_RightSiblingBlockOffSet ,
  2626. t_LeftSiblingBlockOffSet ,
  2627. t_RightSiblingBlockOffSet
  2628. ) ;
  2629. }
  2630. else
  2631. {
  2632. /*
  2633. * Merge sibling nodes
  2634. */
  2635. t_StatusCode = MergeSiblingNode (
  2636. a_ParentNode ,
  2637. a_ParentBlockOffSet ,
  2638. a_Node ,
  2639. a_BlockOffSet ,
  2640. t_PositionBlockOffSet ,
  2641. t_SiblingNode ,
  2642. t_LeftSiblingBlockOffSet ? t_LeftSiblingBlockOffSet : t_RightSiblingBlockOffSet ,
  2643. t_LeftSiblingBlockOffSet ,
  2644. t_RightSiblingBlockOffSet
  2645. ) ;
  2646. }
  2647. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  2648. }
  2649. }
  2650. return t_StatusCode ;
  2651. }
  2652. /******************************************************************************
  2653. *
  2654. * Name:
  2655. *
  2656. *
  2657. * Description:
  2658. *
  2659. *
  2660. *****************************************************************************/
  2661. WmiStatusCode WmiBPlusTree :: RecursiveDeleteFixup (
  2662. WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack ,
  2663. WmiBPKeyNode *a_RootNode ,
  2664. WmiAbsoluteBlockOffSet &a_RootBlockOffSet ,
  2665. WmiBPKeyNode *a_Node ,
  2666. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  2667. WmiRelativeBlockOffSet &a_PositionBlockOffSet
  2668. )
  2669. {
  2670. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  2671. WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
  2672. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  2673. ULONG t_KeyOffSet ;
  2674. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  2675. if ( t_Leaf )
  2676. {
  2677. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  2678. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  2679. }
  2680. else
  2681. {
  2682. t_KeyOffSet = WmiBlockKeyOffSet ;
  2683. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  2684. }
  2685. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  2686. if ( t_Leaf )
  2687. {
  2688. if ( a_RootBlockOffSet == a_BlockOffSet )
  2689. {
  2690. /*
  2691. * Shuffle memory to remove deleted fixup node
  2692. */
  2693. WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize ;
  2694. WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet - t_InternalKeySize ;
  2695. MoveMemory (
  2696. ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet ,
  2697. ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet + t_InternalKeySize ,
  2698. ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_InternalKeySize )
  2699. ) ;
  2700. }
  2701. else
  2702. {
  2703. /*
  2704. * Copy node up to place we deleted from.
  2705. */
  2706. #ifdef DELETE_DEBUG
  2707. PrintNode ( L"\nCopy Down a_RootNode" , a_RootNode , a_RootBlockOffSet ) ;
  2708. PrintNode ( L"\na_Node" , a_Node , a_BlockOffSet ) ;
  2709. #endif
  2710. BYTE *t_FromBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + WmiBlockLeafKeyOffSet ;
  2711. BYTE *t_ToBuffer = ( ( BYTE * ) a_RootNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
  2712. CopyMemory (
  2713. t_ToBuffer ,
  2714. t_FromBuffer ,
  2715. GetKeyTypeLength () ,
  2716. ) ;
  2717. t_FromBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + WmiBlockLeafKeyElementOffSet ;
  2718. t_ToBuffer = ( ( BYTE * ) a_RootNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
  2719. CopyMemory (
  2720. t_ToBuffer ,
  2721. t_FromBuffer ,
  2722. sizeof ( WmiBPElement )
  2723. ) ;
  2724. /*
  2725. * Shuffle memory to remove deleted fixup node
  2726. */
  2727. WmiRelativeBlockOffSet t_TotalSize = a_Node->GetNodeSize () * t_InternalKeySize - t_InternalKeySize ;
  2728. MoveMemory (
  2729. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet ,
  2730. ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_InternalKeySize ,
  2731. ( ULONG ) t_TotalSize + ( t_Leaf ? 0 : t_InternalKeySize )
  2732. ) ;
  2733. }
  2734. a_Node->SetNodeSize ( a_Node->GetNodeSize () - 1 ) ;
  2735. #ifdef DELETE_DEBUG
  2736. PrintNode ( L"\na_Node" , a_Node , a_BlockOffSet ) ;
  2737. #endif
  2738. t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
  2739. if ( t_StatusCode == e_StatusCode_Success )
  2740. {
  2741. /*
  2742. * Finally re balance as required
  2743. */
  2744. WmiBPKeyNode *t_Node = a_Node ;
  2745. WmiAbsoluteBlockOffSet t_BlockOffSet = a_BlockOffSet ;
  2746. m_BlockAllocator.AddRefBlock ( ( BYTE * ) & a_Node ) ;
  2747. do
  2748. {
  2749. BOOL t_ReBalance ;
  2750. if ( t_Leaf )
  2751. {
  2752. t_ReBalance = t_Node->GetNodeSize () < ( MaxLeafKeys () >> 1 ) ? TRUE : FALSE ;
  2753. }
  2754. else
  2755. {
  2756. t_ReBalance = t_Node->GetNodeSize () < ( MaxKeys () >> 1 ) ? TRUE : FALSE ;
  2757. }
  2758. if ( t_ReBalance )
  2759. {
  2760. WmiAbsoluteBlockOffSet t_ParentOffSet = 0 ;
  2761. WmiStatusCode t_TempStatusCode = a_Stack.Top ( t_ParentOffSet ) ;
  2762. if ( t_TempStatusCode == e_StatusCode_Success )
  2763. {
  2764. m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
  2765. BYTE *t_Block = NULL ;
  2766. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ParentOffSet , t_Block ) ;
  2767. if ( t_StatusCode == e_StatusCode_Success )
  2768. {
  2769. WmiBPKeyNode *t_ParentNode = ( WmiBPKeyNode * ) t_Block ;
  2770. t_StatusCode = DeleteReBalance (
  2771. t_ParentNode ,
  2772. t_ParentOffSet ,
  2773. t_Node ,
  2774. t_BlockOffSet
  2775. ) ;
  2776. t_Node = t_ParentNode ;
  2777. t_BlockOffSet = t_ParentOffSet ;
  2778. t_Leaf = ( ( t_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  2779. }
  2780. a_Stack.Pop () ;
  2781. }
  2782. else
  2783. {
  2784. if ( t_Leaf )
  2785. {
  2786. if ( t_Node->GetNodeSize () == 0 )
  2787. {
  2788. if ( t_BlockOffSet == GetRoot () )
  2789. {
  2790. SetRoot ( 0 ) ;
  2791. }
  2792. m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
  2793. m_BlockAllocator.FreeBlock (
  2794. 1 ,
  2795. t_BlockOffSet
  2796. ) ;
  2797. }
  2798. else
  2799. {
  2800. m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
  2801. }
  2802. }
  2803. else
  2804. {
  2805. if ( t_Node->GetNodeSize () == 0 )
  2806. {
  2807. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  2808. CopyMemory (
  2809. ( BYTE * ) & t_ChildOffSet ,
  2810. ( ( BYTE * ) ( t_Node ) ) + t_StartBlockOffSet + WmiBlockKeyPointerOffSet ,
  2811. sizeof ( WmiAbsoluteBlockOffSet )
  2812. ) ;
  2813. SetRoot ( t_ChildOffSet ) ;
  2814. m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
  2815. m_BlockAllocator.FreeBlock (
  2816. 1 ,
  2817. t_BlockOffSet
  2818. ) ;
  2819. }
  2820. else
  2821. {
  2822. m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
  2823. }
  2824. }
  2825. return t_StatusCode ;
  2826. }
  2827. }
  2828. else
  2829. {
  2830. m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
  2831. return t_StatusCode ;
  2832. }
  2833. } while ( t_StatusCode == e_StatusCode_Success ) ;
  2834. }
  2835. }
  2836. else
  2837. {
  2838. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  2839. CopyMemory (
  2840. ( BYTE * ) & t_ChildOffSet ,
  2841. ( ( BYTE * ) ( a_Node ) ) + t_StartBlockOffSet + WmiBlockKeyPointerOffSet ,
  2842. sizeof ( WmiAbsoluteBlockOffSet )
  2843. ) ;
  2844. BYTE *t_Block = NULL ;
  2845. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ;
  2846. if ( t_StatusCode == e_StatusCode_Success )
  2847. {
  2848. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  2849. t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ;
  2850. if ( t_StatusCode == e_StatusCode_Success )
  2851. {
  2852. RecursiveDeleteFixup (
  2853. a_Stack ,
  2854. a_RootNode ,
  2855. a_RootBlockOffSet ,
  2856. t_Node ,
  2857. t_ChildOffSet ,
  2858. a_PositionBlockOffSet
  2859. ) ;
  2860. }
  2861. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  2862. }
  2863. }
  2864. return t_StatusCode ;
  2865. }
  2866. /******************************************************************************
  2867. *
  2868. * Name:
  2869. *
  2870. *
  2871. * Description:
  2872. *
  2873. *
  2874. *****************************************************************************/
  2875. WmiStatusCode WmiBPlusTree :: DeleteFixup (
  2876. WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack ,
  2877. WmiBPKeyNode *a_Node ,
  2878. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  2879. WmiRelativeBlockOffSet &a_PositionBlockOffSet
  2880. )
  2881. {
  2882. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  2883. WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
  2884. ULONG t_InternalKeySize = GetKeyTypeLength () ;
  2885. ULONG t_KeyOffSet ;
  2886. BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  2887. if ( t_Leaf )
  2888. {
  2889. t_KeyOffSet = WmiBlockLeafKeyOffSet ;
  2890. t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ;
  2891. }
  2892. else
  2893. {
  2894. t_KeyOffSet = WmiBlockKeyOffSet ;
  2895. t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ;
  2896. }
  2897. ULONG t_NodeSize = a_Node->GetNodeSize () ;
  2898. if ( t_Leaf )
  2899. {
  2900. t_StatusCode = RecursiveDeleteFixup (
  2901. a_Stack ,
  2902. a_Node ,
  2903. a_BlockOffSet ,
  2904. a_Node ,
  2905. a_BlockOffSet ,
  2906. a_PositionBlockOffSet
  2907. ) ;
  2908. }
  2909. else
  2910. {
  2911. /*
  2912. * Move right one and descend left most to get next key.
  2913. */
  2914. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  2915. CopyMemory (
  2916. ( BYTE * ) & t_ChildOffSet ,
  2917. ( ( BYTE * ) ( a_Node ) ) + a_PositionBlockOffSet + t_InternalKeySize + WmiBlockKeyPointerOffSet ,
  2918. sizeof ( WmiAbsoluteBlockOffSet )
  2919. ) ;
  2920. BYTE *t_Block = NULL ;
  2921. t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ;
  2922. if ( t_StatusCode == e_StatusCode_Success )
  2923. {
  2924. WmiBPKeyNode *t_ChildNode = ( WmiBPKeyNode * ) t_Block ;
  2925. t_StatusCode = RecursiveDeleteFixup (
  2926. a_Stack ,
  2927. a_Node ,
  2928. a_BlockOffSet ,
  2929. t_ChildNode ,
  2930. t_ChildOffSet ,
  2931. a_PositionBlockOffSet
  2932. ) ;
  2933. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  2934. }
  2935. }
  2936. return t_StatusCode ;
  2937. }
  2938. /******************************************************************************
  2939. *
  2940. * Name:
  2941. *
  2942. *
  2943. * Description:
  2944. *
  2945. *
  2946. *****************************************************************************/
  2947. WmiStatusCode WmiBPlusTree :: RecursiveDelete (
  2948. WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack ,
  2949. WmiAbsoluteBlockOffSet &a_BlockOffSet ,
  2950. const WmiBPKey &a_Key ,
  2951. WmiBPElement &a_Element
  2952. )
  2953. {
  2954. WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
  2955. WmiBPElement t_Element = 0 ;
  2956. BYTE *t_Block = NULL ;
  2957. WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , a_BlockOffSet , t_Block ) ;
  2958. if ( t_StatusCode == e_StatusCode_Success )
  2959. {
  2960. WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
  2961. WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
  2962. ULONG t_NodeIndex = 0 ;
  2963. t_StatusCode = FindInBlock (
  2964. t_Node ,
  2965. a_BlockOffSet ,
  2966. a_Key ,
  2967. t_ChildOffSet ,
  2968. t_Element ,
  2969. t_NodeOffSet ,
  2970. t_NodeIndex
  2971. ) ;
  2972. if ( t_StatusCode == e_StatusCode_Success )
  2973. {
  2974. if ( t_Element )
  2975. {
  2976. BOOL t_Leaf = ( ( t_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ;
  2977. if ( t_Leaf == FALSE )
  2978. {
  2979. t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ;
  2980. }
  2981. if ( t_StatusCode == e_StatusCode_Success )
  2982. {
  2983. t_StatusCode = DeleteFixup (
  2984. a_Stack ,
  2985. t_Node ,
  2986. a_BlockOffSet ,
  2987. t_NodeOffSet
  2988. ) ;
  2989. }
  2990. }
  2991. else
  2992. {
  2993. t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ;
  2994. if ( t_StatusCode == e_StatusCode_Success )
  2995. {
  2996. t_StatusCode = RecursiveDelete (
  2997. a_Stack ,
  2998. t_ChildOffSet ,
  2999. a_Key ,
  3000. a_Element
  3001. ) ;
  3002. }
  3003. }
  3004. }
  3005. else
  3006. {
  3007. t_StatusCode = e_StatusCode_NotFound ;
  3008. }
  3009. m_BlockAllocator.ReleaseBlock ( t_Block ) ;
  3010. }
  3011. return t_StatusCode ;
  3012. }
  3013. /******************************************************************************
  3014. *
  3015. * Name:
  3016. *
  3017. *
  3018. * Description:
  3019. *
  3020. *
  3021. *****************************************************************************/
  3022. WmiStatusCode WmiBPlusTree :: Delete (
  3023. const WmiBPKey &a_Key ,
  3024. WmiBPElement &a_Element
  3025. )
  3026. {
  3027. #ifdef DELETE_DEBUG
  3028. OutputDebugString ( L"\n/**************************************" ) ;
  3029. wchar_t t_StringBuffer [ 1024 ] ;
  3030. swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) a_Key.GetConstData () ) ;
  3031. OutputDebugString ( t_StringBuffer ) ;
  3032. OutputDebugString ( L"\n======================================" ) ;
  3033. #endif
  3034. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  3035. if ( m_Root )
  3036. {
  3037. WmiStack <WmiAbsoluteBlockOffSet,8> t_Stack ( m_Allocator ) ;
  3038. t_StatusCode = t_Stack.Initialize () ;
  3039. if ( t_StatusCode == e_StatusCode_Success )
  3040. {
  3041. t_StatusCode = RecursiveDelete (
  3042. t_Stack ,
  3043. m_Root ,
  3044. a_Key ,
  3045. a_Element
  3046. ) ;
  3047. }
  3048. }
  3049. else
  3050. {
  3051. t_StatusCode = e_StatusCode_NotFound ;
  3052. }
  3053. if ( t_StatusCode == e_StatusCode_Success )
  3054. {
  3055. m_Size -- ;
  3056. }
  3057. #ifdef DELETE_DEBUG
  3058. OutputDebugString ( L"\n**************************************\\" ) ;
  3059. #endif
  3060. return t_StatusCode ;
  3061. }
  3062. #endif _BPLUSTREE_CPP