From 8b47e1c575c5d1dbc291e851904f52d464dc0545 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Thu, 17 Oct 2013 16:27:25 +0000 Subject: [PATCH] LUCENE-5292: remove code dup git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1533135 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/search/DisjunctionMaxQuery.java | 14 +++-- .../lucene/search/DisjunctionMaxScorer.java | 54 ++-------------- .../lucene/search/DisjunctionScorer.java | 62 ++++++++++++++++++- .../lucene/search/DisjunctionSumScorer.java | 60 +----------------- 4 files changed, 76 insertions(+), 114 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java index 16645f03950..f61a54fd513 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java @@ -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 { @Override public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer, Bits acceptDocs) throws IOException { - Scorer[] scorers = new Scorer[weights.size()]; - int idx = 0; + List scorers = new ArrayList(); 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; } diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java index f7f885f1d7d..205e78e3242 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java @@ -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; - } - } - } } diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java index e711b508411..05522dd5594 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java @@ -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. + *

+ * {@code subScorers[0]} will be positioned to the new docid, + * which could be {@code NO_MORE_DOCS} (subclass must handle this). + *

+ * 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; } diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java index a37251a908d..49a06757287 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java @@ -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,34 +36,16 @@ 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"); } this.coord = coord; } - - @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 { + @Override + protected void afterNext() throws IOException { final Scorer sub = subScorers[0]; doc = sub.docID(); if (doc != NO_MORE_DOCS) { @@ -96,43 +76,9 @@ class DisjunctionSumScorer extends DisjunctionScorer { public float score() throws IOException { 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.
- * 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; - } - } - } }