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.

273 lines
8.0 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 2000.
  5. //
  6. // File: QOptimiz.hxx
  7. //
  8. // Contents: Query optimizer. Chooses indexes and table implementations.
  9. //
  10. // Classes: CQueryOptimizer
  11. //
  12. // History: 21-Jun-95 KyleP Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <coldesc.hxx>
  17. #include <xpr.hxx>
  18. #include <cqueue.hxx>
  19. #include <strategy.hxx>
  20. #include <qiterate.hxx>
  21. #include <rstprop.hxx>
  22. #include <timlimit.hxx>
  23. #include <ciintf.h>
  24. #include <frmutils.hxx>
  25. class CPidRemapper;
  26. DECLARE_SMARTP( Columns );
  27. DECLARE_SMARTP( Sort );
  28. class CGenericCursor;
  29. class CSingletonCursor;
  30. const MAX_HITS_FOR_FAST_SORT_BY_RANK_OPT = 2000; // Internal cutoff on # results for
  31. // sorted-by-rank optimization
  32. //+---------------------------------------------------------------------------
  33. //
  34. // Class: CQueryOptimizer
  35. //
  36. // Purpose: Chooses indexes and table strategies.
  37. //
  38. // History: 21-Jun-95 KyleP Created.
  39. //
  40. //----------------------------------------------------------------------------
  41. class CQueryOptimizer
  42. {
  43. public:
  44. CQueryOptimizer( XInterface<ICiCQuerySession>& xQuerySession,
  45. ICiCDocStore *pDocStore,
  46. XRestriction & rst,
  47. CColumnSet const & cols,
  48. CSortSet const * psort,
  49. CPidRemapper const & pidmap,
  50. CRowsetProperties const & rProps,
  51. DWORD dwQueryStatus
  52. );
  53. ~CQueryOptimizer();
  54. //
  55. // Table choices.
  56. //
  57. inline BOOL IsMultiCursor() const;
  58. inline BOOL IsFullySorted() const;
  59. inline BOOL IsPositionable() const;
  60. //
  61. // Cursor retrieval
  62. //
  63. inline BOOL RequiresCI() const;
  64. inline void GetCurrentComponentIndex( unsigned & iCurrent,
  65. unsigned & cTotal ) const;
  66. inline BOOL CQueryOptimizer::IsWorkidUnique()
  67. {
  68. //
  69. // If we have a null catalog, we do not have wids in a
  70. // persistent store. So we have to return FALSE here to cause
  71. // the bigtable to associate wids with the matching docs and
  72. // use them wherever wids are needed.
  73. //
  74. return !_fNullCatalog;
  75. }
  76. CGenericCursor * QueryNextCursor( ULONG & status, BOOL& fAbort );
  77. CSingletonCursor * QuerySingletonCursor( BOOL& fAbort );
  78. CTimeLimit & GetTimeLimit();
  79. //
  80. // Singleton support
  81. //
  82. inline void EnableSingletonCursors();
  83. # ifdef CIEXTMODE
  84. void CiExtDump(void *ciExtSelf);
  85. # endif
  86. ULONG MaxResults() const { return _cMaxResults; }
  87. ULONG FirstRows() const { return _cFirstRows; }
  88. BOOL FetchDeferredValue( WORKID wid,
  89. CFullPropSpec const & ps,
  90. PROPVARIANT & var );
  91. BOOL CanPartialDefer()
  92. {
  93. // We cannot partial defer if:
  94. // We have a null catalog OR
  95. // enumOption == CI_ENUM_MUST_NEVER_DEFER
  96. if ( _fNullCatalog )
  97. {
  98. return FALSE;
  99. }
  100. CI_ENUM_OPTIONS enumOption;
  101. SCODE sc = _xQuerySession->GetEnumOption( &enumOption );
  102. if ( FAILED( sc ) )
  103. {
  104. vqDebugOut(( DEB_ERROR, "CanPartialDefer - GetEnumOption returned 0x%x\n", sc ));
  105. return FALSE;
  106. }
  107. return ( enumOption != CI_ENUM_MUST_NEVER_DEFER );
  108. }
  109. private:
  110. //
  111. // Validation
  112. //
  113. BOOL Validate();
  114. //
  115. // Query optimization
  116. //
  117. void ChooseIndexStrategy( CSortSet const * psort, CColumnSet const & cols );
  118. CGenericCursor * ApplyIndexStrategy( ULONG & status, BOOL& fAbort );
  119. ACCESS_MASK _AccessMask() const;
  120. BOOL _fMulti; // TRUE if query requires > 1 cursor.
  121. BOOL _fAtEnd; // TRUE if out of cursors.
  122. BOOL _fFullySorted; // TRUE if current component will iterate
  123. // in sorted order.
  124. DWORD _dwQueryStatus; // The original status
  125. XInterface<ICiCQuerySession> _xQuerySession; // Query session object
  126. XInterface<ICiCDeferredPropRetriever> _xDefPropRetriever; // Deferred property retriever
  127. XInterface<ICiManager> _xCiManager; // Content index
  128. CCiFrameworkParams _frameworkParams; // Admin parameters
  129. BOOL _fSortedByRankOpt; // TRUE if can use CSortedByRankCursor
  130. BOOL _fRankVectorProp; // TRUE if rank vector is in the output column
  131. ULONG _cMaxResults; // Limit on # query results
  132. ULONG _cFirstRows; // only sort and return the first _cFristRows rows
  133. # if CIDBG == 1
  134. XRestriction _xrstOriginal; // For debugging only.
  135. # endif
  136. CPidRemapper const & _pidmap; // VPID/PID/PROPSPEC translations
  137. CTimeLimit _TimeLimit; // execution time limit (must precede _xXpr)
  138. XXpr _xXpr; // Expression (test against object)
  139. XRestriction _xFullyResolvableRst; // Content query
  140. // _TimeLimit must be before _qRstIterator
  141. CQueryRstIterator _qRstIterator; // Iterator over various components of OR query
  142. XColumnSet _xcols; // Used for multi-part queries.
  143. XSortSet _xsort; // Used for multi-part queries.
  144. //
  145. // Singleton support.
  146. //
  147. BOOL _fNeedSingleton; // TRUE if QuerySingletonCursor may be called.
  148. XXpr _xxprSingleton; // Copy of current expression for singleton.
  149. //
  150. // Content queries
  151. //
  152. BOOL _fUseCI; // If TRUE, always use CI value index for property queries.
  153. BOOL _fDeferTrimming; // If TRUE, sorted rank cursor will trim results *after* full fetch from CI
  154. BOOL _fCIRequiredGlobal; // Does the any component of query require a CI ?
  155. BOOL _fCIRequired; // Does the current component of OR query require a CI ?
  156. ACCESS_MASK _am;
  157. CMutexSem _mtxSem; // To serialize when creating deferred prop retriever
  158. BOOL _fNullCatalog; // Do we have a null catalog?
  159. };
  160. inline BOOL CQueryOptimizer::IsMultiCursor() const
  161. {
  162. return _fMulti;
  163. }
  164. inline BOOL CQueryOptimizer::IsFullySorted() const
  165. {
  166. return _fFullySorted || _fSortedByRankOpt;
  167. }
  168. inline BOOL CQueryOptimizer::IsPositionable() const
  169. {
  170. return FALSE;
  171. }
  172. inline void CQueryOptimizer::EnableSingletonCursors()
  173. {
  174. _fNeedSingleton = TRUE;
  175. }
  176. inline BOOL CQueryOptimizer::RequiresCI() const
  177. {
  178. return _fCIRequiredGlobal || _fUseCI;
  179. }
  180. inline void CQueryOptimizer::GetCurrentComponentIndex( unsigned & iCurrent,
  181. unsigned & cTotal ) const
  182. {
  183. _qRstIterator.GetCurComponentIndex( iCurrent, cTotal );
  184. //
  185. // If we're not done, then there is a component waiting inside CQueryOptimizer.
  186. //
  187. if ( !_fAtEnd )
  188. {
  189. Win4Assert( iCurrent >= 2 );
  190. iCurrent--;
  191. }
  192. }
  193. //+-------------------------------------------------------------------------
  194. //
  195. // Member: CQueryOptimizer::_AccessMask, private
  196. //
  197. // Returns: Access mask appropriate given properties in query
  198. //
  199. // History: 23-Oct-95 dlee Created
  200. //
  201. //--------------------------------------------------------------------------
  202. inline ACCESS_MASK CQueryOptimizer::_AccessMask() const
  203. {
  204. return _am;
  205. }
  206. inline CTimeLimit & CQueryOptimizer::GetTimeLimit()
  207. {
  208. return _TimeLimit;
  209. }
  210. DECLARE_SMARTP( QueryOptimizer )