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

View File

@ -27,7 +27,6 @@ import java.io.IOException;
class DisjunctionMaxScorer extends DisjunctionScorer { class DisjunctionMaxScorer extends DisjunctionScorer {
/* Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. */ /* Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. */
private final float tieBreakerMultiplier; private final float tieBreakerMultiplier;
private int doc = -1;
private int freq = -1; private int freq = -1;
/* Used when scoring currently matching doc. */ /* Used when scoring currently matching doc. */
@ -44,40 +43,13 @@ class DisjunctionMaxScorer extends DisjunctionScorer {
* document as they are summed into the result. * document as they are summed into the result.
* @param subScorers * @param subScorers
* The sub scorers this Scorer should iterate on * 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, public DisjunctionMaxScorer(Weight weight, float tieBreakerMultiplier,
Scorer[] subScorers, int numScorers) { Scorer[] subScorers) {
super(weight, subScorers, numScorers); super(weight, subScorers);
this.tieBreakerMultiplier = tieBreakerMultiplier; 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. /** Determine the current document score. Initially invalid, until {@link #nextDoc()} is called the first time.
* @return the score of the current generated document * @return the score of the current generated document
*/ */
@ -86,7 +58,8 @@ class DisjunctionMaxScorer extends DisjunctionScorer {
return scoreMax + (scoreSum - scoreMax) * tieBreakerMultiplier; return scoreMax + (scoreSum - scoreMax) * tieBreakerMultiplier;
} }
private void afterNext() throws IOException { @Override
protected void afterNext() throws IOException {
doc = subScorers[0].docID(); doc = subScorers[0].docID();
if (doc != NO_MORE_DOCS) { if (doc != NO_MORE_DOCS) {
scoreSum = scoreMax = subScorers[0].score(); scoreSum = scoreMax = subScorers[0].score();
@ -112,23 +85,4 @@ class DisjunctionMaxScorer extends DisjunctionScorer {
public int freq() throws IOException { public int freq() throws IOException {
return freq; 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. * limitations under the License.
*/ */
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -26,12 +27,14 @@ import java.util.Collection;
*/ */
abstract class DisjunctionScorer extends Scorer { abstract class DisjunctionScorer extends Scorer {
protected final Scorer subScorers[]; protected final Scorer subScorers[];
/** The document number of the current match. */
protected int doc = -1;
protected int numScorers; protected int numScorers;
protected DisjunctionScorer(Weight weight, Scorer subScorers[], int numScorers) { protected DisjunctionScorer(Weight weight, Scorer subScorers[]) {
super(weight); super(weight);
this.subScorers = subScorers; this.subScorers = subScorers;
this.numScorers = numScorers; this.numScorers = subScorers.length;
heapify(); heapify();
} }
@ -114,4 +117,59 @@ abstract class DisjunctionScorer extends Scorer {
} }
return sum; 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. * This Scorer implements {@link Scorer#advance(int)} and uses advance() on the given Scorers.
*/ */
class DisjunctionSumScorer extends DisjunctionScorer { class DisjunctionSumScorer extends DisjunctionScorer {
/** The document number of the current match. */
private int doc = -1;
/** The number of subscorers that provide the current match. */ /** The number of subscorers that provide the current match. */
protected int nrMatchers = -1; protected int nrMatchers = -1;
@ -38,7 +36,7 @@ class DisjunctionSumScorer extends DisjunctionScorer {
* @param coord Table of coordination factors * @param coord Table of coordination factors
*/ */
DisjunctionSumScorer(Weight weight, Scorer[] subScorers, float[] coord) throws IOException { DisjunctionSumScorer(Weight weight, Scorer[] subScorers, float[] coord) throws IOException {
super(weight, subScorers, subScorers.length); super(weight, subScorers);
if (numScorers <= 1) { if (numScorers <= 1) {
throw new IllegalArgumentException("There must be at least 2 subScorers"); throw new IllegalArgumentException("There must be at least 2 subScorers");
@ -47,25 +45,7 @@ class DisjunctionSumScorer extends DisjunctionScorer {
} }
@Override @Override
public int nextDoc() throws IOException { protected void afterNext() 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 {
final Scorer sub = subScorers[0]; final Scorer sub = subScorers[0];
doc = sub.docID(); doc = sub.docID();
if (doc != NO_MORE_DOCS) { if (doc != NO_MORE_DOCS) {
@ -97,42 +77,8 @@ class DisjunctionSumScorer extends DisjunctionScorer {
return (float)score * coord[nrMatchers]; return (float)score * coord[nrMatchers];
} }
@Override
public int docID() {
return doc;
}
@Override @Override
public int freq() throws IOException { public int freq() throws IOException {
return nrMatchers; 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;
}
}
}
} }