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.

352 lines
9.9 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1999.
  5. //
  6. // File: rowcomp.hxx
  7. //
  8. // Contents: Declaration of the row comparison classes
  9. //
  10. // Classes: CRowCompareVariant
  11. //
  12. // Templates: TRowCompare
  13. //
  14. // History: 31 Aug 1994 dlee Created
  15. //
  16. //--------------------------------------------------------------------------
  17. #pragma once
  18. #include <compare.hxx>
  19. #include <xbuffer.hxx>
  20. #include <shardbuf.hxx>
  21. #include <tblvarnt.hxx>
  22. #include "varntcmp.hxx"
  23. #include "pathstor.hxx"
  24. class CTableWindow;
  25. //+-------------------------------------------------------------------------
  26. //
  27. // Class: CRowCompare
  28. //
  29. // Purpose: Abstract class for row comparisons
  30. //
  31. // Notes: The comparison function should return (for ascending order)
  32. //
  33. // 1..cSortItems if Row1 > Row2,
  34. // 0 if same
  35. // -1..-cSortItems if Row1 < Row2
  36. //
  37. // Return the opposite for descending order.
  38. //
  39. // History: 8/24/94 dlee created
  40. //
  41. //--------------------------------------------------------------------------
  42. class CRowCompare
  43. {
  44. public:
  45. CRowCompare() {}
  46. virtual ~CRowCompare() {}
  47. virtual int Compare(TBL_OFF oRow1, TBL_OFF oRow2) = 0;
  48. };
  49. class CPathStore;
  50. //+-------------------------------------------------------------------------
  51. //
  52. // Class: CRowCompareVariant
  53. //
  54. // Purpose: Default case of row comparisons if a more optimal
  55. // special case is not used. Converts values to variants
  56. // and compares the variants. Also used if more than one
  57. // (not including WORKID) sort spec specified.
  58. //
  59. // Notes: This must be declared unwindable because it has embedded
  60. // unwindable objects.
  61. //
  62. //--------------------------------------------------------------------------
  63. class CRowCompareVariant : public CRowCompare
  64. {
  65. public:
  66. CRowCompareVariant(CTableWindow & TableWindow);
  67. virtual ~CRowCompareVariant();
  68. int Compare(TBL_OFF oRow1,
  69. TBL_OFF oRow2);
  70. int CompareObject(CRetriever & obj,
  71. TBL_OFF oRow2);
  72. enum EVariantSource { eNone, eCompressor, eBuffer, eNewx };
  73. private:
  74. void _FreeVariant(CTableColumn * pColumn,
  75. CTableVariant * pVar,
  76. EVariantSource eSource);
  77. void _MakeVariant(CTableColumn * pColumn,
  78. BYTE * pbRow,
  79. CTableVariant * pVar,
  80. EVariantSource & evSource);
  81. void _MakeVariant(CTableColumn * pColumn,
  82. CRetriever & obj,
  83. unsigned iProp);
  84. PROPVARIANT * _MakeVariant( unsigned iCol,
  85. XUseSharedBuffer & sharedBuf,
  86. CRetriever & obj );
  87. void _Cleanup1();
  88. void _Cleanup2();
  89. int _DoCompare(TBL_OFF oRow2);
  90. void _InitComparators( CSortSet const & sortSet );
  91. PATHID _GetPathId( const CTableColumn & col, BYTE * pbRow );
  92. BOOL _FastCompare( unsigned iCol, BYTE *pbRow1, BYTE * pbRow2,
  93. int & iComp );
  94. BOOL _FastCompare( unsigned iCol, CRetriever & obj,
  95. XUseSharedBuffer & sharedBuf,
  96. BYTE * pbRow2, int & iComp );
  97. unsigned _cProps;
  98. CTableWindow &_TableWindow;
  99. // Comparators for the columns
  100. XArray<CCompareVariants> _aComparator;
  101. // State data for the comparison.
  102. XArray<CTableVariant> _aVar1;
  103. XArray<CTableVariant> _aVar2;
  104. XArray<CTableVariant *> _apVar1;
  105. XArray<CTableVariant *> _apVar2;
  106. XArray<CTableColumn *> _apColumn;
  107. XArray<EVariantSource> _aVarFlags1;
  108. XArray<EVariantSource> _aVarFlags2;
  109. //
  110. // Used for quick path comparison.
  111. //
  112. CPathStore * _pPathStore;
  113. //
  114. // Temporary shared memory for the whole table.
  115. //
  116. CSharedBuffer & _sharedBuf;
  117. // Buffer used for CRetriever temporary data
  118. enum { maxcbBuffer = MAX_PATH * sizeof WCHAR };
  119. XBuffer<BYTE> _xBuffer;
  120. // Most recent row 1 identified by this member is cached
  121. WORKID _widCached;
  122. };
  123. //+-------------------------------------------------------------------------
  124. //
  125. // Template: TRowCompare
  126. //
  127. // Purpose: Special row comparator for inline values: values that are
  128. // stored in the row as opposed to variable-length or easily
  129. // compressed data that is stored out-of-line.
  130. //
  131. // Use of this template is just an optimization over using
  132. // CRowCompareVariant, in which data must be converted to a
  133. // variant before the comparison (which is slow).
  134. //
  135. // You can use this template if:
  136. // -- only one property is in the sort spec
  137. // -- the property value is stored inline
  138. // -- the property value datatype supports relational ops
  139. // -- length of the value is fixed and is not an array
  140. //
  141. //--------------------------------------------------------------------------
  142. template <class T> class TRowCompare : public CRowCompare
  143. {
  144. public:
  145. TRowCompare( CFixedVarTableWindowAllocator &Alloc,
  146. ULONG oData,
  147. ULONG dwOrder) :
  148. _Alloc( Alloc ),
  149. _oData( oData )
  150. {
  151. if (0 == (dwOrder & QUERY_SORTDESCEND /*DBSORTORDER_DESCEND*/ ))
  152. _iGT = 1; // ascending
  153. else
  154. _iGT = -1; // descending
  155. }
  156. ~TRowCompare() {}
  157. int Compare( TBL_OFF oRow1,
  158. TBL_OFF oRow2 )
  159. {
  160. T t1 = * (T *) ((BYTE *) _Alloc.FixedPointer( oRow1 ) + _oData);
  161. T t2 = * (T *) ((BYTE *) _Alloc.FixedPointer( oRow2 ) + _oData);
  162. if (t1 > t2)
  163. return _iGT;
  164. if (t1 < t2)
  165. return -_iGT;
  166. return 0;
  167. }
  168. private:
  169. int _iGT; // return value if 1 > 2
  170. CFixedVarTableWindowAllocator &_Alloc; // allocator where rows are
  171. ULONG _oData; // offset in row where value resides
  172. };
  173. //+-------------------------------------------------------------------------
  174. //
  175. // Template: TRowCompareTwo
  176. //
  177. // Purpose: Same as TRowCompare, except that it also does a second
  178. // compare. A is compared first, then B.
  179. //
  180. // Rules for use of this template are the same as for
  181. // TRowCompare
  182. //
  183. //--------------------------------------------------------------------------
  184. template <class TA, class TB> class TRowCompareTwo : public CRowCompare
  185. {
  186. public:
  187. TRowCompareTwo( CFixedVarTableWindowAllocator &Alloc,
  188. ULONG oDataA,
  189. ULONG dwOrderA,
  190. ULONG oDataB,
  191. ULONG dwOrderB ) :
  192. _CompareA( Alloc, oDataA, dwOrderA ),
  193. _CompareB( Alloc, oDataB, dwOrderB ) {}
  194. ~TRowCompareTwo() {}
  195. int Compare( TBL_OFF oRow1,
  196. TBL_OFF oRow2 )
  197. {
  198. int result = _CompareA.Compare( oRow1, oRow2 );
  199. if (0 == result)
  200. {
  201. // same first key -- now check the second key.
  202. // the * 2 means that it was the second column.
  203. result = 2 * _CompareB.Compare( oRow1, oRow2 );
  204. }
  205. return result;
  206. }
  207. private:
  208. TRowCompare<TA> _CompareA;
  209. TRowCompare<TB> _CompareB;
  210. };
  211. //+-------------------------------------------------------------------------
  212. //
  213. // Template: TRowCompareStringPlus
  214. //
  215. // Purpose: Same as TRowCompareTwo, except that the first key compared
  216. // is a wide string, then the parameterized type is compared.
  217. //
  218. //--------------------------------------------------------------------------
  219. template <class TB> class TRowCompareStringPlus : public CRowCompare
  220. {
  221. public:
  222. TRowCompareStringPlus( CFixedVarTableWindowAllocator &Alloc,
  223. ULONG oDataString,
  224. ULONG dwOrderString,
  225. ULONG oDataB,
  226. ULONG dwOrderB ) :
  227. _Alloc( Alloc ),
  228. _oDataString( oDataString ),
  229. _CompareB( Alloc, oDataB, dwOrderB )
  230. {
  231. if (0 == (dwOrderString & QUERY_SORTDESCEND /*DBSORTORDER_DESCEND*/ ))
  232. _iGTString = 1; // ascending
  233. else
  234. _iGTString = -1; // descending
  235. }
  236. ~TRowCompareStringPlus() {}
  237. int Compare( TBL_OFF oRow1,
  238. TBL_OFF oRow2 )
  239. {
  240. WCHAR * p1 = * (WCHAR **) ((BYTE *) _Alloc.FixedPointer( oRow1 ) + _oDataString );
  241. WCHAR * p2 = * (WCHAR **) ((BYTE *) _Alloc.FixedPointer( oRow2 ) + _oDataString );
  242. // No string is every guaranteed to exist -- even path,
  243. // since a summary catalog may have VT_EMPTY, and a VPATH
  244. // is VT_EMPTY for non-web downlevel queries.
  245. if ( 0 == p1 )
  246. {
  247. if ( 0 == p2 )
  248. return 2 * _CompareB.Compare( oRow1, oRow2 );
  249. else
  250. return _iGTString;
  251. }
  252. else if ( 0 == p2 )
  253. {
  254. return -_iGTString;
  255. }
  256. int rc = CompareStringW( LOCALE_SYSTEM_DEFAULT,
  257. NORM_IGNORECASE,
  258. p1,
  259. -1,
  260. p2,
  261. -1 );
  262. // rc == 1, means less than
  263. // rc == 2, means equal
  264. // rc == 3, means greater than
  265. int result = rc - 2;
  266. if ( result > 0 )
  267. return _iGTString;
  268. if ( result < 0 )
  269. return -_iGTString;
  270. Win4Assert( 0 == result );
  271. // same first key -- now check the second key.
  272. // the * 2 means that it was the second column.
  273. return 2 * _CompareB.Compare( oRow1, oRow2 );
  274. }
  275. private:
  276. int _iGTString; // return value if 1 > 2
  277. CFixedVarTableWindowAllocator &_Alloc; // allocator where rows are
  278. ULONG _oDataString; // offset in row where value resides
  279. TRowCompare<TB> _CompareB;
  280. };