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.

350 lines
9.0 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1999.
  5. //
  6. // File: RECOGNIZ.CXX
  7. //
  8. // Contents: Scan restriction for keys and create recognizers for them
  9. //
  10. // Classes: CScanRst
  11. //
  12. // History: 30-Sep-94 BartoszM Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <recogniz.hxx>
  18. BOOL CKeyDetector::Match ( const CKeyBuf& key ) const
  19. {
  20. return _key.MatchPid (key) && _key.CompareStr (key) == 0;
  21. }
  22. DetectorType CKeyDetector::Type () const
  23. {
  24. return DetSingleKey;
  25. }
  26. BOOL CKeyRangeDetector::Match ( const CKeyBuf& key ) const
  27. {
  28. return _key.MatchPid (key) && _key.CompareStr (key) <= 0
  29. && _keyEnd.MatchPid (key) && _keyEnd.CompareStr (key) > 0;
  30. }
  31. DetectorType CKeyRangeDetector::Type () const
  32. {
  33. return DetRange;
  34. }
  35. BOOL CKeyPrefixDetector::Match ( const CKeyBuf& key ) const
  36. {
  37. return _key.MatchPid (key) && _key.CompareStr (key) <= 0
  38. && _keyEnd.MatchPid (key) && _keyEnd.CompareStr (key) > 0;
  39. }
  40. DetectorType CKeyPrefixDetector::Type () const
  41. {
  42. return DetPrefix;
  43. }
  44. CRecognizer::CRecognizer ()
  45. : _iDet(-1), _aRegionList(0)
  46. {
  47. }
  48. CRecognizer::~CRecognizer ()
  49. {
  50. delete []_aRegionList;
  51. }
  52. void CRecognizer::MakeDetectors ( const CRestriction* pRst )
  53. {
  54. if (pRst)
  55. {
  56. // find all keys and create detectors for them
  57. ScanRst (pRst);
  58. // prepare the array to hold matched key positions
  59. _aRegionList = new CRegionList [Count()];
  60. }
  61. }
  62. void CRecognizer::ScanRst ( const CRestriction* pRst )
  63. {
  64. if (pRst->IsLeaf())
  65. {
  66. ScanLeaf (pRst);
  67. }
  68. else
  69. {
  70. switch (pRst->Type())
  71. {
  72. case RTPhrase:
  73. case RTProximity:
  74. case RTVector:
  75. case RTAnd:
  76. case RTOr:
  77. ScanNode (pRst->CastToNode());
  78. break;
  79. case RTNot:
  80. ScanRst ( ((CNotRestriction *)pRst)->GetChild() );
  81. break;
  82. default:
  83. Win4Assert ( !"Bad Restriction Type" );
  84. THROW (CException(QUERY_E_INVALIDRESTRICTION));
  85. }
  86. }
  87. }
  88. void CRecognizer::ScanNode (const CNodeRestriction * pNode)
  89. {
  90. unsigned cChild = pNode->Count();
  91. for (unsigned i = 0; i < cChild; i++)
  92. {
  93. ScanRst (pNode->GetChild(i));
  94. }
  95. }
  96. void CRecognizer::ScanLeaf (const CRestriction* pRst )
  97. {
  98. switch (pRst->Type())
  99. {
  100. case RTWord:
  101. {
  102. CWordRestriction* wordRst = (CWordRestriction*) pRst;
  103. const CKey* pKey = wordRst->GetKey();
  104. if ( wordRst->IsRange() )
  105. AddPrefix (pKey);
  106. else
  107. AddKey (pKey);
  108. break;
  109. }
  110. case RTSynonym:
  111. {
  112. CSynRestriction* pSynRst = (CSynRestriction*) pRst;
  113. CKeyArray& keyArray = pSynRst->GetKeys();
  114. AddKeyArray ( keyArray, pSynRst->IsRange() );
  115. break;
  116. }
  117. case RTRange:
  118. {
  119. CRangeRestriction* pRangRst = (CRangeRestriction*) pRst;
  120. AddRange ( pRangRst->GetStartKey(), pRangRst->GetEndKey () );
  121. break;
  122. }
  123. case RTNone:
  124. {
  125. // Noise words from vector queries come in as RTNone. Ignore them.
  126. break;
  127. }
  128. default:
  129. Win4Assert ( !"Bad Restriction Type" );
  130. THROW (CException(QUERY_E_INVALIDRESTRICTION));
  131. }
  132. }
  133. //+---------------------------------------------------------------------------
  134. //
  135. // Member: CRecognizer::AddKey, public
  136. //
  137. // Synopsis: Add a key detector
  138. //
  139. // History: 01-Oct-94 BartoszM Created
  140. //
  141. //----------------------------------------------------------------------------
  142. void CRecognizer::AddKey ( const CKey* pKey )
  143. {
  144. int i = FindDet ( DetSingleKey, pKey );
  145. if (i == -1)
  146. {
  147. _aDetector.Push ( new CKeyDetector (*pKey) );
  148. }
  149. }
  150. //+---------------------------------------------------------------------------
  151. //
  152. // Member: CRecognizer::AddPrefix, public
  153. //
  154. // Synopsis: Add a prefix detector
  155. //
  156. // History: 01-Oct-94 BartoszM Created
  157. //
  158. //----------------------------------------------------------------------------
  159. void CRecognizer::AddPrefix ( const CKey* pKey )
  160. {
  161. int i = FindDet ( DetPrefix, pKey );
  162. if (i == -1)
  163. {
  164. _aDetector.Push ( new CKeyPrefixDetector (*pKey) );
  165. }
  166. }
  167. //+---------------------------------------------------------------------------
  168. //
  169. // Member: CRecognizer::AddRange, public
  170. //
  171. // Synopsis: Add a range detector
  172. //
  173. // History: 01-Oct-94 BartoszM Created
  174. //
  175. //----------------------------------------------------------------------------
  176. void CRecognizer::AddRange ( const CKey* pKeyStart, const CKey* pKeyEnd )
  177. {
  178. int i = FindDet ( DetRange, pKeyStart, pKeyEnd );
  179. if (i == -1)
  180. {
  181. _aDetector.Push ( new CKeyRangeDetector (*pKeyStart, *pKeyEnd) );
  182. }
  183. }
  184. //+---------------------------------------------------------------------------
  185. //
  186. // Member: CRecognizer::AddKeyArray, public
  187. //
  188. // Synopsis: Add key detectors
  189. //
  190. // History: 01-Oct-94 BartoszM Created
  191. //
  192. //----------------------------------------------------------------------------
  193. void CRecognizer::AddKeyArray ( const CKeyArray& keyArray, BOOL isRange )
  194. {
  195. if (isRange)
  196. {
  197. for (int i = 0; i < keyArray.Count(); i++ )
  198. {
  199. int j = FindDet (DetPrefix, &keyArray.Get(i));
  200. if (j == -1)
  201. {
  202. _aDetector.Push ( new CKeyPrefixDetector (keyArray.Get(i)) );
  203. }
  204. }
  205. }
  206. else
  207. {
  208. for ( int i = 0; i < keyArray.Count(); i++ )
  209. {
  210. int j = FindDet (DetSingleKey, &keyArray.Get(i));
  211. if (j == -1)
  212. {
  213. _aDetector.Push ( new CKeyDetector (keyArray.Get(i)) );
  214. }
  215. }
  216. }
  217. }
  218. int CRecognizer::FindDet (DetectorType type, const CKey* pKey1, const CKey* pKey2) const
  219. {
  220. Win4Assert ( 0 != pKey1 );
  221. for (unsigned i = 0; i < _aDetector.Count(); i++)
  222. {
  223. const CDetector* pDet = _aDetector.Get (i);
  224. if ( pDet->Type() == type && pKey1->IsExactMatch (*pDet->GetKey()) )
  225. {
  226. switch (type)
  227. {
  228. case DetSingleKey:
  229. case DetPrefix:
  230. Win4Assert ( 0 == pKey2 );
  231. return i;
  232. break;
  233. case DetRange:
  234. Win4Assert ( 0 != pKey2 );
  235. if (pKey2->IsExactMatch (*pDet->GetSecondKey()))
  236. {
  237. return i;
  238. }
  239. break;
  240. }
  241. }
  242. }
  243. return -1;
  244. }
  245. //+---------------------------------------------------------------------------
  246. //
  247. // Member: CRecognizer::Match, public
  248. //
  249. // History: 05-Oct-94 BartoszM Created
  250. //
  251. // Synopsis: It is a sort of an iterator.
  252. // If Match returns TRUE, you should Record the hit,
  253. // after which Match should be called again with the same key
  254. // and so on, until Match returns FALSE
  255. //
  256. //----------------------------------------------------------------------------
  257. BOOL CRecognizer::Match ( const CKeyBuf& key )
  258. {
  259. // start just after the last match
  260. for (unsigned i = _iDet + 1; i < _aDetector.Count(); i++)
  261. {
  262. if ( _aDetector.Get(i)->Match (key) )
  263. {
  264. _iDet = i; // leave it in this state
  265. return TRUE;
  266. }
  267. }
  268. _iDet = -1; // reset the state
  269. return FALSE;
  270. }
  271. //+---------------------------------------------------------------------------
  272. //
  273. // Member: CRecognizer::Record, public
  274. //
  275. // History: 05-Oct-94 BartoszM Created
  276. //
  277. // Synopsis: Records the filter region position of a matched key
  278. //
  279. //----------------------------------------------------------------------------
  280. void CRecognizer::Record ( const FILTERREGION& region, OCCURRENCE occ)
  281. {
  282. Win4Assert ( -1 != _iDet );
  283. CRegionHit* pReg = new CRegionHit ( region, occ );
  284. _aRegionList[_iDet].Insert ( pReg );
  285. }
  286. // Foo* CFooList::Insert ( CFoo* pFoo )
  287. // {
  288. // for ( CBackFooIter it(*this); !AtEnd(it); BackUp(it) )
  289. // {
  290. // if ( it->Size() <= pFoo->Size() ) // overloaded operator ->
  291. // {
  292. // pFoo->InsertAfter(it.GetFoo());
  293. // return;
  294. // }
  295. // }
  296. // // end of list
  297. // Push(pFoo);
  298. // }
  299. //
  300. void CRegionList::Insert (CRegionHit* pHit)
  301. {
  302. for (CRegionBackIter it(*this); !AtEnd(it); BackUp(it))
  303. {
  304. if ( it.GetRegionHit()->Occurrence() <= pHit->Occurrence() )
  305. {
  306. pHit->InsertAfter (it.GetRegionHit());
  307. return;
  308. }
  309. }
  310. _Push(pHit);
  311. }
  312. CRegionList::~CRegionList ()
  313. {
  314. CRegionHit* pHit;
  315. while ( (pHit = (CRegionHit*) _Pop ()) != 0 )
  316. {
  317. delete pHit;
  318. }
  319. }