FileDocCategorySizeDatePackage
DisjunctionMaxScorer.javaAPI DocApache Lucene 2.1.07970Wed Feb 14 10:46:40 GMT 2007org.apache.lucene.search

DisjunctionMaxScorer

public class DisjunctionMaxScorer extends Scorer
The Scorer for DisjunctionMaxQuery's. The union of all documents generated by the the subquery scorers is generated in document number order. The score for each document is the maximum of the scores computed by the subquery scorers that generate that document, plus tieBreakerMultiplier times the sum of the scores for the other subqueries that generate the document.
author
Chuck Williams

Fields Summary
private ArrayList
subScorers
private float
tieBreakerMultiplier
private boolean
more
private boolean
firstTime
Constructors Summary
public DisjunctionMaxScorer(float tieBreakerMultiplier, Similarity similarity)
Creates a new instance of DisjunctionMaxScorer

param
tieBreakerMultiplier Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result.
param
similarity -- not used since our definition involves neither coord nor terms directly

      // True iff next() has not yet been called

                                          
         
        super(similarity);
        this.tieBreakerMultiplier = tieBreakerMultiplier;
    
Methods Summary
public voidadd(org.apache.lucene.search.Scorer scorer)
Add the scorer for a subquery

param
scorer the scorer of a subquery of our associated DisjunctionMaxQuery

        if (scorer.next()) {       // Initialize and retain only if it produces docs
            subScorers.add(scorer);
            more = true;
        }
    
public intdoc()
Determine the current document number. Initially invalid, until {@link #next()} is called the first time.

return
the document number of the currently generated document

        return ((Scorer) subScorers.get(0)).doc();
    
public org.apache.lucene.search.Explanationexplain(int doc)
Explain a score that we computed. UNSUPPORTED -- see explanation capability in DisjunctionMaxQuery.

param
doc the number of a document we scored
return
the Explanation for our score

        throw new UnsupportedOperationException();
    
private voidheapAdjust(int root)

        Scorer scorer=(Scorer)subScorers.get(root);
        int doc=scorer.doc();
        int i=root, size=subScorers.size();
        while (i<=(size>>1)-1) {
            int lchild=(i<<1)+1;
            Scorer lscorer=(Scorer)subScorers.get(lchild);
            int ldoc=lscorer.doc();
            int rdoc=Integer.MAX_VALUE, rchild=(i<<1)+2;
            Scorer rscorer=null;
            if (rchild<size) {
                rscorer=(Scorer)subScorers.get(rchild);
                rdoc=rscorer.doc();
            }
            if (ldoc<doc) {
                if (rdoc<ldoc) {
                    subScorers.set(i, rscorer);
                    subScorers.set(rchild, scorer);
                    i=rchild;
                } else {
                    subScorers.set(i, lscorer);
                    subScorers.set(lchild, scorer);
                    i=lchild;
                }
            } else if (rdoc<doc) {
                subScorers.set(i, rscorer);
                subScorers.set(rchild, scorer);
                i=rchild;
            } else return;
        }
    
private voidheapRemoveRoot()

        int size=subScorers.size();
        if (size==1)
            subScorers.remove(0);
        else {
            subScorers.set(0, subScorers.get(size-1));
            subScorers.remove(size-1);
            heapAdjust(0);
        }
    
private voidheapify()

        int size = subScorers.size();
        for (int i=(size>>1)-1; i>=0; i--)
            heapAdjust(i);
    
public booleannext()
Generate the next document matching our associated DisjunctionMaxQuery.

return
true iff there is a next document

        if (!more) return false;
        if (firstTime) {
            heapify();
            firstTime = false;
            return true;   // more would have been false if no subScorers had any docs
        }
        // Increment all generators that generated the last doc and adjust the heap.
        int lastdoc = ((Scorer) subScorers.get(0)).doc();
        do {
            if (((Scorer) subScorers.get(0)).next())
                heapAdjust(0);
            else {
                heapRemoveRoot();
                if (subScorers.isEmpty()) return (more = false);
            }
        } while ( ((Scorer) subScorers.get(0)).doc()==lastdoc );
        return true;
    
public floatscore()
Determine the current document score. Initially invalid, until {@link #next()} is called the first time.

return
the score of the current generated document

        int doc = ((Scorer) subScorers.get(0)).doc();
        float[] sum = {((Scorer) subScorers.get(0)).score()}, max = {sum[0]};
        int size = subScorers.size();
        scoreAll(1, size, doc, sum, max);
        scoreAll(2, size, doc, sum, max);
        return max[0] + (sum[0] - max[0])*tieBreakerMultiplier;
    
private voidscoreAll(int root, int size, int doc, float[] sum, float[] max)

        if (root<size && ((Scorer) subScorers.get(root)).doc() == doc) {
            float sub = ((Scorer) subScorers.get(root)).score();
            sum[0] += sub;
            max[0] = Math.max(max[0], sub);
            scoreAll((root<<1)+1, size, doc, sum, max);
            scoreAll((root<<1)+2, size, doc, sum, max);
        }
    
public booleanskipTo(int target)
Advance to the first document beyond the current whose number is greater than or equal to target.

param
target the minimum number of the next desired document
return
true iff there is a document to be generated whose number is at least target

        if (firstTime) {
          if (!more) return false;
          heapify();
          firstTime = false;
          return true;   // more would have been false if no subScorers had any docs
        }

        while (subScorers.size()>0 && ((Scorer)subScorers.get(0)).doc()<target) {
            if (((Scorer)subScorers.get(0)).skipTo(target))
                heapAdjust(0);
            else
                heapRemoveRoot();
        }
        if ((subScorers.size()==0))
            return (more = false);
        return true;