Leaked source code of windows server 2003
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.

411 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: seglist.cxx
  7. //
  8. // Contents: List of CTableSegment objects
  9. //
  10. // Classes: CTableSegList
  11. //
  12. // History: 1-15-95 srikants Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.cxx"
  16. #pragma hdrstop
  17. #include <seglist.hxx>
  18. #include "tblwindo.hxx"
  19. #include "tblbuket.hxx"
  20. CTableSegList::~CTableSegList()
  21. {
  22. for ( CTableSegment * pSegment = RemoveTop();
  23. 0 != pSegment;
  24. pSegment = RemoveTop() )
  25. {
  26. delete pSegment;
  27. }
  28. }
  29. //+---------------------------------------------------------------------------
  30. //
  31. // Function: RemoveTop
  32. //
  33. // Synopsis: Removes the top most element from the list and returns it.
  34. //
  35. // Returns: A pointer to the top most element from the list.
  36. //
  37. // History: 1-16-95 srikants Created
  38. //
  39. // Notes:
  40. //
  41. //----------------------------------------------------------------------------
  42. CTableSegment * CTableSegList::RemoveTop()
  43. {
  44. // tbDebugOut (( DEB_ITRACE, "TableSegList::RemoveTop\n" ));
  45. CTableSegment* pSegment = (CTableSegment*) _Pop();
  46. if ( pSegment )
  47. _DecrementCount( *pSegment );
  48. return pSegment;
  49. }
  50. //+---------------------------------------------------------------------------
  51. //
  52. // Function: RemoveFromList
  53. //
  54. // Synopsis: Removes the indicated node from the list.
  55. //
  56. // Arguments: [pNodeToRemove] -
  57. //
  58. // History: 1-16-95 srikants Created
  59. //
  60. // Notes:
  61. //
  62. //----------------------------------------------------------------------------
  63. void CTableSegList::RemoveFromList( CTableSegment * pNodeToRemove )
  64. {
  65. Win4Assert( _IsNodeInList( pNodeToRemove ) &&
  66. "CTableSegList::pNodeToRemove not is list" );
  67. pNodeToRemove->Unlink();
  68. _DecrementCount( *pNodeToRemove );
  69. }
  70. //+---------------------------------------------------------------------------
  71. //
  72. // Function: InsertAfter
  73. //
  74. // Synopsis: Inserts "pNew" node after "pBefore" node.
  75. //
  76. // Arguments: [pBefore] - The node already in list.
  77. // [pNew] - The new node to be inserted.
  78. //
  79. // History: 1-16-95 srikants Created
  80. //
  81. // Notes:
  82. //
  83. //----------------------------------------------------------------------------
  84. void CTableSegList::InsertAfter( CTableSegment * pBefore, CTableSegment * pNew )
  85. {
  86. Win4Assert( 0 != pBefore && 0 != pNew );
  87. pNew->InsertAfter( pBefore );
  88. _IncrementCount( *pNew );
  89. }
  90. //+---------------------------------------------------------------------------
  91. //
  92. // Function: InsertBefore
  93. //
  94. // Synopsis: Inserts "pNew" node before "pAfter" node.
  95. //
  96. // Arguments: [pAfter] - The node already in the list.
  97. // [pNew] - The new node to be inserted.
  98. //
  99. // History: 1-16-95 srikants Created
  100. //
  101. // Notes:
  102. //
  103. //----------------------------------------------------------------------------
  104. void CTableSegList::InsertBefore( CTableSegment * pAfter, CTableSegment * pNew )
  105. {
  106. Win4Assert( 0 != pAfter && 0 != pNew );
  107. pNew->InsertBefore( pAfter );
  108. _IncrementCount( *pNew );
  109. }
  110. //+---------------------------------------------------------------------------
  111. //
  112. // Function: Replace
  113. //
  114. // Synopsis: Replaces the current entry in the iterator with the new
  115. // entry. It also replaces it in the list.
  116. //
  117. // Arguments: [it] - Iterator
  118. // [pNew] - The new entry that replaces the entry in the
  119. // iterator.
  120. //
  121. // Returns: The old segment that was replaced in the list.
  122. //
  123. // History: 4-10-95 srikants Created
  124. //
  125. // Notes:
  126. //
  127. //----------------------------------------------------------------------------
  128. CTableSegment* CTableSegList::Replace( CDoubleIter & it, CTableSegment * pNew )
  129. {
  130. Win4Assert( 0 != pNew );
  131. CTableSegment * pCurr = (CTableSegment *) _Replace( it, pNew );
  132. _DecrementCount( *pCurr );
  133. _IncrementCount( *pNew );
  134. return pCurr;
  135. }
  136. //+---------------------------------------------------------------------------
  137. //
  138. // Function: _IncrementCount
  139. //
  140. // Synopsis: Increments the appropriate count depending upon the type of the
  141. // segment (node)
  142. //
  143. // Arguments: [node] -
  144. //
  145. // History: 1-16-95 srikants Created
  146. //
  147. // Notes:
  148. //
  149. //----------------------------------------------------------------------------
  150. void CTableSegList::_IncrementCount( const CTableSegment & node )
  151. {
  152. switch( node.GetSegmentType() )
  153. {
  154. case CTableSegment::eWindow :
  155. _cWindows++;
  156. break;
  157. case CTableSegment::eBucket :
  158. _cBuckets++;
  159. break;
  160. };
  161. }
  162. //+---------------------------------------------------------------------------
  163. //
  164. // Function: _DecrementCount
  165. //
  166. // Synopsis: Decrements the count of the given node type.
  167. //
  168. // Arguments: [node] -
  169. //
  170. // History: 1-16-95 srikants Created
  171. //
  172. // Notes:
  173. //
  174. //----------------------------------------------------------------------------
  175. void CTableSegList::_DecrementCount( const CTableSegment & node )
  176. {
  177. switch( node.GetSegmentType() )
  178. {
  179. case CTableSegment::eWindow :
  180. Win4Assert( _cWindows > 0 );
  181. _cWindows--;
  182. break;
  183. case CTableSegment::eBucket :
  184. Win4Assert( _cBuckets > 0 );
  185. _cBuckets--;
  186. break;
  187. };
  188. }
  189. //+---------------------------------------------------------------------------
  190. //
  191. // Function: _IsNodeInList
  192. //
  193. // Synopsis: Determines if a given node is in the list.
  194. //
  195. // Arguments: [pNode] - Node whose existence in the list is being tested.
  196. //
  197. // Returns: TRUE if found; FALSE o/w
  198. //
  199. // History: 1-16-95 srikants Created
  200. //
  201. // Notes:
  202. //
  203. //----------------------------------------------------------------------------
  204. BOOL CTableSegList::_IsNodeInList( CTableSegment * pNode )
  205. {
  206. for ( CFwdTableSegIter iter(*this); !AtEnd(iter); Advance(iter) )
  207. {
  208. if ( iter.GetSegment() == pNode )
  209. {
  210. return TRUE;
  211. }
  212. }
  213. return FALSE;
  214. }
  215. CTableWindow * CDoubleTableSegIter::GetWindow()
  216. {
  217. Win4Assert( GetSegment()->GetSegmentType() == CTableSegment::eWindow );
  218. return (CTableWindow *) _pLinkCur;
  219. }
  220. CTableBucket * CDoubleTableSegIter::GetBucket()
  221. {
  222. Win4Assert( GetSegment()->GetSegmentType() == CTableSegment::eBucket );
  223. return (CTableBucket *) _pLinkCur;
  224. }
  225. //+---------------------------------------------------------------------------
  226. //
  227. // Function: ~CSegListMgr
  228. //
  229. // Synopsis: Destroys all the segments in the list.
  230. //
  231. // History: 4-11-95 srikants Created
  232. //
  233. // Notes:
  234. //
  235. //----------------------------------------------------------------------------
  236. CSegListMgr::~CSegListMgr()
  237. {
  238. for ( CTableSegment * pSegment = _list.RemoveTop();
  239. 0 != pSegment;
  240. pSegment = _list.RemoveTop() )
  241. {
  242. delete pSegment;
  243. }
  244. }
  245. //+---------------------------------------------------------------------------
  246. //
  247. // Function: _InvalidateIfCached
  248. //
  249. // Synopsis: If the given segment's pointer is cached, invalidate it.
  250. //
  251. // Arguments: [pSeg] - The segment which is going to go away and so must
  252. // be invalidated.
  253. //
  254. // History: 4-11-95 srikants Created
  255. //
  256. // Notes:
  257. //
  258. //----------------------------------------------------------------------------
  259. void CSegListMgr::_InvalidateIfCached( const CTableSegment * const pSeg )
  260. {
  261. Win4Assert( 0 != pSeg );
  262. if ( _pCachedPutRowSeg == pSeg )
  263. {
  264. _pCachedPutRowSeg = 0;
  265. }
  266. _clientSegs.Invalidate( pSeg );
  267. _bucketSegs.Invalidate( pSeg );
  268. }
  269. //+---------------------------------------------------------------------------
  270. //
  271. // Function: _UpdateSegsInUse
  272. //
  273. // Synopsis: Updates the wid->Segment mapping for wids that are cached.
  274. // For such wids, if they are present in the new segment, the
  275. // mapping is updated.
  276. //
  277. // Arguments: [list] - The list to update in.
  278. // [pSeg] - Pointer to the segment which is the new segment
  279. //
  280. // History: 5-30-95 srikants Created
  281. //
  282. // Notes: Helper function for UpdateSegsInUse()
  283. //
  284. //----------------------------------------------------------------------------
  285. void CSegListMgr::_UpdateSegsInUse( CWidSegMapList & list,
  286. CTableSegment * pSeg )
  287. {
  288. for ( CFwdWidSegMapIter iter(list); !list.AtEnd(iter);
  289. list.Advance(iter) )
  290. {
  291. WORKID wid = iter->GetWorkId();
  292. if ( widInvalid != wid &&
  293. pSeg->IsRowInSegment( wid ) )
  294. {
  295. Win4Assert( 0 == iter->GetSegment() );
  296. iter->Set( pSeg );
  297. }
  298. }
  299. }
  300. //+---------------------------------------------------------------------------
  301. //
  302. // Function: UpdateSegsInUse
  303. //
  304. // Synopsis: Updates the wid->Segment mapping for wids that are cached.
  305. // For such wids, if they are present in the new segment, the
  306. // mapping is updated.
  307. //
  308. // Arguments: [pSeg] - Pointer to a new segment that is coming into
  309. // existence.
  310. //
  311. // History: 4-11-95 srikants Created
  312. //
  313. // Notes:
  314. //
  315. //----------------------------------------------------------------------------
  316. void CSegListMgr::UpdateSegsInUse( CTableSegment * pSeg )
  317. {
  318. Win4Assert( 0 != pSeg );
  319. CWidSegMapList & clientList = _clientSegs.GetList();
  320. _UpdateSegsInUse( clientList, pSeg );
  321. if ( !_bucketSegs.IsEmpty() )
  322. {
  323. CWidSegMapList & bktList = _bucketSegs.GetList();
  324. _UpdateSegsInUse( bktList, pSeg );
  325. }
  326. }
  327. //+---------------------------------------------------------------------------
  328. //
  329. // Member: CSegListMgr::Replace
  330. //
  331. // Synopsis: Replaces the given segment in the _list with the new segments
  332. // passed in the list.
  333. //
  334. // Arguments: [pSeg] - The segment to replace
  335. // [list] - The new list of segments.
  336. //
  337. // History: 10-20-95 srikants Created
  338. //
  339. // Notes:
  340. //
  341. //----------------------------------------------------------------------------
  342. CTableSegment * CSegListMgr::Replace( CTableSegment * pSeg, CTableSegList & list )
  343. {
  344. _lookupArray.Replace( pSeg, list );
  345. CTableSegment * pCurr = pSeg;
  346. CTableSegment * pFirst = list.RemoveTop();
  347. while ( 0 != pFirst )
  348. {
  349. _list.InsertAfter( pCurr, pFirst );
  350. pCurr = pFirst;
  351. pFirst = list.RemoveTop();
  352. }
  353. _list.RemoveFromList( pSeg );
  354. _InvalidateIfCached( pSeg );
  355. _lookupArray.TestInSync( _list );
  356. return pSeg;
  357. }