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.

844 lines
27 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: QKREP.CXX
  7. //
  8. // Contents: Query Key Repository
  9. //
  10. // Classes: CQueryKeyRepository
  11. //
  12. // History: 04-Jun-91 t-WadeR Created.
  13. // 23-Sep-91 BartosM Rewrote to use phrase expr.
  14. // 31-Jan-93 KyleP Use restrictions, not expressions
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <pch.cxx>
  18. #pragma hdrstop
  19. #include <qparse.hxx>
  20. #include <irest.hxx>
  21. #include "qkrep.hxx"
  22. #include <drep.hxx>
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Member: CQueryKeyRepository::CQueryKeyRepository
  26. //
  27. // Synopsis: Creates Key repository
  28. //
  29. // History: 31-May-91 t-WadeR Created
  30. // 23-Sep-91 BartoszM Rewrote to use phrase expr.
  31. //
  32. //----------------------------------------------------------------------------
  33. CQueryKeyRepository::CQueryKeyRepository ( ULONG fuzzy )
  34. : _occLast(OCC_INVALID),
  35. _pOrRst(0),
  36. _pCurAltPhrase(0),
  37. _cInitialNoiseWords(0),
  38. _fNoiseWordsOnly(FALSE),
  39. _fHasSynonym( FALSE )
  40. {
  41. if ( fuzzy == GENERATE_METHOD_PREFIX )
  42. _isRange = TRUE;
  43. else
  44. _isRange = FALSE;
  45. _pPhrase = new CPhraseRestriction( INIT_PHRASE_WORDS );
  46. Win4Assert( _pPhrase->IsValid() );
  47. }
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Member: CQueryKeyRepository::~CQueryKeyRepository
  51. //
  52. // Synopsis: Destroys
  53. //
  54. // History: 31-May-91 t-WadeR Created
  55. // 23-Sep-91 BartoszM Rewrote to use phrase expr.
  56. //
  57. //----------------------------------------------------------------------------
  58. CQueryKeyRepository::~CQueryKeyRepository()
  59. {
  60. delete _pPhrase;
  61. delete _pOrRst;
  62. delete _pCurAltPhrase;
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. // Member: CQueryKeyRepository::AcqXpr
  67. //
  68. // Synopsis: Acquire Phrase(s)
  69. //
  70. // History: 07-Feb-92 BartoszM Created
  71. // 24-Jan-97 KyleP Handle null phrase (from bad alt words)
  72. //
  73. //----------------------------------------------------------------------------
  74. CRestriction * CQueryKeyRepository::AcqRst()
  75. {
  76. CNodeRestriction *pNodeRst;
  77. if ( _pOrRst )
  78. {
  79. Win4Assert( _pPhrase == 0 );
  80. pNodeRst = _pOrRst;
  81. }
  82. else
  83. pNodeRst = _pPhrase;
  84. //
  85. // pNodeRst may be null, if alternate phrasing didn't work out.
  86. //
  87. if ( 0 == pNodeRst )
  88. return 0;
  89. switch( pNodeRst->Count() )
  90. {
  91. case 0:
  92. return( 0 );
  93. break;
  94. case 1:
  95. return( pNodeRst->RemoveChild(0) );
  96. break;
  97. default:
  98. {
  99. CRestriction * tmp = pNodeRst;
  100. _pOrRst = 0;
  101. _pPhrase = 0;
  102. return( tmp );
  103. break;
  104. }
  105. }
  106. } //AcqRst
  107. //+---------------------------------------------------------------------------
  108. //
  109. // Member: CQueryKeyRepository::PutKey
  110. //
  111. // Synopsis: Puts a key into the key list and occurrence list
  112. //
  113. // Arguments: [cNoiseWordsSkipped] -- count of noise words that have been skipped
  114. //
  115. // History: 31-May-91 t-WadeR Created
  116. // 23-Sep-91 BartoszM Rewrote to use phrase expr.
  117. // 29-Nov-94 SitaramR Rewrote to take Start/EndAltPhrase into account
  118. //
  119. //----------------------------------------------------------------------------
  120. void CQueryKeyRepository::PutKey ( ULONG cNoiseWordsSkipped )
  121. {
  122. // check if there is a set of alt phrases with noise words only
  123. if ( _fNoiseWordsOnly )
  124. return;
  125. ciDebugOut (( DEB_ITRACE, "QueryKeyRepository::PutKey \"%.*ws\", pid = %d\n",
  126. _key.StrLen(), _key.GetStr(), _key.Pid() ));
  127. if ( _pCurAltPhrase ) // if, we are processing an alternate phrase
  128. AppendKey( _pCurAltPhrase, cNoiseWordsSkipped );
  129. else
  130. {
  131. if ( _pOrRst )
  132. {
  133. Win4Assert( _pOrRst->Count() );
  134. Win4Assert( _pPhrase == 0 );
  135. for ( unsigned i=0; i<_pOrRst->Count(); i++)
  136. {
  137. CRestriction *pRst = _pOrRst->GetChild(i);
  138. Win4Assert( pRst->Type() == RTPhrase );
  139. AppendKey( (CPhraseRestriction *) pRst, cNoiseWordsSkipped );
  140. }
  141. }
  142. else
  143. AppendKey( _pPhrase, cNoiseWordsSkipped );
  144. }
  145. _occLast = _occ;
  146. } //PutKey
  147. //+---------------------------------------------------------------------------
  148. //
  149. // Member: CQueryKeyRepository::AppendKey
  150. //
  151. // Synopsis: Appends a key to end of phraseRst
  152. //
  153. // Arguments: [pPhraseRst] -- restriction to append to
  154. // [cNoiseWordsSkipped] -- count of noise words that have been skipped
  155. //
  156. // History: 29-Nov-94 SitaramR Created
  157. //
  158. //----------------------------------------------------------------------------
  159. void CQueryKeyRepository::AppendKey( CPhraseRestriction *pPhraseRst,
  160. ULONG cNoiseWordsSkipped )
  161. {
  162. // _occ as generated by CKeyMaker is not accurate because it does not
  163. // take StartAltPhrase/EndAltPhrase into account. We use _occ (and _occLast)
  164. // solely to test for synonyms. The test is:
  165. //
  166. // if ( _occ == _occLast )
  167. // then synonym
  168. if ( _occ == _occLast )
  169. {
  170. ULONG iLast = pPhraseRst->Count()-1;
  171. COccRestriction *pLastChild = pPhraseRst->GetChild( iLast );
  172. Win4Assert( pLastChild );
  173. if ( pLastChild->Type() == RTWord )
  174. {
  175. ciDebugOut (( DEB_ITRACE, "Create Synonym Expression\n" ));
  176. const CKey* pKey = ((CWordRestriction*) pLastChild)->GetKey();
  177. // there can be no noise words between synonyms
  178. Win4Assert( cNoiseWordsSkipped == 0 );
  179. _fHasSynonym = TRUE;
  180. XPtr<CSynRestriction> xTmp(new CSynRestriction ( *pKey,
  181. pLastChild->Occurrence(),
  182. 0, 0, _isRange ));
  183. Win4Assert( xTmp->IsValid() );
  184. delete pLastChild;
  185. pLastChild = xTmp.Acquire();
  186. pPhraseRst->SetChild ( pLastChild, iLast );
  187. }
  188. Win4Assert ( pLastChild->Type() == RTSynonym );
  189. ((CSynRestriction*) pLastChild)->AddKey ( _key );
  190. }
  191. else
  192. {
  193. XPtr<CWordRestriction> xChildRst( new CWordRestriction( _key, _occ,
  194. cNoiseWordsSkipped, 0, _isRange ) );
  195. Win4Assert( xChildRst->IsValid() );
  196. // calculate correct occurrence taking noise words into account
  197. OCCURRENCE occ = _ComputeOccurrence( xChildRst.GetPointer(), pPhraseRst );
  198. xChildRst->SetOccurrence( occ );
  199. pPhraseRst->AddChild ( xChildRst.GetPointer() );
  200. xChildRst.Acquire();
  201. }
  202. } //AppendKey
  203. //+---------------------------------------------------------------------------
  204. //
  205. // Member: CQueryKeyRepository::StartAltPhrase
  206. //
  207. // Synopsis: Preparation for start of an alternate phrase
  208. //
  209. // Arguments: [cNoiseWordsSkipped] -- count of noise words that have been skipped
  210. //
  211. // History: 29-Nov-94 SitaramR Created
  212. //
  213. //----------------------------------------------------------------------------
  214. void CQueryKeyRepository::StartAltPhrase( ULONG cNoiseWordsSkipped )
  215. {
  216. // check if there is a set of alt phrases with noise words only
  217. if ( _fNoiseWordsOnly )
  218. return;
  219. if ( _pCurAltPhrase )
  220. {
  221. if ( _pCurAltPhrase->Count() == 0 )
  222. delete _pCurAltPhrase;
  223. else
  224. {
  225. // add count of noise words skipped to last child of _pCurAltPhrase
  226. COccRestriction *pOccRst = _pCurAltPhrase->GetChild( _pCurAltPhrase->Count()-1 );
  227. Win4Assert( pOccRst );
  228. pOccRst->AddCountPostNoiseWords( cNoiseWordsSkipped );
  229. _stkAltPhrases.Push( _pCurAltPhrase );
  230. }
  231. }
  232. else
  233. {
  234. if ( _pOrRst )
  235. {
  236. Win4Assert( _pOrRst->Count() );
  237. Win4Assert( _pPhrase == 0 );
  238. // add count of noise words of last child of every phrase in _pOrRst
  239. for ( unsigned i=0; i<_pOrRst->Count(); i++)
  240. {
  241. CRestriction *pRst = _pOrRst->GetChild(i);
  242. Win4Assert( pRst->Type() == RTPhrase );
  243. COccRestriction *pOccRst =
  244. ((CPhraseRestriction *)pRst)->GetChild( ((CPhraseRestriction *)pRst)->Count()-1 );
  245. Win4Assert( pOccRst );
  246. pOccRst->AddCountPostNoiseWords( cNoiseWordsSkipped );
  247. }
  248. }
  249. else
  250. {
  251. if ( _pPhrase->Count() != 0 )
  252. {
  253. // add count of noise words skipped to last child of _pPhrase
  254. COccRestriction *pOccRst = _pPhrase->GetChild( _pPhrase->Count()-1 );
  255. Win4Assert( pOccRst );
  256. pOccRst->AddCountPostNoiseWords( cNoiseWordsSkipped );
  257. }
  258. else // sequence of noise words at the beginning of the phrase
  259. _cInitialNoiseWords = cNoiseWordsSkipped;
  260. }
  261. }
  262. _pCurAltPhrase = new CPhraseRestriction( INIT_PHRASE_WORDS );
  263. _occLast = OCC_INVALID; // reset _occLast
  264. }
  265. //+---------------------------------------------------------------------------
  266. //
  267. // Member: CQueryKeyRepository::EndAltPhrase
  268. //
  269. // Synopsis: Append all alternate phrases to existing phrases
  270. //
  271. // Arguments: [cNoiseWordsSkipped] -- count of noise words that have been skipped
  272. //
  273. // History: 29-Nov-94 SitaramR Created
  274. //
  275. //----------------------------------------------------------------------------
  276. void CQueryKeyRepository::EndAltPhrase( ULONG cNoiseWordsSkipped )
  277. {
  278. // check if there is a set of alt phrases with noise words only
  279. if ( _fNoiseWordsOnly )
  280. return;
  281. // call on StartAltPhrase to stack the current alternate phrase
  282. Win4Assert( _pCurAltPhrase );
  283. StartAltPhrase( cNoiseWordsSkipped );
  284. delete _pCurAltPhrase; // allocated in StartAltPhrase, but it is not needed
  285. _pCurAltPhrase = 0;
  286. // if all alternate phrases are noise, then the entire query is an
  287. // uninteresting phrase because we cannot compute the occurrence of the
  288. // first key after the set of alternate phrases. So, clean up and return.
  289. if ( _stkAltPhrases.Count() == 0 )
  290. {
  291. _fNoiseWordsOnly = TRUE;
  292. delete _pOrRst;
  293. _pOrRst = 0;
  294. delete _pPhrase;
  295. _pPhrase = 0;
  296. return;
  297. }
  298. XNodeRestriction xNewOrRst( new CNodeRestriction( RTOr ));
  299. XPhraseRestriction xTailPhrase;
  300. if ( _pOrRst )
  301. {
  302. // concatenate each of the stacked alternate phrases to every child phrase
  303. // of _pOrRst
  304. Win4Assert( _pOrRst->Count() );
  305. Win4Assert( _pPhrase == 0 );
  306. while ( _stkAltPhrases.Count() > 0 )
  307. {
  308. xTailPhrase.Set( _stkAltPhrases.Pop() );
  309. for ( unsigned i=0; i< _pOrRst->Count(); i++)
  310. {
  311. CRestriction *pRst = _pOrRst->GetChild(i);
  312. Win4Assert( pRst->Type() == RTPhrase );
  313. CloneAndAdd( xNewOrRst.GetPointer(), (CPhraseRestriction *)pRst,
  314. xTailPhrase.GetPointer() );
  315. }
  316. CPhraseRestriction *pTailPhrase = xTailPhrase.Acquire();
  317. delete pTailPhrase;
  318. }
  319. }
  320. else // only one phrase so far
  321. {
  322. while ( _stkAltPhrases.Count() > 0 )
  323. {
  324. xTailPhrase.Set( _stkAltPhrases.Pop() );
  325. CloneAndAdd( xNewOrRst.GetPointer(), _pPhrase, xTailPhrase.GetPointer() );
  326. CPhraseRestriction *pTailPhrase = xTailPhrase.Acquire();
  327. delete pTailPhrase;
  328. }
  329. }
  330. delete _pPhrase;
  331. _pPhrase = 0;
  332. delete _pOrRst;
  333. _pOrRst = xNewOrRst.Acquire();
  334. _occLast = OCC_INVALID; // reset _occLast
  335. }
  336. //+---------------------------------------------------------------------------
  337. //
  338. // Member: CQueryKeyRepository::CloneAndAdd
  339. //
  340. // Synopsis: Clone pHeadPhrase, pTailPhrase, concatenate and add the
  341. // resulting phrase to pOrRst
  342. //
  343. // Arguments: [pOrRst] -- Destination Or node
  344. // [pHeadPhrase] -- first part of a phrase
  345. // [pTailPhrase] -- remaining part of a phrase
  346. //
  347. // History: 29-Nov-94 SitaramR Created
  348. //
  349. //----------------------------------------------------------------------------
  350. void CQueryKeyRepository::CloneAndAdd( CNodeRestriction *pOrRst,
  351. CPhraseRestriction *pHeadPhrase,
  352. CPhraseRestriction *pTailPhrase )
  353. {
  354. XPhraseRestriction xPhraseRst( new CPhraseRestriction( INIT_PHRASE_WORDS ) );
  355. Win4Assert( xPhraseRst->IsValid() );
  356. // clone head
  357. XOccRestriction xOccRst;
  358. for ( unsigned i=0; i<pHeadPhrase->Count(); i++ )
  359. {
  360. xOccRst.Set( pHeadPhrase->GetChild(i)->Clone() );
  361. Win4Assert( xOccRst->IsValid() );
  362. xPhraseRst.GetPointer()->AddChild( xOccRst.GetPointer() );
  363. xOccRst.Acquire();
  364. }
  365. // clone tail
  366. for ( i=0; i<pTailPhrase->Count(); i++)
  367. {
  368. xOccRst.Set( pTailPhrase->GetChild(i)->Clone() );
  369. Win4Assert( xOccRst->IsValid() );
  370. OCCURRENCE occ = _ComputeOccurrence( xOccRst.GetPointer(), xPhraseRst.GetPointer() );
  371. xOccRst.GetPointer()->SetOccurrence( occ );
  372. xPhraseRst.GetPointer()->AddChild( xOccRst.GetPointer() );
  373. xOccRst.Acquire();
  374. }
  375. pOrRst->AddChild( xPhraseRst.GetPointer() );
  376. xPhraseRst.Acquire();
  377. }
  378. //+---------------------------------------------------------------------------
  379. //
  380. // Member: CQueryKeyRepository::_ComputeOccurrence
  381. //
  382. // Synopsis: Computes the noise word adjusted occurrence
  383. //
  384. // Arguments: [pOccRst] -- restriction whose occurrence is to be computed
  385. // [pPhrase] -- phrase to which pOccRst is being appended
  386. //
  387. // History: 29-Nov-94 SitaramR Created
  388. //
  389. //----------------------------------------------------------------------------
  390. OCCURRENCE CQueryKeyRepository::_ComputeOccurrence( COccRestriction *pOccRst,
  391. CPhraseRestriction *pPhraseRst )
  392. {
  393. OCCURRENCE occ;
  394. if ( pPhraseRst->Count() )
  395. {
  396. COccRestriction *pPrevOccRst = pPhraseRst->GetChild( pPhraseRst->Count()-1 );
  397. Win4Assert( pPrevOccRst );
  398. // Occurrence of pOccRst is computed as:
  399. // occurrence of previous child (pPrevOccRst) in pPhraseRst
  400. // + count of noise words following pPrevOccRst
  401. // + count of noise words preceeding pOccRst
  402. // + 1
  403. occ = pPrevOccRst->Occurrence() + pPrevOccRst->CountPostNoiseWords() +
  404. pOccRst->CountPrevNoiseWords() + 1;
  405. }
  406. else
  407. {
  408. // Since there are no preivous restrictions, occurrence of
  409. // pOccRst is computed as:
  410. //
  411. // count of noise words at the beginning of phrase
  412. // + count of noise words preceeding pOccRst
  413. // + 1
  414. occ = _cInitialNoiseWords + pOccRst->CountPrevNoiseWords() + 1;
  415. }
  416. return occ;
  417. }
  418. //+---------------------------------------------------------------------------
  419. //
  420. // Member: CQueryKeyRepository::GetBuffers
  421. //
  422. // Synopsis: Returns address of repository's input buffers
  423. //
  424. // Effects:
  425. //
  426. // Arguments: [ppcbInBuf] -- pointer to pointer to size of input buffer
  427. // [ppbInBuf] -- pointer to pointer to recieve address of buffer
  428. // [ppocc] -- pointer to pointer to recieve address of occurrences
  429. //
  430. // History: 05-June-91 t-WadeR Created.
  431. //
  432. // Notes:
  433. //
  434. //----------------------------------------------------------------------------
  435. void CQueryKeyRepository::GetBuffers( unsigned** ppcbWordBuf,
  436. BYTE** ppbWordBuf, OCCURRENCE** ppocc )
  437. {
  438. _key.SetCount(MAXKEYSIZE);
  439. *ppcbWordBuf = _key.GetCountAddress();
  440. *ppbWordBuf = _key.GetWritableBuf();
  441. *ppocc = &_occ;
  442. }
  443. //+---------------------------------------------------------------------------
  444. //
  445. // Member: CQueryKeyRepository::GetFlags
  446. //
  447. // Synopsis: Returns address of rank and range flags
  448. //
  449. // Arguments: [ppRange] -- range flag
  450. // [ppRank] -- rank flag
  451. //
  452. // History: 11-Feb-92 BartoszM Created.
  453. //
  454. //----------------------------------------------------------------------------
  455. void CQueryKeyRepository::GetFlags ( BOOL** ppRange, CI_RANK** ppRank )
  456. {
  457. *ppRange = &_isRange;
  458. *ppRank = &_rank;
  459. }
  460. //+---------------------------------------------------------------------------
  461. //
  462. // Member: CQueryKeyRepository::FixUp
  463. //
  464. // Synopsis: This funstion creates a word restriction with the cached phrase
  465. // in the CDataRepository. Then it connects the new Word Restriction
  466. // to the phrase (internal restriction ) with a new Or restriction.
  467. // If the internal restriction is an Or restriction, than it simply
  468. // do a AddChild to the Or restriction.
  469. //
  470. // Arguments : [drep] -- CDataRepository containing the cached phrase
  471. //
  472. // History: 10-Feb-2000 KitmanH Created
  473. //
  474. // Note: This function is a hack to fix a word breaker issue. The word
  475. // breaker does compund word breaking for some languages, such as
  476. // German. For example, "tes" is broken into "tes" and "1".
  477. // "tes" get a synonyn "t" and "1" gets a synonym "es". This is a
  478. // result of a hack in the infosoft word breaker. The "1" is a place
  479. // holder and is thrown out in a non prefix match phrase to capture
  480. // the case ("tes" | "t") "es". However, this breaks the prefix
  481. // matching scenerio. Noise words are not thrown out in a prefix
  482. // matching (GENERATE_METHOD_PREFIX) query, "tes*" becomes
  483. // (tes*|t*) (1*|es*). In this case, tes*" is not a match unless
  484. // it is followed immediately with a 1* or es*, e.g. "test case"
  485. // is not a match whereas "tested 1000 times" and "testing especially"
  486. // are matches. The hack here is to Or a CWordRestriction of the
  487. // originally phrase without word breaking. This hack works fine,
  488. // if the original phrase is a single word. It will not work in the
  489. // multiple word case.
  490. //
  491. //----------------------------------------------------------------------------
  492. void CQueryKeyRepository::FixUp( CDataRepository & drep )
  493. {
  494. //
  495. // If the keyRep has synonym, we assume word breaking has occured.
  496. //
  497. if ( _isRange && _fHasSynonym )
  498. {
  499. XNodeRestriction xOrRst;
  500. if ( _pPhrase )
  501. {
  502. xOrRst.Set( new CNodeRestriction( RTOr, 2 ) );
  503. xOrRst->AddChild ( _pPhrase );
  504. }
  505. else
  506. {
  507. Win4Assert( 0 != _pOrRst );
  508. xOrRst.Set( _pOrRst );
  509. }
  510. CKeyBuf KeyBuf;
  511. KeyBuf.SetPid( _key.Pid() );
  512. drep.NormalizeWStr( KeyBuf.GetWritableBuf(), KeyBuf.GetCountAddress() );
  513. // Create a CWordRestriction with the Normalized form of the whole phrase
  514. XPtr<CWordRestriction> xWordRst( new CWordRestriction( KeyBuf,
  515. 0, // occurence
  516. 0,
  517. 0,
  518. TRUE ) );
  519. xOrRst->AddChild( xWordRst.GetPointer() );
  520. xWordRst.Acquire();
  521. _pOrRst = xOrRst.Acquire();
  522. _pPhrase = 0;
  523. }
  524. }
  525. //+---------------------------------------------------------------------------
  526. //
  527. // Member: CVectorKeyRepository::CVectorKeyRepository
  528. //
  529. // Synopsis: Creates Vector Key repository
  530. //
  531. // History: 18-Jan-95 SitaramR Created
  532. //
  533. //----------------------------------------------------------------------------
  534. CVectorKeyRepository::CVectorKeyRepository( const CFullPropSpec & ps,
  535. LCID lcid,
  536. ULONG ulWeight,
  537. CPidMapper & pidMap,
  538. CLangList & langList )
  539. : _occLast(OCC_INVALID),
  540. _ps(ps),
  541. _lcid(lcid),
  542. _ulWeight(ulWeight),
  543. _pidMap(pidMap),
  544. _langList( langList )
  545. {
  546. _pVectorRst = new CVectorRestriction( VECTOR_RANK_JACCARD );
  547. }
  548. //+---------------------------------------------------------------------------
  549. //
  550. // Member: CVectorKeyRepository::~CVectorKeyRepository
  551. //
  552. // History: 18-Jan-95 SitaramR Created
  553. //
  554. //----------------------------------------------------------------------------
  555. CVectorKeyRepository::~CVectorKeyRepository()
  556. {
  557. delete _pVectorRst;
  558. }
  559. //+---------------------------------------------------------------------------
  560. //
  561. // Member: CVectorKeyRepository::AcqRst
  562. //
  563. // Synopsis: Acquire vector restriction
  564. //
  565. // History: 18-Jan-95 SitaramR Created
  566. //
  567. //----------------------------------------------------------------------------
  568. CVectorRestriction* CVectorKeyRepository::AcqRst()
  569. {
  570. if ( _pVectorRst->Count() == 0 )
  571. return 0;
  572. else
  573. {
  574. CVectorRestriction *pTmp = _pVectorRst;
  575. _pVectorRst = 0;
  576. return pTmp;
  577. }
  578. }
  579. //+---------------------------------------------------------------------------
  580. //
  581. // Member: CVectorKeyRepository::PutKey
  582. //
  583. // Synopsis: Adds a key to the vector restriction
  584. //
  585. // Arguments: cNoiseWordsSkipped -- ignored (used by CQueryKeyRepository::PutKey )
  586. //
  587. // History: 18-Jan-95 SitaramR Created
  588. //
  589. //----------------------------------------------------------------------------
  590. void CVectorKeyRepository::PutKey( ULONG cNoiseWordsSkipped )
  591. {
  592. ciDebugOut (( DEB_ITRACE, "VectorKeyRepository::PutKey \"%.*ws\", pid=%d\n",
  593. _key.StrLen(), _key.GetStr(), _key.Pid() ));
  594. // _occ as generated by CKeyMaker is not accurate because it does not
  595. // take StartAltPhrase/EndAltPhrase into account. We use _occ (and _occLast)
  596. // solely to test for synonyms. The test is:
  597. //
  598. // if ( _occ == _occLast )
  599. // then synonym
  600. if ( _occ == _occLast )
  601. {
  602. ULONG iLast = _pVectorRst->Count()-1;
  603. COccRestriction *pLastChild = (COccRestriction *)_pVectorRst->GetChild( iLast );
  604. Win4Assert( pLastChild );
  605. if ( pLastChild->Type() == RTWord )
  606. {
  607. ciDebugOut (( DEB_ITRACE, "Create Synonym Expression\n" ));
  608. const CKey* pKey = ((CWordRestriction*) pLastChild)->GetKey();
  609. // there can be no noise words between synonyms
  610. Win4Assert( cNoiseWordsSkipped == 0 );
  611. CSynRestriction* tmp = new CSynRestriction ( *pKey,
  612. pLastChild->Occurrence(),
  613. 0, 0, FALSE );
  614. Win4Assert( tmp->IsValid() );
  615. delete pLastChild;
  616. pLastChild = tmp;
  617. _pVectorRst->SetChild ( tmp, iLast );
  618. }
  619. Win4Assert ( pLastChild->Type() == RTSynonym );
  620. ((CSynRestriction*) pLastChild)->AddKey ( _key );
  621. }
  622. else
  623. {
  624. XWordRestriction xWordRst( new CWordRestriction( _key, 1, 0, 0, FALSE ));
  625. _pVectorRst->AddChild( xWordRst.GetPointer() );
  626. xWordRst.Acquire();
  627. }
  628. _occLast = _occ;
  629. }
  630. //+---------------------------------------------------------------------------
  631. //
  632. // Member: CVectorKeyRepository::GetBuffers
  633. //
  634. // Synopsis: Returns address of repository's input buffers
  635. //
  636. // Arguments: [ppcbInBuf] -- pointer to pointer to size of input buffer
  637. // [ppbInBuf] -- pointer to pointer to recieve address of buffer
  638. // [ppocc] -- pointer to pointer to recieve address of occurrences
  639. //
  640. // History: 18-Jan-95 SitaramR Created.
  641. //
  642. //----------------------------------------------------------------------------
  643. void CVectorKeyRepository::GetBuffers( unsigned** ppcbWordBuf,
  644. BYTE** ppbWordBuf, OCCURRENCE** ppocc )
  645. {
  646. _key.SetCount(MAXKEYSIZE);
  647. *ppcbWordBuf = _key.GetCountAddress();
  648. *ppbWordBuf = _key.GetWritableBuf();
  649. *ppocc = &_occ;
  650. }
  651. //+---------------------------------------------------------------------------
  652. //
  653. // Member: CVectorKeyRepository::GetFlags
  654. //
  655. // Synopsis: Returns address of rank and range flags
  656. //
  657. // Arguments: [ppRange] -- range flag
  658. // [ppRank] -- rank flag
  659. //
  660. // History: 18-Jan-95 SitaramR Created.
  661. //
  662. //----------------------------------------------------------------------------
  663. void CVectorKeyRepository::GetFlags ( BOOL** ppRange, CI_RANK** ppRank )
  664. {
  665. *ppRange = 0;
  666. *ppRank = 0;
  667. }
  668. //+---------------------------------------------------------------------------
  669. //
  670. // Member: CVectorKeyRepository::PutPhrase
  671. //
  672. // Synopsis: Stores query time phrases
  673. //
  674. // Arguments: [pwcPhrase] -- phrase as it exists in the text sources
  675. // [cwcPhrase] -- count of characters in pwcPhrase
  676. //
  677. // History: 14-Feb-95 SitaramR Created.
  678. //
  679. //----------------------------------------------------------------------------
  680. SCODE CVectorKeyRepository::PutPhrase( WCHAR const *pwcPhrase, ULONG cwcPhrase )
  681. {
  682. XPtrST<WCHAR> xString( new WCHAR[cwcPhrase+1] );
  683. RtlCopyMemory( xString.GetPointer(), pwcPhrase, cwcPhrase*sizeof(WCHAR) );
  684. xString.GetPointer()[cwcPhrase] = 0;
  685. CQueryKeyRepository keyRep( GENERATE_METHOD_EXACT );
  686. BreakPhrase( xString.GetPointer(), _ps, _lcid, GENERATE_METHOD_EXACT, keyRep, 0, _pidMap, _langList );
  687. CRestriction *pPhraseRst = keyRep.AcqRst();
  688. if ( 0 != pPhraseRst )
  689. {
  690. XPtr<CRestriction> xRst( pPhraseRst );
  691. pPhraseRst->SetWeight( _ulWeight );
  692. _pVectorRst->AddChild( pPhraseRst );
  693. xRst.Acquire();
  694. }
  695. _occLast = OCC_INVALID; // reset _occLast
  696. return S_OK;
  697. }
  698. //
  699. // The following are needed to make midl happy. There are no other interfaces
  700. // to bind to. Inheritance from IUnknown is unnecessary.
  701. //
  702. SCODE STDMETHODCALLTYPE CVectorKeyRepository::QueryInterface(REFIID riid, void * * ppvObject)
  703. {
  704. *ppvObject = 0;
  705. return( E_NOTIMPL );
  706. }
  707. ULONG STDMETHODCALLTYPE CVectorKeyRepository::AddRef()
  708. {
  709. return( 1 );
  710. }
  711. ULONG STDMETHODCALLTYPE CVectorKeyRepository::Release()
  712. {
  713. return( 1 );
  714. }