Clover Coverage Report
Coverage timestamp: Fri May 9 2008 10:54:27 EST
../../../../img/srcFileCovDistChart10.png 0% of files have more coverage
80   196   32   7.27
38   123   0.4   11
11     2.91  
1    
 
  DisjunctionMaxScorer       Line # 29 80 32 92.2% 0.92248064
 
  (20)
 
1    package org.apache.lucene.search;
2   
3    /**
4    * Copyright 2004 The Apache Software Foundation
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10    * http://www.apache.org/licenses/LICENSE-2.0
11    *
12    * Unless required by applicable law or agreed to in writing, software
13    * distributed under the License is distributed on an "AS IS" BASIS,
14    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    * See the License for the specific language governing permissions and
16    * limitations under the License.
17    */
18   
19    import java.io.IOException;
20    import java.util.ArrayList;
21   
22    /**
23    * The Scorer for DisjunctionMaxQuery's. The union of all documents generated by the the subquery scorers
24    * is generated in document number order. The score for each document is the maximum of the scores computed
25    * by the subquery scorers that generate that document, plus tieBreakerMultiplier times the sum of the scores
26    * for the other subqueries that generate the document.
27    * @author Chuck Williams
28    */
 
29    class DisjunctionMaxScorer extends Scorer {
30   
31    /* The scorers for subqueries that have remaining docs, kept as a min heap by number of next doc. */
32    private ArrayList subScorers = new ArrayList();
33   
34    /* Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. */
35    private float tieBreakerMultiplier;
36   
37    private boolean more = false; // True iff there is a next document
38    private boolean firstTime = true; // True iff next() has not yet been called
39   
40    /** Creates a new instance of DisjunctionMaxScorer
41    * @param tieBreakerMultiplier Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result.
42    * @param similarity -- not used since our definition involves neither coord nor terms directly */
 
43  100 toggle public DisjunctionMaxScorer(float tieBreakerMultiplier, Similarity similarity) {
44  100 super(similarity);
45  100 this.tieBreakerMultiplier = tieBreakerMultiplier;
46    }
47   
48    /** Add the scorer for a subquery
49    * @param scorer the scorer of a subquery of our associated DisjunctionMaxQuery
50    */
 
51  238 toggle public void add(Scorer scorer) throws IOException {
52  238 if (scorer.next()) { // Initialize and retain only if it produces docs
53  214 subScorers.add(scorer);
54  214 more = true;
55    }
56    }
57   
58    /** Generate the next document matching our associated DisjunctionMaxQuery.
59    * @return true iff there is a next document
60    */
 
61  364 toggle public boolean next() throws IOException {
62  0 if (!more) return false;
63  364 if (firstTime) {
64  81 heapify();
65  81 firstTime = false;
66  81 return true; // more would have been false if no subScorers had any docs
67    }
68    // Increment all generators that generated the last doc and adjust the heap.
69  283 int lastdoc = ((Scorer) subScorers.get(0)).doc();
70  283 do {
71  467 if (((Scorer) subScorers.get(0)).next())
72  313 heapAdjust(0);
73    else {
74  154 heapRemoveRoot();
75  154 if (subScorers.isEmpty()) return (more = false);
76    }
77  394 } while ( ((Scorer) subScorers.get(0)).doc()==lastdoc );
78  210 return true;
79    }
80   
81    /** Determine the current document number. Initially invalid, until {@link #next()} is called the first time.
82    * @return the document number of the currently generated document
83    */
 
84  556 toggle public int doc() {
85  556 return ((Scorer) subScorers.get(0)).doc();
86    }
87   
88    /** Determine the current document score. Initially invalid, until {@link #next()} is called the first time.
89    * @return the score of the current generated document
90    */
 
91  317 toggle public float score() throws IOException {
92  317 int doc = ((Scorer) subScorers.get(0)).doc();
93  317 float[] sum = {((Scorer) subScorers.get(0)).score()}, max = {sum[0]};
94  317 int size = subScorers.size();
95  317 scoreAll(1, size, doc, sum, max);
96  317 scoreAll(2, size, doc, sum, max);
97  317 return max[0] + (sum[0] - max[0])*tieBreakerMultiplier;
98    }
99   
100    // Recursively iterate all subScorers that generated last doc computing sum and max
 
101  1028 toggle private void scoreAll(int root, int size, int doc, float[] sum, float[] max) throws IOException {
102  1028 if (root<size && ((Scorer) subScorers.get(root)).doc() == doc) {
103  197 float sub = ((Scorer) subScorers.get(root)).score();
104  197 sum[0] += sub;
105  197 max[0] = Math.max(max[0], sub);
106  197 scoreAll((root<<1)+1, size, doc, sum, max);
107  197 scoreAll((root<<1)+2, size, doc, sum, max);
108    }
109    }
110   
111    /** Advance to the first document beyond the current whose number is greater than or equal to target.
112    * @param target the minimum number of the next desired document
113    * @return true iff there is a document to be generated whose number is at least target
114    */