LUCENE-5292: remove code dup

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1533135 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2013-10-17 16:27:25 +00:00
parent 6614dee738
commit 8b47e1c575
4 changed files with 76 additions and 114 deletions

View File

@ -20,6 +20,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.lucene.index.AtomicReaderContext;
@ -154,17 +155,20 @@ public class DisjunctionMaxQuery extends Query implements Iterable<Query> {
@Override
public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder,
boolean topScorer, Bits acceptDocs) throws IOException {
Scorer[] scorers = new Scorer[weights.size()];
int idx = 0;
List<Scorer> scorers = new ArrayList<Scorer>();
for (Weight w : weights) {
// we will advance() subscorers
Scorer subScorer = w.scorer(context, true, false, acceptDocs);
if (subScorer != null) {
scorers[idx++] = subScorer;
scorers.add(subScorer);
}
}
if (idx == 0) return null; // all scorers did not have documents
DisjunctionMaxScorer result = new DisjunctionMaxScorer(this, tieBreakerMultiplier, scorers, idx);
if (scorers.isEmpty()) {
// no sub-scorers had any documents
return null;
}
DisjunctionMaxScorer result = new DisjunctionMaxScorer(this, tieBreakerMultiplier, scorers.toArray(new Scorer[scorers.size()]));
return result;
}

View File

