#include "CLucene/StdHeader.h" #include "PhraseScorer.h" #include "PhraseQueue.h" #include "PhrasePositions.h" #include "HitCollector.h" #include "Scorer.h" #include "Similarity.h" namespace lucene{ namespace search{ PhraseScorer::PhraseScorer(TermPositions** tps, const int_t tpsLength, l_byte_t* n, float_t w): norms(n), weight(w), pq( *new PhraseQueue(tpsLength) ) { // use PQ to build a sorted list of PhrasePositions for (int_t i = 0; i < tpsLength; i++) pq.put( new PhrasePositions(*tps[i], i) ); pqToList(); } PhraseScorer::~PhraseScorer() { /* DSR: The PriorityQueue $pq is actually empty at present, the elements ** having been transferred by pqToList() to the linked list starting with ** $first. The nodes of that linked list are deleted by the destructor of ** $first, rather than the destructor of $pq. */ delete first; delete &pq; } void PhraseScorer::score(HitCollector& results, const int_t end){ while (last->doc < end) { // find doc w/ all the terms while (first->doc < last->doc) { // scan forward in first do { first->Next(); } while (first->doc < last->doc); firstToLast(); if (last->doc >= end) return; } // found doc with all terms float_t freq = phraseFreq(); // check for phrase if (freq > 0.0) { float_t score = Similarity::tf(freq)*weight; // compute score score *= Similarity::normf(norms[first->doc]); // normalize results.collect(first->doc, score); // add to results } last->Next(); // resume scanning } } void PhraseScorer::pqToList() { last = first = NULL; while (pq.top() != NULL) { PhrasePositions* pp = pq.pop(); if (last != NULL) { // add next to end of list last->next = pp; } else first = pp; last = pp; pp->next = NULL; } } void PhraseScorer::firstToLast() { last->next = first; // move first to end of list last = first; first = first->next; last->next = NULL; } }}