|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DisjunctionMaxScorer | Line # 29 | 80 | 32 | 92.2% |
0.92248064
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (20) | |||
| Result | |||
|
0.9147287
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleEqualScores3
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleEqualScores3
|
1 PASS | |
|
0.8604651
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanRequiredEqualScores
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanRequiredEqualScores
|
1 PASS | |
|
0.8604651
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ1
org.apache.lucene.search.TestSimpleExplanations.testDMQ1
|
1 PASS | |
|
0.8604651
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleEqualScores1
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleEqualScores1
|
1 PASS | |
|
0.8604651
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ7
org.apache.lucene.search.TestSimpleExplanations.testDMQ7
|
1 PASS | |
|
0.8604651
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ2
org.apache.lucene.search.TestSimpleExplanations.testDMQ2
|
1 PASS | |
|
0.82945734
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ5
org.apache.lucene.search.TestSimpleExplanations.testDMQ5
|
1 PASS | |
|
0.82945734
|
org.apache.lucene.search.TestComplexExplanations.testDMQ10
org.apache.lucene.search.TestComplexExplanations.testDMQ10
|
1 PASS | |
|
0.82945734
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ9
org.apache.lucene.search.TestSimpleExplanations.testDMQ9
|
1 PASS | |
|
0.82945734
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleEqualScores2
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleEqualScores2
|
1 PASS | |
|
0.82945734
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleTiebreaker
org.apache.lucene.search.TestDisjunctionMaxQuery.testSimpleTiebreaker
|
1 PASS | |
|
0.82945734
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ8
org.apache.lucene.search.TestSimpleExplanations.testDMQ8
|
1 PASS | |
|
0.7596899
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ6
org.apache.lucene.search.TestSimpleExplanations.testDMQ6
|
1 PASS | |
|
0.7209302
|
org.apache.lucene.search.TestComplexExplanations.test1
org.apache.lucene.search.TestComplexExplanations.test1
|
1 PASS | |
|
0.7209302
|
org.apache.lucene.search.TestComplexExplanations.test2
org.apache.lucene.search.TestComplexExplanations.test2
|
1 PASS | |
|
0.68992245
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanOptionalWithTiebreaker
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanOptionalWithTiebreaker
|
1 PASS | |
|
0.68992245
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanOptionalWithTiebreakerAndBoost
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanOptionalWithTiebreakerAndBoost
|
1 PASS | |
|
0.68992245
|
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanOptionalNoTiebreaker
org.apache.lucene.search.TestDisjunctionMaxQuery.testBooleanOptionalNoTiebreaker
|
1 PASS | |
|
0.5813953
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ4
org.apache.lucene.search.TestSimpleExplanations.testDMQ4
|
1 PASS | |
|
0.503876
|
org.apache.lucene.search.TestSimpleExplanations.testDMQ3
org.apache.lucene.search.TestSimpleExplanations.testDMQ3
|
1 PASS | |
| 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 |
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 |
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 |
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 |
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 |
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 |
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 | */ | |