@ -27,7 +27,6 @@ import java.io.IOException;
class DisjunctionMaxScorer extends DisjunctionScorer {
/* Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. */
private final float tieBreakerMultiplier;
private int doc = -1;
private int freq = -1;
/* Used when scoring currently matching doc. */
@ -44,40 +43,13 @@ class DisjunctionMaxScorer extends DisjunctionScorer {
* document as they are summed into the result.
* @param subScorers
* The sub scorers this Scorer should iterate on
* @param numScorers
* The actual number of scorers to iterate on. Note that the array's
* length may be larger than the actual number of scorers.
*/
public DisjunctionMaxScorer(Weight weight, float tieBreakerMultiplier,
Scorer[] subScorers, int numScorers) {
super(weight, subScorers, numScorers);
Scorer[] subScorers) {
super(weight, subScorers);
this.tieBreakerMultiplier = tieBreakerMultiplier;
}
@Override
public int nextDoc() throws IOException {
assert doc != NO_MORE_DOCS;
while(true) {
if (subScorers[0].nextDoc() != NO_MORE_DOCS) {
heapAdjust(0);
} else {
heapRemoveRoot();
if (numScorers == 0) {
return doc = NO_MORE_DOCS;
}
}
if (subScorers[0].docID() != doc) {
afterNext();
return doc;
}
}
}
@Override
public int docID() {
return doc;
}
/** Determine the current document score. Initially invalid, until {@link #nextDoc()} is called the first time.
* @return the score of the current generated document
*/
@ -86,7 +58,8 @@ class DisjunctionMaxScorer extends DisjunctionScorer {
return scoreMax + (scoreSum - scoreMax) * tieBreakerMultiplier;
}
private void afterNext() throws IOException {
@Override
protected void afterNext() throws IOException {
doc = subScorers[0].docID();
if (doc != NO_MORE_DOCS) {
scoreSum = scoreMax = subScorers[0].score();
@ -112,23 +85,4 @@ class DisjunctionMaxScorer extends DisjunctionScorer {
public int freq() throws IOException {
return freq;
}
@Override
public int advance(int target) throws IOException {
assert doc != NO_MORE_DOCS;
while(true) {
if (subScorers[0].advance(target) != NO_MORE_DOCS) {
heapAdjust(0);
} else {
heapRemoveRoot();
if (numScorers == 0) {
return doc = NO_MORE_DOCS;
}
}
if (subScorers[0].docID() >= target) {
afterNext();
return doc;
}
}
}
}

View File

@ -17,6 +17,7 @@ package org.apache.lucene.search;
* limitations under the License.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@ -26,12 +27,14 @@ import java.util.Collection;
*/
abstract class DisjunctionScorer extends Scorer {
protected final Scorer subScorers[];
/** The document number of the current match. */
protected int doc = -1;
protected int numScorers;
protected DisjunctionScorer(Weight weight, Scorer subScorers[], int numScorers) {
protected DisjunctionScorer(Weight weight, Scorer subScorers[]) {
super(weight);
this.subScorers = subScorers;
this.numScorers = numScorers;
this.numScorers = subScorers.length;
heapify();
}
@ -114,4 +117,59 @@ abstract class DisjunctionScorer extends Scorer {
}
return sum;
}
@Override
public int docID() {
return doc;
}
@Override
public int nextDoc() throws IOException {
assert doc != NO_MORE_DOCS;
while(true) {
if (subScorers[0].nextDoc() != NO_MORE_DOCS) {
heapAdjust(0);
} else {
heapRemoveRoot();
if (numScorers == 0) {
return doc = NO_MORE_DOCS;
}
}
if (subScorers[0].docID() != doc) {
afterNext();
return doc;
}
}
}
@Override
public int advance(int target) throws IOException {
assert doc != NO_MORE_DOCS;
while(true) {
if (subScorers[0].advance(target) != NO_MORE_DOCS) {
heapAdjust(0);
} else {
heapRemoveRoot();
if (numScorers == 0) {
return doc = NO_MORE_DOCS;
}
}
if (subScorers[0].docID() >= target) {
afterNext();
return doc;
}
}
}
/**
* Called after next() or advance() land on a new document.
* <p>
* {@code subScorers[0]} will be positioned to the new docid,
* which could be {@code NO_MORE_DOCS} (subclass must handle this).
* <p>
* implementations should assign {@code doc} appropriately, and do any
* other work necessary to implement {@code score()} and {@code freq()}
*/
// TODO: make this less horrible
protected abstract void afterNext() throws IOException;
}

View File

@ -23,8 +23,6 @@ import java.io.IOException;
* This Scorer implements {@link Scorer#advance(int)} and uses advance() on the given Scorers.
*/
class DisjunctionSumScorer extends DisjunctionScorer {
/** The document number of the current match. */
private int doc = -1;
/** The number of subscorers that provide the current match. */
protected int nrMatchers = -1;
@ -38,7 +36,7 @@ class DisjunctionSumScorer extends DisjunctionScorer {
* @param coord Table of coordination factors
*/
DisjunctionSumScorer(Weight weight, Scorer[] subScorers, float[] coord) throws IOException {
super(weight, subScorers, subScorers.length);
super(weight, subScorers);
if (numScorers <= 1) {
throw new IllegalArgumentException("There must be at least 2 subScorers");
@ -47,25 +45,7 @@ class DisjunctionSumScorer extends DisjunctionScorer {
}
@Override
public int nextDoc() throws IOException {
assert doc != NO_MORE_DOCS;
while(true) {
if (subScorers[0].nextDoc() != NO_MORE_DOCS) {
heapAdjust(0);
} else {
heapRemoveRoot();
if (numScorers == 0) {
return doc = NO_MORE_DOCS;
}
}
if (subScorers[0].docID() != doc) {
afterNext();
return doc;
}
}
}
private void afterNext() throws IOException {
protected void afterNext() throws IOException {
final Scorer sub = subScorers[0];
doc = sub.docID();
if (doc != NO_MORE_DOCS) {
@ -97,42 +77,8 @@ class DisjunctionSumScorer extends DisjunctionScorer {
return (float)score * coord[nrMatchers];
}
@Override
public int docID() {
return doc;
}
@Override
public int freq() throws IOException {
return nrMatchers;
}
/**
* Advances to the first match beyond the current whose document number is
* greater than or equal to a given target. <br>
* The implementation uses the advance() method on the subscorers.
*
* @param target
* The target document number.
* @return the document whose number is greater than or equal to the given
* target, or -1 if none exist.
*/
@Override
public int advance(int target) throws IOException {
assert doc != NO_MORE_DOCS;
while(true) {
if (subScorers[0].advance(target) != NO_MORE_DOCS) {
heapAdjust(0);
} else {
heapRemoveRoot();
if (numScorers == 0) {
return doc = NO_MORE_DOCS;
}
}
if (subScorers[0].docID() >= target) {
afterNext();
return doc;
}
}
}
}