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.

443 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  4. //
  5. // File: NodeXpr.cxx
  6. //
  7. // Contents: Internal expression classes
  8. //
  9. // Classes: CXpr
  10. //
  11. // History: 11-Sep-91 KyleP Created
  12. // 23-Jan-95 t-colinb Added Support for RTVector in
  13. // CNodeXpr::IsMatch
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <pch.cxx>
  17. #pragma hdrstop
  18. #include <xpr.hxx>
  19. #include <parse.hxx>
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Member: CNodeXpr::CNodeXpr, public
  23. //
  24. // Synopsis: Initialze an empty node.
  25. //
  26. // Arguments: [type] -- Type of node (AND, OR, etc.)
  27. // [cInit] -- A hint about the number of expressions which
  28. // will be added to this node.
  29. //
  30. // Signals: ???
  31. //
  32. // History: 05-Dec-91 KyleP Created.
  33. //
  34. //----------------------------------------------------------------------------
  35. CNodeXpr::CNodeXpr ( CXpr::NodeType type, unsigned cInit )
  36. : CXpr ( type ),
  37. _cXpr( 0 ),
  38. _size( cInit )
  39. {
  40. _aXpr = new CXpr* [cInit];
  41. }
  42. //+---------------------------------------------------------------------------
  43. //
  44. // Member: CNodeXpr::CNodeXpr, public
  45. //
  46. // Synopsis: Copy constructor
  47. //
  48. // Arguments: [nxpr] -- Node to copy from.
  49. //
  50. // Signals: ???
  51. //
  52. // History: 11-Dec-91 KyleP Created.
  53. //
  54. //----------------------------------------------------------------------------
  55. CNodeXpr::CNodeXpr( CNodeXpr & nxpr )
  56. : CXpr ( nxpr.NType() )
  57. {
  58. _cXpr = nxpr._cXpr;
  59. _size = nxpr._cXpr;
  60. _weight = nxpr._weight;
  61. _aXpr = new CXpr * [ _size ];
  62. RtlZeroMemory( _aXpr, _size * sizeof( CXpr * ) );
  63. TRY
  64. {
  65. for ( int i = _cXpr-1; i >= 0; i-- )
  66. _aXpr[i] = nxpr._aXpr[i]->Clone();
  67. }
  68. CATCH( CException, e )
  69. {
  70. for ( unsigned i = 0; i < _cXpr; i++ )
  71. delete _aXpr[i];
  72. delete _aXpr;
  73. RETHROW();
  74. }
  75. END_CATCH
  76. }
  77. //+---------------------------------------------------------------------------
  78. //
  79. // Member: CNodeXpr::~CNodeXpr, public
  80. //
  81. // Synopsis: Destroy subexpressions and cursor (if any)
  82. //
  83. // Signals: ???
  84. //
  85. // History: 05-Dec-91 KyleP Created.
  86. //
  87. //----------------------------------------------------------------------------
  88. CNodeXpr::~CNodeXpr ()
  89. {
  90. for ( unsigned i = 0; i < _cXpr; i++ )
  91. delete _aXpr[i];
  92. delete _aXpr;
  93. }
  94. //+---------------------------------------------------------------------------
  95. //
  96. // Member: CNodeXpr::Clone, public
  97. //
  98. // Returns: A copy of this node.
  99. //
  100. // Signals: ???
  101. //
  102. // Derivation: From base class CXpr, Always override in subclasses.
  103. //
  104. // History: 11-Dec-91 KyleP Created.
  105. //
  106. //----------------------------------------------------------------------------
  107. CXpr * CNodeXpr::Clone()
  108. {
  109. return( new CNodeXpr( *this ) );
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CNodeXpr::SelectIndexing, public
  114. //
  115. // Effects: Selects indexing for children.
  116. //
  117. // History: 03-Nov-94 KyleP Created.
  118. //
  119. // Notes: Index selection is only applicable for AND nodes.
  120. //
  121. //----------------------------------------------------------------------------
  122. void CNodeXpr::SelectIndexing( CIndexStrategy & strategy )
  123. {
  124. BOOL fModeChange;
  125. if ( NType() == NTAnd )
  126. fModeChange = strategy.SetAndMode();
  127. else if ( NType() == NTOr )
  128. fModeChange = strategy.SetOrMode();
  129. else
  130. {
  131. strategy.SetUnknownBounds();
  132. return;
  133. }
  134. for ( unsigned i = 0; i < _cXpr; i++ )
  135. _aXpr[i]->SelectIndexing( strategy );
  136. if ( fModeChange )
  137. strategy.DoneWithBoolean();
  138. }
  139. //+---------------------------------------------------------------------------
  140. //
  141. // Member: CNodeXpr::IsLeaf, public
  142. //
  143. // Returns: FALSE. Nodes are never leaf expressions.
  144. //
  145. // Derivation: From base class CXpr, Frequently override in subclasses.
  146. //
  147. // History: 12-Dec-91 KyleP Created.
  148. //
  149. //----------------------------------------------------------------------------
  150. BOOL CNodeXpr::IsLeaf() const
  151. {
  152. return FALSE;
  153. }
  154. //+---------------------------------------------------------------------------
  155. //
  156. // Member: CNodeXpr::AddChild, public
  157. //
  158. // Synopsis: Add an expression to the node.
  159. //
  160. // Arguments: [child] -- Expression to add.
  161. //
  162. // Signals: ???
  163. //
  164. // History: 12-Dec-91 KyleP Created.
  165. //
  166. // Notes: Once an expression has been added to a node it is owned
  167. // by that node. (e.g., no one else should delete it)
  168. //
  169. //----------------------------------------------------------------------------
  170. void CNodeXpr::AddChild ( CXpr* child )
  171. {
  172. Win4Assert( child );
  173. if ( _cXpr < _size )
  174. {
  175. _aXpr[_cXpr++] = child;
  176. }
  177. else
  178. {
  179. CXpr ** newArray = new CXpr * [ 2 * _size ];
  180. memcpy( newArray, _aXpr, _cXpr * sizeof( CXpr * ) );
  181. Win4Assert( _cXpr == _size );
  182. newArray[_cXpr++] = child;
  183. delete _aXpr;
  184. _size *= 2;
  185. _aXpr = newArray;
  186. }
  187. }
  188. //+---------------------------------------------------------------------------
  189. //
  190. // Member: CNodeXpr::HitCount, public
  191. //
  192. // Returns: Sum for OR, Min for AND
  193. //
  194. // History: 01-May-91 KyleP Created.
  195. //
  196. // Notes: HitCount only makes sense for content clauses. If there
  197. // are any non-content clauses then HitCount will return 0.
  198. //
  199. //----------------------------------------------------------------------------
  200. ULONG CNodeXpr::HitCount( CRetriever & obj )
  201. {
  202. ULONG result;
  203. switch ( NType() )
  204. {
  205. case NTAnd:
  206. {
  207. result = 0;
  208. for (int i = Count()-1; i >= 0; i--)
  209. {
  210. ULONG thisChild = GetChild( i )->HitCount( obj );
  211. result = (thisChild) ? min( result, thisChild ) : result;
  212. }
  213. }
  214. break;
  215. case NTOr:
  216. {
  217. result = 0;
  218. for (int i = Count()-1; i >= 0; i--)
  219. {
  220. ULONG thisChild = GetChild( i )->HitCount( obj );
  221. if ( 0 != thisChild )
  222. {
  223. result += GetChild( i )->HitCount( obj );
  224. }
  225. else
  226. {
  227. result = 0;
  228. break;
  229. }
  230. }
  231. }
  232. break;
  233. default:
  234. result = 0;
  235. break;
  236. }
  237. return( result );
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Member: CNodeXpr::Rank, public
  242. //
  243. // Returns: Sum for OR, Min for AND
  244. //
  245. // History: 01-May-91 KyleP Created.
  246. //
  247. //----------------------------------------------------------------------------
  248. LONG CNodeXpr::Rank( CRetriever & obj )
  249. {
  250. LONG result;
  251. switch ( NType() )
  252. {
  253. case NTAnd:
  254. {
  255. result = MAX_QUERY_RANK;
  256. for (int i = Count()-1; i >= 0; i--)
  257. {
  258. result = min( result, GetChild( i )->Rank( obj ) );
  259. }
  260. }
  261. break;
  262. case NTOr:
  263. {
  264. result = 0;
  265. for (int i = Count()-1; i >= 0; i--)
  266. {
  267. result += GetChild( i )->Rank( obj );
  268. }
  269. result /= Count();
  270. }
  271. break;
  272. default:
  273. result = 0;
  274. break;
  275. }
  276. return( result );
  277. }
  278. //+---------------------------------------------------------------------------
  279. //
  280. // Member: CNodeXpr::IsMatch, public
  281. //
  282. // Arguments: [obj] -- The objects table. [obj] is already positioned
  283. // to the record to test.
  284. // [wid] -- Workid of object to which [obj] is positioned.
  285. //
  286. // Returns: TRUE if the current record satisfies the relation.
  287. //
  288. // Signals: ???
  289. //
  290. // History: 20-Nov-91 KyleP Created.
  291. // 23-Jan-95 t-colinb Added Support for RTVector in
  292. //
  293. //
  294. //----------------------------------------------------------------------------
  295. BOOL CNodeXpr::IsMatch( CRetriever & obj )
  296. {
  297. Win4Assert( NType() == NTAnd ||
  298. NType() == NTOr ||
  299. NType() == NTVector );
  300. //
  301. // If some portion of the node has been indexed, adjust the cursor to
  302. // the wid we're looking for.
  303. //
  304. WORKID widCur = widInvalid;
  305. BOOL result;
  306. switch ( NType() )
  307. {
  308. case NTAnd:
  309. result = TRUE;
  310. {
  311. for (int i = Count()-1; result && i >= 0; i--)
  312. {
  313. result = GetChild( i )->IsMatch( obj );
  314. }
  315. }
  316. break;
  317. case NTOr:
  318. case NTVector:
  319. result = FALSE;
  320. {
  321. for (int i = Count()-1; !result && i >= 0; i--)
  322. {
  323. result = GetChild( i )->IsMatch( obj );
  324. }
  325. }
  326. break;
  327. default:
  328. result = FALSE;
  329. break;
  330. }
  331. return result;
  332. }
  333. //+---------------------------------------------------------------------------
  334. //
  335. // Member: CNodeXpr::RemoveChild, public
  336. //
  337. // Synopsis: Removes a node.
  338. //
  339. // Arguments: [iPos] -- Position of node to remove.
  340. //
  341. // Requires: [iPos] is a valid node.
  342. //
  343. // Returns: The child node which was removed.
  344. //
  345. // History: 19-Nov-91 KyleP Created.
  346. //
  347. // Notes: CNodeXpr does not guarantee the position of nodes across
  348. // calls to RemoveChild.
  349. //
  350. //----------------------------------------------------------------------------
  351. CXpr* CNodeXpr::RemoveChild ( unsigned iPos )
  352. {
  353. Win4Assert ( iPos <= _cXpr );
  354. CXpr * pxp = _aXpr[iPos];
  355. _aXpr[iPos] = _aXpr[ _cXpr - 1 ];
  356. _cXpr--;
  357. #if (CIDBG == 1)
  358. _aXpr[ _cXpr ] = 0;
  359. #endif
  360. return( pxp );
  361. }
  362. //+-------------------------------------------------------------------------
  363. //
  364. // Member: CVectorXpr::CVectorXpr, public
  365. //
  366. // Synopsis: Constructs a vector expression.
  367. //
  368. // Arguments: [type] -- Type of node (AND, OR, etc.)
  369. // [cInit] -- A hint about the number of expressions
  370. // which will be added.
  371. // [RankMethod] -- Method used to compute rank.
  372. //
  373. // History: 24-Jul-92 KyleP Created
  374. //
  375. //--------------------------------------------------------------------------
  376. CVectorXpr::CVectorXpr( unsigned cInit,
  377. ULONG RankMethod )
  378. : CNodeXpr( CXpr::NTVector, cInit ),
  379. _ulRankMethod( RankMethod )
  380. {
  381. }