#include "CLucene/StdHeader.h"
#include "PhraseQuery.h"
#include "SearchHeader.h"
#include "Scorer.h"
#include "BooleanQuery.h"
#include "TermQuery.h"
#include "CLucene/index/Term.h"
#include "CLucene/index/Terms.h"
#include "CLucene/index/IndexReader.h"
#include "CLucene/util/StringBuffer.h"
#include "CLucene/util/VoidList.h"
#include "ExactPhraseScorer.h"
#include "SloppyPhraseScorer.h"
using
namespace
lucene::index;
using
namespace
lucene::util;
namespace
lucene{
namespace
search{
PhraseQuery::PhraseQuery(){
idf = 0.0f;
weight = 0.0f;
slop = 0;
field = NULL;
}
PhraseQuery::~PhraseQuery(){
for
(uint_t i = 0; i < terms.size(); i++){
terms[i]->finalize();
}
}
const
char_t* PhraseQuery::getQueryName()
const
{
return
_T(
"PhraseQuery"
);
}
bool
PhraseQuery::add(Term* term) {
CND_PRECONDITION(term != NULL,
"term is NULL"
)
if
(terms.size() == 0){
field = term->Field();
}
else
{
if
(stringCompare(term->Field(), field) != 0){
return
false
;
}
}
terms.push_back(term->pointer());
return
true
;
}
float_t PhraseQuery::sumOfSquaredWeights(Searcher& searcher) {
Term *T = NULL;
for
(uint_t i = 0; i < terms.size(); i++){
T = terms.at(i);
CND_CONDITION(T != NULL,
"T is NULL"
);
idf += Similarity::idf(*T, searcher);
}
weight = idf * boost;
return
weight * weight;
}
void
PhraseQuery::normalize(
const
float_t norm) {
weight *= norm;
weight *= idf;
}
Scorer* PhraseQuery::scorer(IndexReader& reader) {
int_t tpsLength = terms.size();
if
(tpsLength == 0)
return
NULL;
if
(tpsLength == 1) {
Term* term = terms.at(0);
TermDocs* docs = &reader.termDocs(term);
if
(docs == NULL)
return
NULL;
return
new
TermScorer(*docs, reader.getNorms(term->Field()), weight);
}
TermPositions** tps =
new
TermPositions*[tpsLength];
CND_CONDITION(tps != NULL,
"Could not allocate memory for tps"
);
TermPositions* p = NULL;
for
(uint_t i = 0; i < terms.size(); i++) {
p = &reader.termPositions(terms.at(i));
if
(p == NULL) {
while
(--i >= 0){
_DELETE(tps[i]);
}
_DELETE_ARRAY(tps);
return
NULL;
}
tps[i] = p;
}
Scorer* ret = NULL;
#ifndef NO_FUZZY_QUERY
if
(slop != 0){
ret =
new
SloppyPhraseScorer(tps,tpsLength, slop, reader.getNorms(field), weight);
}
else
#endif
ret =
new
ExactPhraseScorer(tps, tpsLength,reader.getNorms(field), weight);
CND_CONDITION(ret != NULL,
"Could not allocate memory for ret"
)
_DELETE_ARRAY(tps);
return
ret;
}
void
PhraseQuery::getTerms(Term**& ret, int_t& size){
size = terms.size();
ret =
new
Term*[size];
CND_CONDITION(ret != NULL,
"Could not allocated memory for ret"
)
for
( int_t i=0;i<size;i++ ){
ret[i] = terms[i];
}
}
const
char_t* PhraseQuery::toString(
const
char_t* f) {
CND_PRECONDITION(f != NULL,
"f is NULL"
)
StringBuffer buffer;
if
( stringCompare(field,f)!= 0) {
buffer.append(field);
buffer.append( _T(
":"
));
}
buffer.append( _T(
"\""
) );
Term *T = NULL;
for
(uint_t i = 0; i < terms.size(); i++) {
T = terms.at(i);
CND_CONDITION(T !=NULL,
"T is NULL"
)
buffer.append( T->Text() );
if
(i != terms.size()-1){
buffer.append(_T(
" "
));
}
}
buffer.append( _T(
"\""
) );
#ifndef NO_FUZZY_QUERY
if
(slop != 0) {
buffer.append(_T(
"~"
));
buffer.append(slop);
}
#endif
if
(boost != 1.0f) {
buffer.append(_T(
"^"
));
buffer.append( boost,10 );
}
return
buffer.ToString();
}
}}