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.

433 lines
13 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 2000.
  5. //
  6. // File: BigTable.hxx
  7. //
  8. // Contents: Data structures for large tables.
  9. //
  10. // Classes: CLargeTable
  11. // CTableSegment
  12. //
  13. // History: 12 Jan 1994 Alanw Created
  14. //
  15. //--------------------------------------------------------------------------
  16. #pragma once
  17. #include <tableseg.hxx>
  18. #include <seglist.hxx>
  19. #include <segmru.hxx>
  20. #include <shardbuf.hxx>
  21. #include <abktize.hxx>
  22. #include <wregion.hxx>
  23. class CInlineVariant;
  24. class CBucketizeWindows;
  25. class CRequestServer;
  26. // We need to continue to use this error since it's in the on-the-wire
  27. // protocol. It doesn't end up going out to a user however.
  28. #ifndef DB_S_BLOCKLIMITEDROWS
  29. #define DB_S_BLOCKLIMITEDROWS DB_S_DIALECTIGNORED
  30. #endif // DB_S_BLOCKLIMITEDROWS
  31. const LONGLONG eSigLargeTable = 0x454C424154474942i64; // "BIGTABLE"
  32. //+-------------------------------------------------------------------------
  33. //
  34. // Class: CLargeTable
  35. //
  36. // Purpose: In-memory object table. Composed of a set of table
  37. // segments.
  38. //
  39. // Interface: CTableSegment
  40. // CTableSegMgr
  41. //
  42. //--------------------------------------------------------------------------
  43. class CLargeTable : public CTableSource, public CTableSink
  44. {
  45. friend class CTableRowPutter;
  46. friend class CTableRowGetter;
  47. friend class CTableRowLocator;
  48. friend class CAsyncBucketExploder;
  49. //
  50. // Maximum number of entries that are in use by client to be cached.
  51. // Segments that have these entries will be pinned as windows.
  52. //
  53. enum { cMaxClientEntriesToPin = 4 };
  54. //
  55. // Maximum number of windows before we start bucketizing them
  56. //
  57. enum { cMaxWindows = 5 };
  58. //
  59. // Minimum rows in a window for it to be bucketized.
  60. //
  61. enum { cMinRowsToBucketize = CTableSink::cBucketRowLimit * 80 / 100 };
  62. public:
  63. CLargeTable( XColumnSet & col,
  64. XSortSet & sort,
  65. unsigned cCategorizers,
  66. CMutexSem &_mutex,
  67. BOOL fUniqueWorkid,
  68. CRequestServer * pQuiesce );
  69. virtual ~CLargeTable();
  70. // Virtual methods inherited from CTableSink
  71. WORKID PathToWorkID( CRetriever& obj,
  72. CTableSink::ERowType eRowType );
  73. BOOL WorkIdToPath( WORKID wid, CInlineVariant & pathVarnt,
  74. ULONG & cbVarnt );
  75. BOOL PutRow( CRetriever & obj, CTableSink::ERowType eRowType );
  76. void RemoveRow( PROPVARIANT const & varUnique );
  77. CSortSet const & SortOrder();
  78. void ProgressDone (ULONG ulDenominator, ULONG ulNumerator);
  79. void Quiesce ();
  80. void QueryAbort();
  81. // Virtual methods inherited from CTableSource
  82. DBCOUNTITEM RowCount();
  83. SCODE GetRows( HWATCHREGION hRegion,
  84. WORKID widStart,
  85. CI_TBL_CHAPT chapt,
  86. CTableColumnSet const & rOutColumns,
  87. CGetRowsParams& rGetParams,
  88. WORKID& rwidNextRowToTransfer );
  89. void RestartPosition ( CI_TBL_CHAPT chapt );
  90. void LokGetOneColumn( WORKID wid,
  91. CTableColumn const & rOutColumn,
  92. BYTE * pbOut,
  93. PVarAllocator & rVarAllocator );
  94. SCODE GetRowsAt(
  95. HWATCHREGION hRegion,
  96. WORKID widStart,
  97. CI_TBL_CHAPT chapt,
  98. DBROWOFFSET iRowOffset,
  99. CTableColumnSet const & rOutColumns,
  100. CGetRowsParams & rGetParams,
  101. WORKID & rwidLastRowTransferred );
  102. SCODE GetRowsAtRatio(
  103. HWATCHREGION hRegion,
  104. ULONG num,
  105. ULONG denom,
  106. CI_TBL_CHAPT chapt,
  107. CTableColumnSet const & rOutColumns,
  108. CGetRowsParams & rGetParams,
  109. WORKID & rwidLastRowTransferred );
  110. BOOL IsRowInSegment( WORKID wid );
  111. SCODE GetNotifications(CNotificationParams &Params);
  112. WORKID GetCurrentPosition( CI_TBL_CHAPT chapt );
  113. WORKID SetCurrentPosition( CI_TBL_CHAPT chapt, WORKID wid );
  114. //
  115. // Methods supporting CTableCursor actions
  116. //
  117. SCODE GetApproximatePosition(
  118. CI_TBL_CHAPT chapt,
  119. CI_TBL_BMK bmk,
  120. DBCOUNTITEM * pulNumerator,
  121. DBCOUNTITEM * pulDenominator
  122. );
  123. BOOL IsColumnInTable( PROPID PropId );
  124. SCODE GetNotifications(
  125. CNotificationSync &Sync,
  126. DBWATCHNOTIFY &changeType);
  127. void CancelAsyncNotification();
  128. void LokCompleteAsyncNotification ();
  129. BOOL IsEmptyForQuery()
  130. {
  131. return _segList.IsEmpty();
  132. }
  133. //
  134. // Internal
  135. //
  136. // Watch Regions
  137. void CreateWatchRegion (ULONG mode, HWATCHREGION* phRegion);
  138. void ChangeWatchMode ( HWATCHREGION hRegion, ULONG mode);
  139. void GetWatchRegionInfo ( HWATCHREGION hRegion,
  140. CI_TBL_CHAPT* pChapter,
  141. CI_TBL_BMK* pBookmark,
  142. DBROWCOUNT* pcRows);
  143. void DeleteWatchRegion (HWATCHREGION hRegion);
  144. void ShrinkWatchRegion (HWATCHREGION hRegion,
  145. CI_TBL_CHAPT chapter,
  146. CI_TBL_BMK bookmark,
  147. LONG cRows );
  148. void Refresh ();
  149. void RatioFinished (DBCOUNTITEM& ulDenominator,
  150. DBCOUNTITEM& ulNumerator,
  151. DBCOUNTITEM& cRows );
  152. void SetQueryExecute( CQAsyncExecute * pQExecute ); // virtual
  153. void ReleaseQueryExecute();
  154. CMutexSem & GetMutex()
  155. {
  156. return _mutex;
  157. }
  158. ULONG _AllocSegId()
  159. {
  160. ULONG id = _nextSegId;
  161. _nextSegId++;
  162. return id;
  163. }
  164. #ifdef CIEXTMODE
  165. void CiExtDump(void *ciExtSelf);
  166. #endif
  167. CSortSet const * GetSortSet() const { return _pSortSet; }
  168. BOOL IsSorted() const { return 0 != _pSortSet; }
  169. private:
  170. void _LokCheckQueryStatus( );
  171. DBCOUNTITEM _LokRowCount();
  172. CSortSet * _CheckAndAddWidToSortSet( XSortSet & sort );
  173. void _LokRemoveCategorizedRow( CI_TBL_CHAPT chapt,
  174. WORKID wid,
  175. WORKID widNext,
  176. CTableSegment * pSegment );
  177. //
  178. // Methods to locate a row in the table.
  179. //
  180. CTableSegment * _LokFindTableSegment(
  181. WORKID wid
  182. );
  183. WORKID _LokLocateTableSegment(
  184. CDoubleTableSegIter & rIter,
  185. CI_TBL_CHAPT chapt,
  186. WORKID wid
  187. );
  188. CTableSegment * _LokSplitWindow( CTableWindow ** ppWindow,
  189. ULONG iSplitQuery );
  190. CTableWindow * _LokGetClosestWindow( ULONG cRowsFromFront,
  191. CLinearRange & winRange );
  192. CI_TBL_BMK _FindNearestDynamicBmk( CTableWindow * pWindow,
  193. CI_TBL_CHAPT chapter,
  194. CI_TBL_BMK bookmark );
  195. //
  196. // Splitting windows and converting windows <-> buckets.
  197. //
  198. void _LokConvertToBucket( CTableWindow **ppWindow );
  199. void _LokConvertWindowsToBucket( WORKID widToPin = widInvalid );
  200. void _NoLokBucketToWindows( XPtr<CTableBucket> & xBucket,
  201. WORKID widToPin = widInvalid,
  202. BOOL isWatched = FALSE,
  203. BOOL fOptimizeBucketization = TRUE );
  204. void _NoLokBucketToWindows( CDynStack<CTableBucket> & xBktStack,
  205. WORKID widToPin = widInvalid,
  206. BOOL isWatched = TRUE,
  207. BOOL fOptimizeBucketization = TRUE );
  208. CTableBucket * _LokReplaceWithEmptyWindow( CDoubleTableSegIter & iter );
  209. //
  210. // Deferred notification processing.
  211. //
  212. BOOL _LokIsWatched() const
  213. {
  214. return _bitIsWatched;
  215. }
  216. void LokStretchWatchRegion ( CWatchRegion* pRegion,
  217. CDynStack<CTableBucket>& xBktToConvert);
  218. BOOL _LokIsPutRowDeferred( WORKID wid, CRetriever &obj );
  219. void _LokDeferPutRow( WORKID wid, CRetriever &obj );
  220. BOOL _LokRemoveIfDeferred( WORKID wid );
  221. static ULONG _Diff( ULONG num1, ULONG num2 )
  222. {
  223. return num1 >= num2 ? num1-num2 : num2-num1;
  224. }
  225. BOOL LokNeedToNotifyReset (DBWATCHNOTIFY& changeType);
  226. BOOL NeedToNotifyReset (DBWATCHNOTIFY& changeType);
  227. void _LokAddToExplodeList( CAsyncBucketExploder * pBktExploder );
  228. void _RemoveFromExplodeList( CAsyncBucketExploder * pBktExploder );
  229. BOOL LokNeedToNotify();
  230. BOOL NeedToNotify();
  231. //
  232. // Helper methods for CTablePutRow and CTableGetRows
  233. //
  234. CTableWindow * _CreateNewWindow( ULONG segId, CTableRowKey & lowKey,
  235. CTableRowKey & highKey);
  236. CSegListMgr & _GetSegListMgr() { return _segListMgr; }
  237. //-----------------------------------------------
  238. // This MUST be the first variable in this class.
  239. //-----------------------------------------------
  240. const LONGLONG _sigLargeTable;
  241. //
  242. // Global statistics on memory usage and targets for driving
  243. // paging heuristics.
  244. //
  245. ULONG _cbMemoryTarget; // Target for max. memory consumption
  246. ULONG _cbMemoryUsage; // Current memory consumption
  247. //
  248. // _MasterColumnSet gives the union of the currently bound columns,
  249. // and other columns which are stored in some table and potentially
  250. // bindable. Hidden and computed columns are included, as are
  251. // columns which appear in sort keys, but which are not bound output
  252. // columns.
  253. //
  254. // The master column set also includes the accumulated experience
  255. // for deciding on good column compressions.
  256. //
  257. CColumnMasterSet _MasterColumnSet;
  258. BOOL _fUniqueWorkid;
  259. //
  260. // Serialization.
  261. //
  262. CMutexSem &_mutex; // Serialize Table access
  263. //
  264. // List of all the segments that constitute this table and its
  265. // manager.
  266. //
  267. CSegListMgr _segListMgr;
  268. CTableSegList & _segList; // List of segments
  269. CWatchList _watchList; // List of watch regions (requires _segList)
  270. //
  271. // For allocating segment ids.
  272. //
  273. ULONG _nextSegId;
  274. //
  275. // _pCategory points to the categorizer one level up
  276. //
  277. CTableSegment * _pCategorization;
  278. unsigned _cCategorizersTotal;
  279. BOOL _fAbort; // Set to TRUE if an abort is in progress
  280. //
  281. // Sort specification
  282. //
  283. CSortSet *_pSortSet; // sort specification
  284. //
  285. // Members needed to determine where a particular row goes in.
  286. //
  287. XArray<VARTYPE> _vtInfoSortKey; // Variant type info for the sort cols
  288. XPtr<CTableKeyCompare> _keyCompare;
  289. XPtr<CTableRowKey> _currRow;
  290. //
  291. // Notifications
  292. //
  293. unsigned _bitNotifyEnabled:1; // Set to TRUE if notifications are
  294. // enabled.
  295. unsigned _bitChangeQuiesced:1; // have we toggled between un/quiesced?
  296. unsigned _bitQuiesced:1; // have we quiesced (as opposed to unquiesced)?
  297. unsigned _bitClientNotified:1; // client has been notified
  298. unsigned _bitRefresh:1; // need to refresh?
  299. unsigned _bitIsWatched:1; // Set to TRUE if the table is watched.
  300. //
  301. // Deferred notifications.
  302. //
  303. CTableBucket * _pDeferredRows; // Bucket containing the deferred
  304. // notification.
  305. HANDLE _hNotifyEvent; // Event on which notifications are triggered
  306. CRequestServer *_pRequestServer; // Used to signal notifications
  307. DBWATCHNOTIFY _changeType;
  308. // progress calculation
  309. BOOL _fProgressNeeded;
  310. BOOL _fQuiescent;
  311. ULONG _ulProgressDenom;
  312. ULONG _ulProgressNum;
  313. // Buffer used for all table segments during a putrow while the
  314. // bigtable is under lock.
  315. CSharedBuffer _sharedBuf;
  316. CQAsyncExecute * _pQExecute; // used for bucket->window conversion
  317. CAsyncBucketsList _explodeBktsList;
  318. // current position of GetNextRows for non-chaptered rowset
  319. WORKID _widCurrent;
  320. // is rankvector bound as a column?
  321. BOOL _fRankVectorBound;
  322. // may be 0 or an object that needs notification on quiesce
  323. CRequestServer *_pQuiesce;
  324. BOOL _fSortDefined;
  325. };