|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 1999.
//
// File: RECOGNIZ.CXX
//
// Contents: Scan restriction for keys and create recognizers for them
//
// Classes: CScanRst
//
// History: 30-Sep-94 BartoszM Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <recogniz.hxx>
BOOL CKeyDetector::Match ( const CKeyBuf& key ) const { return _key.MatchPid (key) && _key.CompareStr (key) == 0; }
DetectorType CKeyDetector::Type () const { return DetSingleKey; }
BOOL CKeyRangeDetector::Match ( const CKeyBuf& key ) const { return _key.MatchPid (key) && _key.CompareStr (key) <= 0 && _keyEnd.MatchPid (key) && _keyEnd.CompareStr (key) > 0; }
DetectorType CKeyRangeDetector::Type () const { return DetRange; }
BOOL CKeyPrefixDetector::Match ( const CKeyBuf& key ) const { return _key.MatchPid (key) && _key.CompareStr (key) <= 0 && _keyEnd.MatchPid (key) && _keyEnd.CompareStr (key) > 0; }
DetectorType CKeyPrefixDetector::Type () const { return DetPrefix; }
CRecognizer::CRecognizer () : _iDet(-1), _aRegionList(0) { }
CRecognizer::~CRecognizer () { delete []_aRegionList; }
void CRecognizer::MakeDetectors ( const CRestriction* pRst ) { if (pRst) { // find all keys and create detectors for them
ScanRst (pRst); // prepare the array to hold matched key positions
_aRegionList = new CRegionList [Count()]; } }
void CRecognizer::ScanRst ( const CRestriction* pRst ) { if (pRst->IsLeaf()) { ScanLeaf (pRst); } else { switch (pRst->Type()) { case RTPhrase: case RTProximity: case RTVector: case RTAnd: case RTOr: ScanNode (pRst->CastToNode()); break; case RTNot: ScanRst ( ((CNotRestriction *)pRst)->GetChild() ); break; default: Win4Assert ( !"Bad Restriction Type" ); THROW (CException(QUERY_E_INVALIDRESTRICTION)); } } }
void CRecognizer::ScanNode (const CNodeRestriction * pNode) { unsigned cChild = pNode->Count(); for (unsigned i = 0; i < cChild; i++) { ScanRst (pNode->GetChild(i)); } }
void CRecognizer::ScanLeaf (const CRestriction* pRst ) { switch (pRst->Type()) { case RTWord: { CWordRestriction* wordRst = (CWordRestriction*) pRst; const CKey* pKey = wordRst->GetKey();
if ( wordRst->IsRange() ) AddPrefix (pKey); else AddKey (pKey); break; } case RTSynonym: { CSynRestriction* pSynRst = (CSynRestriction*) pRst; CKeyArray& keyArray = pSynRst->GetKeys(); AddKeyArray ( keyArray, pSynRst->IsRange() ); break; } case RTRange: { CRangeRestriction* pRangRst = (CRangeRestriction*) pRst; AddRange ( pRangRst->GetStartKey(), pRangRst->GetEndKey () ); break; } case RTNone: { // Noise words from vector queries come in as RTNone. Ignore them.
break; } default: Win4Assert ( !"Bad Restriction Type" ); THROW (CException(QUERY_E_INVALIDRESTRICTION)); } }
//+---------------------------------------------------------------------------
//
// Member: CRecognizer::AddKey, public
//
// Synopsis: Add a key detector
//
// History: 01-Oct-94 BartoszM Created
//
//----------------------------------------------------------------------------
void CRecognizer::AddKey ( const CKey* pKey ) { int i = FindDet ( DetSingleKey, pKey ); if (i == -1) { _aDetector.Push ( new CKeyDetector (*pKey) ); } }
//+---------------------------------------------------------------------------
//
// Member: CRecognizer::AddPrefix, public
//
// Synopsis: Add a prefix detector
//
// History: 01-Oct-94 BartoszM Created
//
//----------------------------------------------------------------------------
void CRecognizer::AddPrefix ( const CKey* pKey ) { int i = FindDet ( DetPrefix, pKey ); if (i == -1) { _aDetector.Push ( new CKeyPrefixDetector (*pKey) ); } }
//+---------------------------------------------------------------------------
//
// Member: CRecognizer::AddRange, public
//
// Synopsis: Add a range detector
//
// History: 01-Oct-94 BartoszM Created
//
//----------------------------------------------------------------------------
void CRecognizer::AddRange ( const CKey* pKeyStart, const CKey* pKeyEnd ) { int i = FindDet ( DetRange, pKeyStart, pKeyEnd ); if (i == -1) { _aDetector.Push ( new CKeyRangeDetector (*pKeyStart, *pKeyEnd) ); } }
//+---------------------------------------------------------------------------
//
// Member: CRecognizer::AddKeyArray, public
//
// Synopsis: Add key detectors
//
// History: 01-Oct-94 BartoszM Created
//
//----------------------------------------------------------------------------
void CRecognizer::AddKeyArray ( const CKeyArray& keyArray, BOOL isRange ) { if (isRange) { for (int i = 0; i < keyArray.Count(); i++ ) { int j = FindDet (DetPrefix, &keyArray.Get(i)); if (j == -1) { _aDetector.Push ( new CKeyPrefixDetector (keyArray.Get(i)) ); } } } else { for ( int i = 0; i < keyArray.Count(); i++ ) { int j = FindDet (DetSingleKey, &keyArray.Get(i)); if (j == -1) { _aDetector.Push ( new CKeyDetector (keyArray.Get(i)) ); } } } }
int CRecognizer::FindDet (DetectorType type, const CKey* pKey1, const CKey* pKey2) const { Win4Assert ( 0 != pKey1 ); for (unsigned i = 0; i < _aDetector.Count(); i++) { const CDetector* pDet = _aDetector.Get (i); if ( pDet->Type() == type && pKey1->IsExactMatch (*pDet->GetKey()) ) { switch (type) { case DetSingleKey: case DetPrefix: Win4Assert ( 0 == pKey2 ); return i; break; case DetRange: Win4Assert ( 0 != pKey2 ); if (pKey2->IsExactMatch (*pDet->GetSecondKey())) { return i; } break; } } } return -1; }
//+---------------------------------------------------------------------------
//
// Member: CRecognizer::Match, public
//
// History: 05-Oct-94 BartoszM Created
//
// Synopsis: It is a sort of an iterator.
// If Match returns TRUE, you should Record the hit,
// after which Match should be called again with the same key
// and so on, until Match returns FALSE
//
//----------------------------------------------------------------------------
BOOL CRecognizer::Match ( const CKeyBuf& key ) { // start just after the last match
for (unsigned i = _iDet + 1; i < _aDetector.Count(); i++) { if ( _aDetector.Get(i)->Match (key) ) { _iDet = i; // leave it in this state
return TRUE; } } _iDet = -1; // reset the state
return FALSE; }
//+---------------------------------------------------------------------------
//
// Member: CRecognizer::Record, public
//
// History: 05-Oct-94 BartoszM Created
//
// Synopsis: Records the filter region position of a matched key
//
//----------------------------------------------------------------------------
void CRecognizer::Record ( const FILTERREGION& region, OCCURRENCE occ) { Win4Assert ( -1 != _iDet ); CRegionHit* pReg = new CRegionHit ( region, occ );
_aRegionList[_iDet].Insert ( pReg ); }
// Foo* CFooList::Insert ( CFoo* pFoo )
// {
// for ( CBackFooIter it(*this); !AtEnd(it); BackUp(it) )
// {
// if ( it->Size() <= pFoo->Size() ) // overloaded operator ->
// {
// pFoo->InsertAfter(it.GetFoo());
// return;
// }
// }
// // end of list
// Push(pFoo);
// }
//
void CRegionList::Insert (CRegionHit* pHit) { for (CRegionBackIter it(*this); !AtEnd(it); BackUp(it)) { if ( it.GetRegionHit()->Occurrence() <= pHit->Occurrence() ) { pHit->InsertAfter (it.GetRegionHit()); return; } } _Push(pHit); }
CRegionList::~CRegionList () { CRegionHit* pHit; while ( (pHit = (CRegionHit*) _Pop ()) != 0 ) { delete pHit; } }
|