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.

406 lines
9.9 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: seglist.hxx
  7. //
  8. // Contents: List of CTableSegment objects.
  9. //
  10. // Classes: CTableSegList
  11. //
  12. // Functions:
  13. //
  14. // History: 1-15-95 srikants Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #pragma once
  18. #include <tableseg.hxx>
  19. #include <segmru.hxx>
  20. #include <sglookup.hxx>
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Class: CTableSegList
  24. //
  25. // Purpose: A List of CTableSegments
  26. //
  27. // History: 1-16-95 srikants Created
  28. //
  29. // Notes:
  30. //
  31. //----------------------------------------------------------------------------
  32. class CTableSegList : public CDoubleList
  33. {
  34. friend class CSegListMgr;
  35. friend class CFwdTableSegIter;
  36. friend class CBackTableSegIter;
  37. public:
  38. CTableSegList() : _cWindows(0), _cBuckets(0){}
  39. ~CTableSegList();
  40. CTableSegment* GetTop() { return (CTableSegment *) _Top(); }
  41. unsigned GetWindowsCount() const { return _cWindows; }
  42. unsigned GetBucketsCount() const { return _cBuckets; }
  43. unsigned GetSegmentsCount() const { return _cWindows + _cBuckets; }
  44. CTableSegment * GetFirst()
  45. {
  46. return !IsEmpty() ? (CTableSegment *) _root.Next() : 0;
  47. }
  48. CTableSegment * GetLast()
  49. {
  50. return !IsEmpty() ? (CTableSegment *) _root.Prev() : 0;
  51. }
  52. CTableSegment * GetNext( CTableSegment * pNode )
  53. {
  54. Win4Assert( 0 != pNode );
  55. if ( !IsLast( *pNode ) )
  56. {
  57. return (CTableSegment *) pNode->Next();
  58. }
  59. else
  60. {
  61. return 0;
  62. }
  63. }
  64. CTableSegment * GetPrev( CTableSegment * pNode )
  65. {
  66. Win4Assert( 0 != pNode );
  67. if ( !IsFirst( *pNode ) )
  68. {
  69. return (CTableSegment *) pNode->Prev();
  70. }
  71. else
  72. {
  73. return 0;
  74. }
  75. }
  76. void Push ( CTableSegment * pTableSeg )
  77. {
  78. Win4Assert( 0 != pTableSeg );
  79. _Push ( pTableSeg );
  80. _IncrementCount( *pTableSeg );
  81. }
  82. void Queue( CTableSegment * pTableSeg )
  83. {
  84. Win4Assert( 0 != pTableSeg );
  85. _Queue ( pTableSeg );
  86. _IncrementCount( *pTableSeg );
  87. }
  88. void InsertAfter ( CTableSegment * pBefore, CTableSegment * pNew );
  89. void InsertBefore( CTableSegment * pAfter, CTableSegment * pNew );
  90. CTableSegment * RemoveTop();
  91. void RemoveFromList( CTableSegment * pNode );
  92. CTableSegment * Replace( CDoubleIter &it, CTableSegment * pNew );
  93. #ifdef CIEXTMODE
  94. void CiExtDump(void *ciExtSelf);
  95. #endif
  96. private:
  97. unsigned _cWindows; // Count of windows
  98. unsigned _cBuckets; // Count of buckets
  99. BOOL _IsNodeInList( CTableSegment * pNode );
  100. void _IncrementCount( const CTableSegment & node );
  101. void _DecrementCount( const CTableSegment & node );
  102. CDoubleLink & _GetRoot()
  103. {
  104. return _root;
  105. }
  106. };
  107. //+---------------------------------------------------------------------------
  108. //
  109. // Class: CDoubleTableSegIter
  110. //
  111. // Purpose: Iterator over a table segment list.
  112. //
  113. // History: 25-Jul-95 BartoszM Created.
  114. //
  115. //----------------------------------------------------------------------------
  116. class CDoubleTableSegIter : public CDoubleList::CDoubleIter
  117. {
  118. public:
  119. CDoubleTableSegIter ( CDoubleLink* pSeg ) : CDoubleIter(pSeg) {}
  120. CDoubleTableSegIter ( CDoubleTableSegIter& iter ) : CDoubleIter(iter) {}
  121. CTableSegment* operator->() { return (CTableSegment*) _pLinkCur; }
  122. CTableSegment* GetSegment() { return (CTableSegment*) _pLinkCur; }
  123. CTableWindow * GetWindow();
  124. CTableBucket * GetBucket();
  125. };
  126. //+---------------------------------------------------------------------------
  127. //
  128. // Class: CFwdTableSegIter
  129. //
  130. // Purpose: Iterator over a table segment list.
  131. //
  132. // History: 15-Jan-95 SrikantS Created.
  133. //
  134. //----------------------------------------------------------------------------
  135. class CTableWindow;
  136. class CTableBucket;
  137. class CFwdTableSegIter : public CDoubleTableSegIter
  138. {
  139. public:
  140. CFwdTableSegIter ( CTableSegList& list )
  141. : CDoubleTableSegIter(list._GetRoot().Next()) {}
  142. // copy constructor
  143. CFwdTableSegIter ( CFwdTableSegIter& iter) : CDoubleTableSegIter(iter) {}
  144. };
  145. //+---------------------------------------------------------------------------
  146. //
  147. // Class: CBackTableSegIter
  148. //
  149. // Purpose: Iterator over a table segment list.
  150. //
  151. // History: 15-Jan-95 SrikantS Created.
  152. //
  153. //----------------------------------------------------------------------------
  154. class CBackTableSegIter : public CDoubleTableSegIter
  155. {
  156. public:
  157. CBackTableSegIter ( CTableSegList& list )
  158. : CDoubleTableSegIter(list._GetRoot().Prev()) {}
  159. };
  160. inline BOOL IsSpecialWid( WORKID wid )
  161. {
  162. Win4Assert( WORKID_TBLBEFOREFIRST == ((WORKID) 0xfffffffb) );
  163. Win4Assert( WORKID_TBLFIRST == ((WORKID) 0xfffffffc) );
  164. Win4Assert( WORKID_TBLLAST == ((WORKID) 0xfffffffd) );
  165. Win4Assert( WORKID_TBLAFTERLAST == ((WORKID) 0xfffffffe) );
  166. return wid >= WORKID_TBLBEFOREFIRST &&
  167. wid <= WORKID_TBLAFTERLAST;
  168. }
  169. //+---------------------------------------------------------------------------
  170. //
  171. // Class: CSegListMgr
  172. //
  173. // Purpose: Manages list of segments and caching of segments that are
  174. // in use by the query or client threads.
  175. //
  176. // History: 4-11-95 srikants Created
  177. //
  178. // Notes: All operations that modify the physical structure of the
  179. // segment list MUST go through this object.
  180. //
  181. //----------------------------------------------------------------------------
  182. class CSegListMgr
  183. {
  184. public:
  185. CSegListMgr( unsigned nSegsToCache )
  186. : _pCachedPutRowSeg(0) , _clientSegs(nSegsToCache),
  187. _bucketSegs(ULONG_MAX)
  188. {
  189. }
  190. ~CSegListMgr();
  191. void Push ( CTableSegment * pTableSeg )
  192. {
  193. _list.Push( pTableSeg );
  194. _lookupArray.InsertBefore( 0, pTableSeg );
  195. }
  196. void InsertAfter ( CTableSegment * pBefore, CTableSegment * pNew )
  197. {
  198. _list.InsertAfter( pBefore, pNew );
  199. _lookupArray.InsertAfter( pBefore, pNew );
  200. _lookupArray.TestInSync( _list );
  201. }
  202. void InsertBefore( CTableSegment * pAfter, CTableSegment * pNew )
  203. {
  204. _list.InsertBefore( pAfter, pNew );
  205. _lookupArray.InsertBefore( pAfter, pNew );
  206. _lookupArray.TestInSync( _list );
  207. }
  208. CTableSegment * RemoveTop()
  209. {
  210. CTableSegment * pFirst = _list.RemoveTop();
  211. _InvalidateIfCached( pFirst );
  212. _lookupArray.RemoveEntry( pFirst );
  213. _lookupArray.TestInSync( _list );
  214. return pFirst;
  215. }
  216. void RemoveFromList( CTableSegment * pNode )
  217. {
  218. _list.RemoveFromList( pNode );
  219. _InvalidateIfCached( pNode );
  220. _lookupArray.RemoveEntry( pNode );
  221. _lookupArray.TestInSync( _list );
  222. }
  223. //
  224. // Replaces the node in the iterator with the new node in the iterator
  225. // as well as the list.
  226. //
  227. CTableSegment * Replace( CDoubleList::CDoubleIter & iter, CTableSegment * pNew )
  228. {
  229. Win4Assert( 0 != pNew );
  230. Win4Assert( !_list.AtEnd( iter ) );
  231. CTableSegment * pCurrent = _list.Replace(iter, pNew);
  232. _InvalidateIfCached( pCurrent );
  233. _lookupArray.Replace( pCurrent, pNew );
  234. _lookupArray.TestInSync( _list );
  235. return pCurrent;
  236. }
  237. CTableSegment * Replace( CTableSegment * pOld, CTableSegList & list );
  238. //
  239. // Methods that operate on the cached segment pointers.
  240. //
  241. void SetCachedPutRowSeg( CTableSegment * pSeg )
  242. {
  243. _pCachedPutRowSeg = pSeg;
  244. }
  245. CTableSegment * GetCachedPutRowSeg()
  246. {
  247. return _pCachedPutRowSeg;
  248. }
  249. void SetInUseByClient( WORKID wid, CTableSegment * pSeg )
  250. {
  251. if ( widInvalid != wid &&
  252. !IsSpecialWid(wid) )
  253. {
  254. _clientSegs.AddReplace( wid, pSeg );
  255. }
  256. }
  257. void UpdateSegsInUse( CTableSegment * pSeg );
  258. BOOL IsInUseByClient( CTableSegment * pSeg )
  259. {
  260. return _clientSegs.IsSegmentInUse( pSeg );
  261. }
  262. BOOL IsRecentlyUsed( CTableSegment * pSeg )
  263. {
  264. if ( pSeg == _pCachedPutRowSeg ||
  265. _clientSegs.IsSegmentInUse( pSeg ) )
  266. {
  267. return TRUE;
  268. }
  269. else if ( !_bucketSegs.IsEmpty() &&
  270. _bucketSegs.IsSegmentInUse( pSeg ) )
  271. {
  272. return TRUE;
  273. }
  274. return FALSE;
  275. }
  276. void SetInUseByBuckets( WORKID wid )
  277. {
  278. if ( widInvalid != wid &&
  279. !IsSpecialWid(wid) )
  280. {
  281. _bucketSegs.AddReplace( wid, 0 );
  282. }
  283. }
  284. void ClearInUseByBuckets( WORKID wid )
  285. {
  286. if ( widInvalid != wid &&
  287. !IsSpecialWid(wid) )
  288. {
  289. _bucketSegs.Remove( wid );
  290. }
  291. }
  292. CTableSegList & GetList()
  293. {
  294. return _list;
  295. }
  296. CSegmentArray & GetSegmentArray() { return _lookupArray; }
  297. #ifdef CIEXTMODE
  298. void CiExtDump(void *ciExtSelf);
  299. #endif
  300. private:
  301. CTableSegment * _pCachedPutRowSeg;
  302. // Last segment into which a row was
  303. // added.
  304. CTableSegList _list; // List of table segments
  305. CSegmentArray _lookupArray;
  306. // Array used to to quick lookups on
  307. // key
  308. CMRUSegments _clientSegs;// List of segments most recently used
  309. // by the client.
  310. CMRUSegments _bucketSegs;// List of segments that are currently
  311. // being converted to windows and so
  312. // should be pinned as windows.
  313. void _InvalidateIfCached( const CTableSegment * const pSeg );
  314. void _UpdateSegsInUse( CWidSegMapList & list , CTableSegment * pSeg );
  315. };