diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
index 0e8b093b5e5..4faf7d2e886 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
@@ -261,7 +261,7 @@ public class MultiPhraseQuery extends Query {
if (scorer != null) {
int newDoc = scorer.advance(doc);
if (newDoc == doc) {
- float freq = slop == 0 ? scorer.freq() : ((SloppyPhraseScorer)scorer).freq;
+ float freq = slop == 0 ? scorer.freq() : ((SloppyPhraseScorer)scorer).sloppyFreq();
SloppySimScorer docScorer = similarity.sloppySimScorer(stats, context);
ComplexExplanation result = new ComplexExplanation();
result.setDescription("weight("+getQuery()+" in "+doc+") [" + similarity.getClass().getSimpleName() + "], result of:");
diff --git a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
index 2b13dcfe06a..223c5d723ef 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
@@ -303,7 +303,7 @@ public class PhraseQuery extends Query {
if (scorer != null) {
int newDoc = scorer.advance(doc);
if (newDoc == doc) {
- float freq = slop == 0 ? scorer.freq() : ((PhraseScorer)scorer).freq;
+ float freq = slop == 0 ? scorer.freq() : ((SloppyPhraseScorer)scorer).sloppyFreq();
SloppySimScorer docScorer = similarity.sloppySimScorer(stats, context);
ComplexExplanation result = new ComplexExplanation();
result.setDescription("weight("+getQuery()+" in "+doc+") [" + similarity.getClass().getSimpleName() + "], result of:");
diff --git a/lucene/core/src/java/org/apache/lucene/search/PhraseScorer.java b/lucene/core/src/java/org/apache/lucene/search/PhraseScorer.java
deleted file mode 100644
index c77feb1afda..00000000000
--- a/lucene/core/src/java/org/apache/lucene/search/PhraseScorer.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package org.apache.lucene.search;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-
-import org.apache.lucene.search.similarities.Similarity;
-
-/** Expert: Scoring functionality for phrase queries.
- *
A document is considered matching if it contains the phrase-query terms
- * at "valid" positions. What "valid positions" are
- * depends on the type of the phrase query: for an exact phrase query terms are required
- * to appear in adjacent locations, while for a sloppy phrase query some distance between
- * the terms is allowed. The abstract method {@link #phraseFreq()} of extending classes
- * is invoked for each document containing all the phrase query terms, in order to
- * compute the frequency of the phrase query in that document. A non zero frequency
- * means a match.
- */
-abstract class PhraseScorer extends Scorer {
- PhrasePositions min, max;
-
- protected float freq; //phrase frequency in current doc as computed by phraseFreq().
-
- final Similarity.SloppySimScorer docScorer;
-
- PhraseScorer(Weight weight, PhraseQuery.PostingsAndFreq[] postings,
- Similarity.SloppySimScorer docScorer) {
- super(weight);
- this.docScorer = docScorer;
-
- // convert tps to a list of phrase positions.
- // note: phrase-position differs from term-position in that its position
- // reflects the phrase offset: pp.pos = tp.pos - offset.
- // this allows to easily identify a matching (exact) phrase
- // when all PhrasePositions have exactly the same position.
- if (postings.length > 0) {
- min = new PhrasePositions(postings[0].postings, postings[0].position, 0, postings[0].terms);
- max = min;
- max.doc = -1;
- for (int i = 1; i < postings.length; i++) {
- PhrasePositions pp = new PhrasePositions(postings[i].postings, postings[i].position, i, postings[i].terms);
- max.next = pp;
- max = pp;
- max.doc = -1;
- }
- max.next = min; // make it cyclic for easier manipulation
- }
- }
-
- @Override
- public int docID() {
- return max.doc;
- }
-
- @Override
- public int nextDoc() throws IOException {
- return advance(max.doc);
- }
-
- @Override
- public float score() throws IOException {
- return docScorer.score(max.doc, freq);
- }
-
- private boolean advanceMin(int target) throws IOException {
- if (!min.skipTo(target)) {
- max.doc = NO_MORE_DOCS; // for further calls to docID()
- return false;
- }
- min = min.next; // cyclic
- max = max.next; // cyclic
- return true;
- }
-
- @Override
- public int advance(int target) throws IOException {
- freq = 0.0f;
- if (!advanceMin(target)) {
- return NO_MORE_DOCS;
- }
- boolean restart=false;
- while (freq == 0.0f) {
- while (min.doc < max.doc || restart) {
- restart = false;
- if (!advanceMin(max.doc)) {
- return NO_MORE_DOCS;
- }
- }
- // found a doc with all of the terms
- freq = phraseFreq(); // check for phrase
- restart = true;
- }
-
- // found a match
- return max.doc;
- }
-
- /**
- * For a document containing all the phrase query terms, compute the
- * frequency of the phrase in that document.
- * A non zero frequency means a match.
- *
Note, that containing all phrase terms does not guarantee a match - they have to be found in matching locations.
- * @return frequency of the phrase in current doc, 0 if not found.
- */
- abstract float phraseFreq() throws IOException;
-
- @Override
- public String toString() { return "scorer(" + weight + ")"; }
-
-}
diff --git a/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java b/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java
index af46873a905..f810af22267 100644
--- a/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java
@@ -29,7 +29,12 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.OpenBitSet;
-final class SloppyPhraseScorer extends PhraseScorer {
+final class SloppyPhraseScorer extends Scorer {
+ private PhrasePositions min, max;
+
+ private float sloppyFreq; //phrase frequency in current doc as computed by phraseFreq().
+
+ private final Similarity.SloppySimScorer docScorer;
private final int slop;
private final int numPostings;
@@ -47,10 +52,28 @@ final class SloppyPhraseScorer extends PhraseScorer {
SloppyPhraseScorer(Weight weight, PhraseQuery.PostingsAndFreq[] postings,
int slop, Similarity.SloppySimScorer docScorer) {
- super(weight, postings, docScorer);
+ super(weight);
+ this.docScorer = docScorer;
this.slop = slop;
this.numPostings = postings==null ? 0 : postings.length;
pq = new PhraseQueue(postings.length);
+ // convert tps to a list of phrase positions.
+ // note: phrase-position differs from term-position in that its position
+ // reflects the phrase offset: pp.pos = tp.pos - offset.
+ // this allows to easily identify a matching (exact) phrase
+ // when all PhrasePositions have exactly the same position.
+ if (postings.length > 0) {
+ min = new PhrasePositions(postings[0].postings, postings[0].position, 0, postings[0].terms);
+ max = min;
+ max.doc = -1;
+ for (int i = 1; i < postings.length; i++) {
+ PhrasePositions pp = new PhrasePositions(postings[i].postings, postings[i].position, i, postings[i].terms);
+ max.next = pp;
+ max = pp;
+ max.doc = -1;
+ }
+ max.next = min; // make it cyclic for easier manipulation
+ }
}
/**
@@ -71,8 +94,7 @@ final class SloppyPhraseScorer extends PhraseScorer {
* would get same score as "g f"~2, although "c b"~2 could be matched twice.
* We may want to fix this in the future (currently not, for performance reasons).
*/
- @Override
- protected float phraseFreq() throws IOException {
+ private float phraseFreq() throws IOException {
if (!initPhrasePositions()) {
return 0.0f;
}
@@ -489,10 +511,14 @@ final class SloppyPhraseScorer extends PhraseScorer {
}
@Override
- public int freq() throws IOException {
+ public int freq() {
return numMatches;
}
+ float sloppyFreq() {
+ return sloppyFreq;
+ }
+
// private void printQueue(PrintStream ps, PhrasePositions ext, String title) {
// //if (min.doc != ?) return;
// ps.println();
@@ -514,5 +540,54 @@ final class SloppyPhraseScorer extends PhraseScorer {
// }
// }
+ private boolean advanceMin(int target) throws IOException {
+ if (!min.skipTo(target)) {
+ max.doc = NO_MORE_DOCS; // for further calls to docID()
+ return false;
+ }
+ min = min.next; // cyclic
+ max = max.next; // cyclic
+ return true;
+ }
+ @Override
+ public int docID() {
+ return max.doc;
+ }
+
+ @Override
+ public int nextDoc() throws IOException {
+ return advance(max.doc);
+ }
+
+ @Override
+ public float score() {
+ return docScorer.score(max.doc, sloppyFreq);
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ sloppyFreq = 0.0f;
+ if (!advanceMin(target)) {
+ return NO_MORE_DOCS;
+ }
+ boolean restart=false;
+ while (sloppyFreq == 0.0f) {
+ while (min.doc < max.doc || restart) {
+ restart = false;
+ if (!advanceMin(max.doc)) {
+ return NO_MORE_DOCS;
+ }
+ }
+ // found a doc with all of the terms
+ sloppyFreq = phraseFreq(); // check for phrase
+ restart = true;
+ }
+
+ // found a match
+ return max.doc;
+ }
+
+ @Override
+ public String toString() { return "scorer(" + weight + ")"; }
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java
index 327ec0488d1..80d9c469d7e 100644
--- a/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java
+++ b/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java
@@ -189,25 +189,6 @@ final class JustCompileSearch {
}
- static final class JustCompilePhraseScorer extends PhraseScorer {
-
- JustCompilePhraseScorer(Weight weight, PhraseQuery.PostingsAndFreq[] postings,
- Similarity.SloppySimScorer docScorer) {
- super(weight, postings, docScorer);
- }
-
- @Override
- protected float phraseFreq() {
- throw new UnsupportedOperationException(UNSUPPORTED_MSG);
- }
-
- @Override
- public int freq() throws IOException {
- throw new UnsupportedOperationException(UNSUPPORTED_MSG);
- }
-
- }
-
static final class JustCompileQuery extends Query {
@Override