blob: 9f8187476bce96b63cb5f41a726c4374e5380e0e [file] [log] [blame]
Index: src/java/org/apache/lucene/search/BooleanQuery.java
===================================================================
--- src/java/org/apache/lucene/search/BooleanQuery.java (revision 541956)
+++ src/java/org/apache/lucene/search/BooleanQuery.java (working copy)
@@ -219,40 +219,14 @@
}
}
- /** @return A good old 1.4 Scorer */
+ /** @return Returns BooleanScorer2 that uses and provides skipTo(),
+ * and scores documents in document number order.
+ */
public Scorer scorer(IndexReader reader) throws IOException {
- // First see if the (faster) ConjunctionScorer will work. This can be
- // used when all clauses are required. Also, at this point a
- // BooleanScorer cannot be embedded in a ConjunctionScorer, as the hits
- // from a BooleanScorer are not always sorted by document number (sigh)
- // and hence BooleanScorer cannot implement skipTo() correctly, which is
- // required by ConjunctionScorer.
- boolean allRequired = true;
- boolean noneBoolean = true;
- for (int i = 0 ; i < weights.size(); i++) {
- BooleanClause c = (BooleanClause)clauses.get(i);
- if (!c.isRequired())
- allRequired = false;
- if (c.getQuery() instanceof BooleanQuery)
- noneBoolean = false;
- }
+ BooleanScorer2 result = new BooleanScorer2(similarity,
+ minNrShouldMatch,
+ allowDocsOutOfOrder);
- if (allRequired && noneBoolean) { // ConjunctionScorer is okay
- ConjunctionScorer result =
- new ConjunctionScorer(similarity);
- for (int i = 0 ; i < weights.size(); i++) {
- Weight w = (Weight)weights.elementAt(i);
- Scorer subScorer = w.scorer(reader);
- if (subScorer == null)
- return null;
- result.add(subScorer);
- }
- return result;
- }
-
- // Use good-old BooleanScorer instead.
- BooleanScorer result = new BooleanScorer(similarity);
-
for (int i = 0 ; i < weights.size(); i++) {
BooleanClause c = (BooleanClause)clauses.get(i);
Weight w = (Weight)weights.elementAt(i);
@@ -335,54 +309,48 @@
}
}
- private class BooleanWeight2 extends BooleanWeight {
- /* Merge into BooleanWeight in case the 1.4 BooleanScorer is dropped */
- public BooleanWeight2(Searcher searcher)
- throws IOException {
- super(searcher);
- }
+ /** Whether hit docs may be collected out of docid order. */
+ private static boolean allowDocsOutOfOrder = false;
- /** @return An alternative Scorer that uses and provides skipTo(),
- * and scores documents in document number order.
- */
- public Scorer scorer(IndexReader reader) throws IOException {
- BooleanScorer2 result = new BooleanScorer2(similarity,
- minNrShouldMatch);
+ /**
+ * Indicates whether hit docs may be collected out of docid
+ * order. In other words, with this setting,
+ * {@link HitCollector#collect(int,float)} might be
+ * invoked first for docid N and only later for docid N-1.
+ * Being static, this setting is system wide.
+ * If docs out of order are allowed scoring might be faster
+ * for certain queries (disjunction queries with less than
+ * 32 prohibited terms). This setting has no effect for
+ * other queries.
+ */
+ public static void setAllowDocsOutOfOrder(boolean allow) {
+ allowDocsOutOfOrder = allow;
+ }
+
+ /**
+ * Whether hit docs may be collected out of docid order.
+ * @see #setAllowDocsOutOfOrder(boolean)
+ */
+ public static boolean getAllowDocsOutOfOrder() {
+ return allowDocsOutOfOrder;
+ }
- for (int i = 0 ; i < weights.size(); i++) {
- BooleanClause c = (BooleanClause)clauses.get(i);
- Weight w = (Weight)weights.elementAt(i);
- Scorer subScorer = w.scorer(reader);
- if (subScorer != null)
- result.add(subScorer, c.isRequired(), c.isProhibited());
- else if (c.isRequired())
- return null;
- }
-
- return result;
- }
- }
-
- /** Indicates whether to use good old 1.4 BooleanScorer. */
- private static boolean useScorer14 = false;
-
+ /**
+ * @deprecated Use {@link #setAllowDocsOutOfOrder(boolean)} instead.
+ */
public static void setUseScorer14(boolean use14) {
- useScorer14 = use14;
+ setAllowDocsOutOfOrder(use14);
}
-
+
+ /**
+ * @deprecated Use {@link #getAllowDocsOutOfOrder()} instead.
+ */
public static boolean getUseScorer14() {
- return useScorer14;
+ return getAllowDocsOutOfOrder();
}
protected Weight createWeight(Searcher searcher) throws IOException {
-
- if (0 < minNrShouldMatch) {
- // :TODO: should we throw an exception if getUseScorer14 ?
- return new BooleanWeight2(searcher);
- }
-
- return getUseScorer14() ? (Weight) new BooleanWeight(searcher)
- : (Weight) new BooleanWeight2(searcher);
+ return new BooleanWeight(searcher);
}
public Query rewrite(IndexReader reader) throws IOException {
Index: src/java/org/apache/lucene/search/BooleanScorer2.java
===================================================================
--- src/java/org/apache/lucene/search/BooleanScorer2.java (revision 541956)
+++ src/java/org/apache/lucene/search/BooleanScorer2.java (working copy)
@@ -32,7 +32,6 @@
private ArrayList optionalScorers = new ArrayList();
private ArrayList prohibitedScorers = new ArrayList();
-
private class Coordinator {
int maxCoord = 0; // to be increased for each non prohibited scorer
@@ -66,7 +65,13 @@
/** The number of optionalScorers that need to match (if there are any) */
private final int minNrShouldMatch;
+
+ /** Whether it is allowed to return documents out of order.
+ * This can accelerate the scoring of disjunction queries.
+ */
+ private boolean allowDocsOutOfOrder;
+
/** Create a BooleanScorer2.
* @param similarity The similarity to be used.
* @param minNrShouldMatch The minimum number of optional added scorers
@@ -74,23 +79,40 @@
* In case no required scorers are added,
* at least one of the optional scorers will have to
* match during the search.
+ * @param allowDocsOutOfOrder Whether it is allowed to return documents out of order.
+ * This can accelerate the scoring of disjunction queries.
*/
- public BooleanScorer2(Similarity similarity, int minNrShouldMatch) {
+ public BooleanScorer2(Similarity similarity, int minNrShouldMatch, boolean allowDocsOutOfOrder) {
super(similarity);
if (minNrShouldMatch < 0) {
throw new IllegalArgumentException("Minimum number of optional scorers should not be negative");
}
coordinator = new Coordinator();
this.minNrShouldMatch = minNrShouldMatch;
+ this.allowDocsOutOfOrder = allowDocsOutOfOrder;
}
/** Create a BooleanScorer2.
* In no required scorers are added,
* at least one of the optional scorers will have to match during the search.
* @param similarity The similarity to be used.
+ * @param minNrShouldMatch The minimum number of optional added scorers
+ * that should match during the search.
+ * In case no required scorers are added,
+ * at least one of the optional scorers will have to
+ * match during the search.
*/
+ public BooleanScorer2(Similarity similarity, int minNrShouldMatch) {
+ this(similarity, minNrShouldMatch, false);
+ }
+
+ /** Create a BooleanScorer2.
+ * In no required scorers are added,
+ * at least one of the optional scorers will have to match during the search.
+ * @param similarity The similarity to be used.
+ */
public BooleanScorer2(Similarity similarity) {
- this(similarity, 0);
+ this(similarity, 0, false);
}
public void add(final Scorer scorer, boolean required, boolean prohibited) {
@@ -285,8 +307,8 @@
* <br>When this method is used the {@link #explain(int)} method should not be used.
*/
public void score(HitCollector hc) throws IOException {
- if ((requiredScorers.size() == 0) &&
- prohibitedScorers.size() < 32) {
+ if (allowDocsOutOfOrder && requiredScorers.size() == 0
+ && prohibitedScorers.size() < 32) {
// fall back to BooleanScorer, scores documents somewhat out of order
BooleanScorer bs = new BooleanScorer(getSimilarity(), minNrShouldMatch);
Iterator si = optionalScorers.iterator();
Index: src/test/org/apache/lucene/search/QueryUtils.java
===================================================================
--- src/test/org/apache/lucene/search/QueryUtils.java (revision 541956)
+++ src/test/org/apache/lucene/search/QueryUtils.java (working copy)
@@ -85,7 +85,7 @@
public static void checkSkipTo(final Query q, final IndexSearcher s) throws IOException {
//System.out.println("Checking "+q);
- if (BooleanQuery.getUseScorer14()) return; // 1.4 doesn't support skipTo
+ if (BooleanQuery.getAllowDocsOutOfOrder()) return; // 1.4 doesn't support skipTo
final int skip_op = 0;
final int next_op = 1;
@@ -106,10 +106,6 @@
final Weight w = q.weight(s);
final Scorer scorer = w.scorer(s.getIndexReader());
- if (scorer instanceof BooleanScorer || scorer instanceof BooleanScorer2) {
- return; // TODO change this if BooleanScorers would once again guarantee docs in order.
- }
-
// FUTURE: ensure scorer.doc()==-1
final int[] sdoc = new int[] {-1};
Index: src/test/org/apache/lucene/search/TestBoolean2.java
===================================================================
--- src/test/org/apache/lucene/search/TestBoolean2.java (revision 541956)
+++ src/test/org/apache/lucene/search/TestBoolean2.java (working copy)
@@ -72,16 +72,16 @@
//System.out.println("Query: " + queryText);
try {
Query query1 = makeQuery(queryText);
- BooleanQuery.setUseScorer14(true);
+ BooleanQuery.setAllowDocsOutOfOrder(true);
Hits hits1 = searcher.search(query1);
Query query2 = makeQuery(queryText); // there should be no need to parse again...
- BooleanQuery.setUseScorer14(false);
+ BooleanQuery.setAllowDocsOutOfOrder(false);
Hits hits2 = searcher.search(query2);
CheckHits.checkHitsQuery(query2, hits1, hits2, expDocNrs);
} finally { // even when a test fails.
- BooleanQuery.setUseScorer14(false);
+ BooleanQuery.setAllowDocsOutOfOrder(false);
}
}
@@ -168,14 +168,14 @@
// match up.
Sort sort = Sort.INDEXORDER;
- BooleanQuery.setUseScorer14(false);
+ BooleanQuery.setAllowDocsOutOfOrder(false);
QueryUtils.check(q1,searcher);
Hits hits1 = searcher.search(q1,sort);
if (hits1.length()>0) hits1.id(hits1.length()-1);
- BooleanQuery.setUseScorer14(true);
+ BooleanQuery.setAllowDocsOutOfOrder(true);
Hits hits2 = searcher.search(q1,sort);
if (hits2.length()>0) hits2.id(hits1.length()-1);
tot+=hits2.length();
@@ -183,7 +183,7 @@
}
} finally { // even when a test fails.
- BooleanQuery.setUseScorer14(false);
+ BooleanQuery.setAllowDocsOutOfOrder(false);
}
// System.out.println("Total hits:"+tot);