/*------------------------------------------------------------------------------ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team * * Distributable under the terms of either the Apache License (Version 2.0) or * the GNU Lesser General Public License, as specified in the COPYING file. ------------------------------------------------------------------------------*/ #include "CLucene/StdHeader.h" #ifndef NO_PREFIX_QUERY #include "PrefixQuery.h" CL_NS_USE(index) CL_NS_DEF(search) PrefixQuery::PrefixQuery(Term* Prefix){ //Func - Constructor. // Constructs a query for terms starting with prefix //Pre - Prefix != NULL //Post - The instance has been created //Get a pointer to Prefix prefix = _CL_POINTER(Prefix); } PrefixQuery::PrefixQuery(const PrefixQuery& clone):Query(clone){ prefix = _CL_POINTER(clone.prefix); } Query* PrefixQuery::clone() const{ return _CLNEW PrefixQuery(*this); } Term* PrefixQuery::getPrefix(bool pointer){ if ( pointer ) return _CL_POINTER(prefix); else return prefix; } PrefixQuery::~PrefixQuery(){ //Func - Destructor //Pre - true //Post - The instance has been destroyed. //Delete prefix by finalizing it _CLDECDELETE(prefix); } /** Returns a hash code value for this object.*/ size_t PrefixQuery::hashCode() const { return Similarity::floatToByte(getBoost()) ^ prefix->hashCode(); } const TCHAR* PrefixQuery::getQueryName()const{ //Func - Returns the name "PrefixQuery" //Pre - true //Post - The string "PrefixQuery" has been returned return getClassName(); } const TCHAR* PrefixQuery::getClassName(){ //Func - Returns the name "PrefixQuery" //Pre - true //Post - The string "PrefixQuery" has been returned return _T("PrefixQuery"); } bool PrefixQuery::equals(Query * other) const{ if (!(other->instanceOf(PrefixQuery::getClassName()))) return false; PrefixQuery* rq = (PrefixQuery*)other; bool ret = (this->getBoost() == rq->getBoost()) && (this->prefix->equals(rq->prefix)); return ret; } Query* PrefixQuery::rewrite(IndexReader* reader){ BooleanQuery* query = _CLNEW BooleanQuery(); TermEnum* enumerator = reader->terms(prefix); Term* lastTerm = NULL; try { const TCHAR* prefixText = prefix->text(); const TCHAR* prefixField = prefix->field(); int32_t prefixLen = prefix->textLength(); do { lastTerm = enumerator->term(); if (lastTerm != NULL && lastTerm->field() == prefixField ){ //now see if term->text() starts with prefixText int32_t termLen = lastTerm->textLength(); if ( prefixLen>termLen ) break; //the prefix is longer than the term, can't be matched //check for prefix match if ( _tcsncmp(lastTerm->text(),prefixText,prefixLen)!=0 ) break; TermQuery* tq = _CLNEW TermQuery(lastTerm); // found a match tq->setBoost(getBoost()); // set the boost query->add(tq,true,false, false); // add to query } else break; _CLDECDELETE(lastTerm); } while (enumerator->next()); }_CLFINALLY( enumerator->close(); _CLDELETE(enumerator); _CLDECDELETE(lastTerm); ); _CLDECDELETE(lastTerm); //if we only added one clause and the clause is not prohibited then //we can just return the query if (query->getClauseCount() == 1) { // optimize 1-clause queries BooleanClause** clauses = query->getClauses(); BooleanClause* c = clauses[0]; _CLDELETE_ARRAY(clauses); if (!c->prohibited) { // just return clause c->deleteQuery=false; Query* ret = c->query; _CLDELETE(query); return ret; } } return query; } Query* PrefixQuery::combine(Query** queries) { return Query::mergeBooleanQueries(queries); } TCHAR* PrefixQuery::toString(const TCHAR* field) const{ //Func - Creates a user-readable version of this query and returns it as as string //Pre - field != NULL //Post - a user-readable version of this query has been returned as as string //Instantiate a stringbuffer buffer to store the readable version temporarily CL_NS(util)::StringBuffer buffer; //check if field equal to the field of prefix if( field==NULL || _tcscmp(prefix->field(),field) != 0 ) { //Append the field of prefix to the buffer buffer.append(prefix->field()); //Append a colon buffer.append(_T(":") ); } //Append the text of the prefix buffer.append(prefix->text()); //Append a wildchar character buffer.append(_T("*")); //if the boost factor is not eaqual to 1 if (getBoost() != 1.0f) { //Append ^ buffer.append(_T("^")); //Append the boost factor buffer.appendFloat( getBoost(),1); } //Convert StringBuffer buffer to TCHAR block and return it return buffer.toString(); } CL_NS_END #endif