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.

493 lines
9.6 KiB

  1. #ifndef __KEYEDARRAY_CPP
  2. #define __KEYEDARRAY_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 <KeyedArray.h>
  26. #endif
  27. /******************************************************************************
  28. *
  29. * Name:
  30. *
  31. *
  32. * Description:
  33. *
  34. *
  35. *****************************************************************************/
  36. template <class WmiKey,class WmiElement,ULONG GrowSize>
  37. WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: WmiKeyedArray <WmiKey,WmiElement,GrowSize> (
  38. WmiAllocator &a_Allocator
  39. ) : m_Allocator ( a_Allocator ) ,
  40. m_Size ( 0 ) ,
  41. m_AllocatedSize ( 0 ) ,
  42. m_Block ( NULL )
  43. {
  44. }
  45. /******************************************************************************
  46. *
  47. * Name:
  48. *
  49. *
  50. * Description:
  51. *
  52. *
  53. *****************************************************************************/
  54. template <class WmiKey,class WmiElement,ULONG GrowSize>
  55. WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: ~WmiKeyedArray <WmiKey,WmiElement,GrowSize> ()
  56. {
  57. WmiStatusCode t_StatusCode = UnInitialize () ;
  58. }
  59. /******************************************************************************
  60. *
  61. * Name:
  62. *
  63. *
  64. * Description:
  65. *
  66. *
  67. *****************************************************************************/
  68. template <class WmiKey,class WmiElement,ULONG GrowSize>
  69. WmiStatusCode WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: Initialize ()
  70. {
  71. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  72. return t_StatusCode ;
  73. }
  74. /******************************************************************************
  75. *
  76. * Name:
  77. *
  78. *
  79. * Description:
  80. *
  81. *
  82. *****************************************************************************/
  83. template <class WmiKey,class WmiElement,ULONG GrowSize>
  84. WmiStatusCode WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: UnInitialize ()
  85. {
  86. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  87. if ( m_Block )
  88. {
  89. for ( ULONG t_Index = 0 ; t_Index < m_Size ; t_Index ++ )
  90. {
  91. WmiArrayNode *t_Node = & m_Block [ t_Index ] ;
  92. t_Node->~WmiArrayNode () ;
  93. }
  94. WmiStatusCode t_StatusCode = m_Allocator.Delete (
  95. ( void * ) m_Block
  96. ) ;
  97. }
  98. return t_StatusCode ;
  99. }
  100. /******************************************************************************
  101. *
  102. * Name:
  103. *
  104. *
  105. * Description:
  106. *
  107. *
  108. *****************************************************************************/
  109. template <class WmiKey,class WmiElement,ULONG GrowSize>
  110. WmiStatusCode WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: Insert (
  111. const WmiKey &a_Key ,
  112. const WmiElement &a_Element ,
  113. Iterator &a_Iterator
  114. )
  115. {
  116. ULONG t_LowerIndex = 0 ;
  117. ULONG t_UpperIndex = m_Size ;
  118. while ( t_LowerIndex < t_UpperIndex )
  119. {
  120. ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
  121. #if 0
  122. LONG t_Compare = CompareElement ( a_Key , m_Block [ t_Index ].m_Key ) ;
  123. if ( t_Compare == 0 )
  124. #else
  125. if ( a_Key == m_Block [ t_Index ].m_Key )
  126. #endif
  127. {
  128. return e_StatusCode_AlreadyExists ;
  129. }
  130. else
  131. {
  132. #if 0
  133. if ( t_Compare < 0 )
  134. #else
  135. if ( a_Key < m_Block [ t_Index ].m_Key )
  136. #endif
  137. {
  138. t_UpperIndex = t_Index ;
  139. }
  140. else
  141. {
  142. t_LowerIndex = t_Index + 1 ;
  143. }
  144. }
  145. }
  146. WmiStatusCode t_StatusCode ;
  147. WmiArrayNode *t_Block ;
  148. if ( m_Block )
  149. {
  150. if ( m_Size == m_AllocatedSize )
  151. {
  152. t_StatusCode = m_Allocator.ReAlloc (
  153. ( void ** ) m_Block ,
  154. ( void ** ) &t_Block ,
  155. ( m_Size + GrowSize ) * sizeof ( WmiArrayNode )
  156. ) ;
  157. if ( t_StatusCode == e_StatusCode_Success )
  158. {
  159. m_Block = t_Block ;
  160. MoveMemory ( & m_Block [ t_LowerIndex + 1 ] , & m_Block [ t_LowerIndex ] , ( m_Size - t_LowerIndex ) * sizeof ( WmiArrayNode ) ) ;
  161. WmiArrayNode *t_Node = & m_Block [ t_LowerIndex ] ;
  162. :: new ( ( void* ) t_Node ) WmiArrayNode () ;
  163. t_Node->m_Element = a_Element ;
  164. t_Node->m_Key = a_Key ;
  165. a_Iterator = Iterator ( this , t_LowerIndex ) ;
  166. m_Size ++ ;
  167. m_AllocatedSize = m_AllocatedSize + GrowSize ;
  168. }
  169. return t_StatusCode ;
  170. }
  171. else
  172. {
  173. MoveMemory ( & m_Block [ t_LowerIndex + 1 ] , & m_Block [ t_LowerIndex ] , ( m_Size - t_LowerIndex ) * sizeof ( WmiArrayNode ) ) ;
  174. WmiArrayNode *t_Node = & m_Block [ t_LowerIndex ] ;
  175. :: new ( ( void* ) t_Node ) WmiArrayNode () ;
  176. t_Node->m_Element = a_Element ;
  177. t_Node->m_Key = a_Key ;
  178. a_Iterator = Iterator ( this , t_LowerIndex ) ;
  179. m_Size ++ ;
  180. return e_StatusCode_Success ;
  181. }
  182. }
  183. else
  184. {
  185. t_StatusCode = m_Allocator.New (
  186. ( void ** ) & t_Block ,
  187. GrowSize * sizeof ( WmiArrayNode )
  188. ) ;
  189. if ( t_StatusCode == e_StatusCode_Success )
  190. {
  191. m_Block = t_Block ;
  192. WmiArrayNode *t_Node = & m_Block [ 0 ] ;
  193. :: new ( ( void* ) t_Node ) WmiArrayNode () ;
  194. t_Node->m_Element = a_Element ;
  195. t_Node->m_Key = a_Key ;
  196. a_Iterator = Iterator ( this , t_LowerIndex ) ;
  197. m_Size ++ ;
  198. m_AllocatedSize = m_AllocatedSize + GrowSize ;
  199. }
  200. return t_StatusCode ;
  201. }
  202. }
  203. /******************************************************************************
  204. *
  205. * Name:
  206. *
  207. *
  208. * Description:
  209. *
  210. *
  211. *****************************************************************************/
  212. template <class WmiKey,class WmiElement,ULONG GrowSize>
  213. WmiStatusCode WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: Delete (
  214. const WmiKey &a_Key
  215. )
  216. {
  217. if ( m_Block )
  218. {
  219. ULONG t_LowerIndex = 0 ;
  220. ULONG t_UpperIndex = m_Size ;
  221. while ( t_LowerIndex < t_UpperIndex )
  222. {
  223. ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
  224. #if 0
  225. LONG t_Compare = CompareElement ( a_Key , m_Block [ t_Index ].m_Key ) ;
  226. if ( t_Compare == 0 )
  227. #else
  228. if ( a_Key == m_Block [ t_Index ].m_Key )
  229. #endif
  230. {
  231. MoveMemory ( & m_Block [ t_Index ] , & m_Block [ t_Index + 1 ] , ( m_Size - 1 - t_Index ) * sizeof ( WmiArrayNode ) ) ;
  232. if ( m_Size == m_AllocatedSize - GrowSize )
  233. {
  234. WmiStatusCode t_StatusCode ;
  235. WmiArrayNode *t_Block ;
  236. t_StatusCode = m_Allocator.ReAlloc (
  237. ( void ** ) m_Block ,
  238. ( void ** ) &t_Block ,
  239. ( m_Size - 1 ) * sizeof ( WmiArrayNode )
  240. ) ;
  241. if ( t_StatusCode == e_StatusCode_Success )
  242. {
  243. m_Block = t_Block ;
  244. m_Size -- ;
  245. m_AllocatedSize = m_AllocatedSize - GrowSize ;
  246. return t_StatusCode ;
  247. }
  248. }
  249. else
  250. {
  251. m_Size -- ;
  252. return e_StatusCode_Success ;
  253. }
  254. }
  255. else
  256. {
  257. #if 0
  258. if ( t_Compare < 0 )
  259. #else
  260. if ( a_Key < m_Block [ t_Index ].m_Key )
  261. #endif
  262. {
  263. t_UpperIndex = t_Index ;
  264. }
  265. else
  266. {
  267. t_LowerIndex = t_Index + 1 ;
  268. }
  269. }
  270. }
  271. }
  272. return e_StatusCode_NotFound ;
  273. }
  274. /******************************************************************************
  275. *
  276. * Name:
  277. *
  278. *
  279. * Description:
  280. *
  281. *
  282. *****************************************************************************/
  283. template <class WmiKey,class WmiElement,ULONG GrowSize>
  284. WmiStatusCode WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: Find (
  285. const WmiKey &a_Key ,
  286. Iterator &a_Iterator
  287. )
  288. {
  289. ULONG t_LowerIndex = 0 ;
  290. ULONG t_UpperIndex = m_Size ;
  291. while ( t_LowerIndex < t_UpperIndex )
  292. {
  293. ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
  294. #if 0
  295. LONG t_Compare = CompareElement ( a_Key , m_Block [ t_Index ].m_Key ) ;
  296. if ( t_Compare == 0 )
  297. #else
  298. if ( a_Key == m_Block [ t_Index ].m_Key )
  299. #endif
  300. {
  301. a_Iterator = Iterator ( this , t_Index ) ;
  302. return e_StatusCode_Success ;
  303. }
  304. else
  305. {
  306. #if 0
  307. if ( t_Compare < 0 )
  308. #else
  309. if ( a_Key < m_Block [ t_Index ].m_Key )
  310. #endif
  311. {
  312. t_UpperIndex = t_Index ;
  313. }
  314. else
  315. {
  316. t_LowerIndex = t_Index + 1 ;
  317. }
  318. }
  319. }
  320. return e_StatusCode_NotFound ;
  321. }
  322. /******************************************************************************
  323. *
  324. * Name:
  325. *
  326. *
  327. * Description:
  328. *
  329. *
  330. *****************************************************************************/
  331. template <class WmiKey,class WmiElement,ULONG GrowSize>
  332. WmiStatusCode WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: FindNext (
  333. const WmiKey &a_Key ,
  334. Iterator &a_Iterator
  335. )
  336. {
  337. if ( m_Size )
  338. {
  339. ULONG t_LowerIndex = 0 ;
  340. ULONG t_UpperIndex = m_Size ;
  341. while ( t_LowerIndex < t_UpperIndex )
  342. {
  343. ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
  344. #if 0
  345. LONG t_Compare = CompareElement ( a_Key , m_Block [ t_Index ].m_Key ) ;
  346. if ( t_Compare == 0 )
  347. #else
  348. if ( a_Key == m_Block [ t_Index ].m_Key )
  349. #endif
  350. {
  351. a_Iterator = Iterator ( this , t_Index ).Increment () ;
  352. return e_StatusCode_Success ;
  353. }
  354. else
  355. {
  356. #if 0
  357. if ( t_Compare < 0 )
  358. #else
  359. if ( a_Key < m_Block [ t_Index ].m_Key )
  360. #endif
  361. {
  362. t_UpperIndex = t_Index ;
  363. }
  364. else
  365. {
  366. t_LowerIndex = t_Index + 1 ;
  367. }
  368. }
  369. }
  370. a_Iterator = Iterator ( this , t_Lower ).Increment () ;
  371. return e_StatusCode_Success ;
  372. }
  373. else
  374. {
  375. return e_StatusCode_NotFound ;
  376. }
  377. }
  378. /******************************************************************************
  379. *
  380. * Name:
  381. *
  382. *
  383. * Description:
  384. *
  385. *
  386. *****************************************************************************/
  387. template <class WmiKey,class WmiElement,ULONG GrowSize>
  388. WmiStatusCode WmiKeyedArray <WmiKey,WmiElement,GrowSize> :: Merge (
  389. WmiKeyedArray <WmiKey,WmiElement,GrowSize> &a_Tree
  390. )
  391. {
  392. #if 0
  393. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  394. Iterator t_Iterator = a_Tree.Root ();
  395. while ( ! t_Iterator.Null () )
  396. {
  397. Iterator t_InsertIterator ;
  398. WmiStatusCode t_StatusCode = Insert ( t_Iterator.GetKey () , t_Iterator.GetElement () , t_InsertIterator ) ;
  399. if ( t_StatusCode )
  400. {
  401. t_StatusCode = a_Tree.Delete ( t_Iterator.GetKey () ) ;
  402. }
  403. t_Iterator = a_Tree.Root () ;
  404. }
  405. return t_StatusCode ;
  406. #else
  407. return e_StatusCode_NotFound ;
  408. #endif
  409. }
  410. #endif __KEYEDARRAY_CPP