blob: b59af6af82a3bbc0eb8521df913e5990c2e098ab [file] [log] [blame]
Index: src/java/org/apache/lucene/search/BitSetFilter.java
===================================================================
--- src/java/org/apache/lucene/search/BitSetFilter.java (revision 0)
+++ src/java/org/apache/lucene/search/BitSetFilter.java (revision 0)
@@ -0,0 +1,43 @@
+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 java.util.BitSet;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.util.DocIdBitSet;
+
+/**
+ * Filter that uses a BitSet.
+ */
+public abstract class BitSetFilter extends Filter {
+ /**
+ * @return A BitSet with true for documents which should be permitted in
+ * search results, and false for those that should not.
+ */
+ public abstract BitSet bits(IndexReader reader) throws IOException;
+
+ /**
+ * @return a {@link DocIdBitSet} that wraps a BitSet obtained from {@link #bits(IndexReader)}
+ * and provides a {@link DocIdBitSetIterator}
+ */
+ public final DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ return new DocIdBitSet(bits(reader));
+ }
+}
Property changes on: src\java\org\apache\lucene\search\BitSetFilter.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/java/org/apache/lucene/search/CachingSpanFilter.java
===================================================================
--- src/java/org/apache/lucene/search/CachingSpanFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/CachingSpanFilter.java (working copy)
@@ -43,11 +43,19 @@
this.filter = filter;
}
+ /**
+ * @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
+ */
public BitSet bits(IndexReader reader) throws IOException {
SpanFilterResult result = getCachedResult(reader);
return result != null ? result.getBits() : null;
}
-
+
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ SpanFilterResult result = getCachedResult(reader);
+ return result != null ? result.getDocIdSet() : null;
+ }
+
private SpanFilterResult getCachedResult(IndexReader reader) throws IOException {
SpanFilterResult result = null;
if (cache == null) {
Index: src/java/org/apache/lucene/search/CachingWrapperFilter.java
===================================================================
--- src/java/org/apache/lucene/search/CachingWrapperFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/CachingWrapperFilter.java (working copy)
@@ -43,6 +43,9 @@
this.filter = filter;
}
+ /**
+ * @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
+ */
public BitSet bits(IndexReader reader) throws IOException {
if (cache == null) {
cache = new WeakHashMap();
@@ -63,7 +66,29 @@
return bits;
}
+
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ if (cache == null) {
+ cache = new WeakHashMap();
+ }
+ synchronized (cache) { // check cache
+ DocIdSet cached = (DocIdSet) cache.get(reader);
+ if (cached != null) {
+ return cached;
+ }
+ }
+
+ final DocIdSet docIdSet = filter.getDocIdSet(reader);
+
+ synchronized (cache) { // update cache
+ cache.put(reader, docIdSet);
+ }
+
+ return docIdSet;
+
+ }
+
public String toString() {
return "CachingWrapperFilter("+filter+")";
}
Index: src/java/org/apache/lucene/search/ConstantScoreQuery.java
===================================================================
--- src/java/org/apache/lucene/search/ConstantScoreQuery.java (revision 610038)
+++ src/java/org/apache/lucene/search/ConstantScoreQuery.java (working copy)
@@ -85,7 +85,7 @@
public Explanation explain(IndexReader reader, int doc) throws IOException {
ConstantScorer cs = (ConstantScorer)scorer(reader);
- boolean exists = cs.bits.get(doc);
+ boolean exists = cs.docIdSetIterator.skipTo(doc) && (cs.docIdSetIterator.doc() == doc);
ComplexExplanation result = new ComplexExplanation();
@@ -107,23 +107,22 @@
}
protected class ConstantScorer extends Scorer {
- final BitSet bits;
+ final DocIdSetIterator docIdSetIterator;
final float theScore;
int doc=-1;
public ConstantScorer(Similarity similarity, IndexReader reader, Weight w) throws IOException {
super(similarity);
theScore = w.getValue();
- bits = filter.bits(reader);
+ docIdSetIterator = filter.getDocIdSet(reader).iterator();
}
public boolean next() throws IOException {
- doc = bits.nextSetBit(doc+1);
- return doc >= 0;
+ return docIdSetIterator.next();
}
public int doc() {
- return doc;
+ return docIdSetIterator.doc();
}
public float score() throws IOException {
@@ -131,8 +130,7 @@
}
public boolean skipTo(int target) throws IOException {
- doc = bits.nextSetBit(target); // requires JDK 1.4
- return doc >= 0;
+ return docIdSetIterator.skipTo(target);
}
public Explanation explain(int doc) throws IOException {
Index: src/java/org/apache/lucene/search/DocIdSet.java
===================================================================
--- src/java/org/apache/lucene/search/DocIdSet.java (revision 0)
+++ src/java/org/apache/lucene/search/DocIdSet.java (revision 0)
@@ -0,0 +1,27 @@
+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.
+ */
+
+
+/**
+ * A DocIdSet contains a set of doc ids. Implementing classes must provide
+ * a {@link DocIdSetIterator} to access the set.
+ */
+public abstract class DocIdSet {
+ public abstract DocIdSetIterator iterator();
+}
Property changes on: src\java\org\apache\lucene\search\DocIdSet.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/java/org/apache/lucene/search/DocIdSetIterator.java
===================================================================
--- src/java/org/apache/lucene/search/DocIdSetIterator.java (revision 0)
+++ src/java/org/apache/lucene/search/DocIdSetIterator.java (revision 0)
@@ -0,0 +1,49 @@
+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;
+
+/**
+ * This abstract class defines methods to iterate over a set of
+ * non-decreasing doc ids.
+ */
+public abstract class DocIdSetIterator {
+ /** Returns the current document number. <p> This is invalid until {@link
+ #next()} is called for the first time.*/
+ public abstract int doc();
+
+ /** Moves to the next docId in the set. Returns true, iff
+ * there is such a docId. */
+ public abstract boolean next() throws IOException;
+
+ /** Skips entries to the first beyond the current whose document number is
+ * greater than or equal to <i>target</i>. <p>Returns true iff there is such
+ * an entry. <p>Behaves as if written: <pre>
+ * boolean skipTo(int target) {
+ * do {
+ * if (!next())
+ * return false;
+ * } while (target > doc());
+ * return true;
+ * }
+ * </pre>
+ * Some implementations are considerably more efficient than that.
+ */
+ public abstract boolean skipTo(int target) throws IOException;
+}
Property changes on: src\java\org\apache\lucene\search\DocIdSetIterator.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/java/org/apache/lucene/search/Filter.java
===================================================================
--- src/java/org/apache/lucene/search/Filter.java (revision 610038)
+++ src/java/org/apache/lucene/search/Filter.java (working copy)
@@ -20,11 +20,32 @@
import java.util.BitSet;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.util.DocIdBitSet;
-/** Abstract base class providing a mechanism to restrict searches to a subset
- of an index. */
+/** Abstract base class providing a mechanism to use a subset of an index
+ * for restriction or permission of index search results.
+ * <p>
+ * <b>Note:</b> In Lucene 3.0 {@link #bits(IndexReader)} will be removed
+ * and {@link #getDocIdSet(IndexReader)} will be defined as abstract.
+ * All implementing classes must therefore implement {@link #getDocIdSet(IndexReader)}
+ * in order to work with Lucene 3.0.
+ */
public abstract class Filter implements java.io.Serializable {
- /** Returns a BitSet with true for documents which should be permitted in
- search results, and false for those that should not. */
- public abstract BitSet bits(IndexReader reader) throws IOException;
+ /**
+ * @return A BitSet with true for documents which should be permitted in
+ * search results, and false for those that should not.
+ * @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
+ */
+ public BitSet bits(IndexReader reader) throws IOException {
+ return null;
+ }
+
+ /**
+ * @return a DocIdSet that provides the documents which should be
+ * permitted or prohibited in search results.
+ * @see DocIdBitSet
+ */
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ return new DocIdBitSet(bits(reader));
+ }
}
Index: src/java/org/apache/lucene/search/FilteredQuery.java
===================================================================
--- src/java/org/apache/lucene/search/FilteredQuery.java (revision 610038)
+++ src/java/org/apache/lucene/search/FilteredQuery.java (working copy)
@@ -21,7 +21,6 @@
import org.apache.lucene.util.ToStringUtils;
import java.io.IOException;
-import java.util.BitSet;
import java.util.Set;
@@ -47,7 +46,7 @@
/**
* Constructs a new query which applies a filter to the results of the original query.
- * Filter.bits() will be called every time this query is used in a search.
+ * Filter.getDocIdSet() will be called every time this query is used in a search.
* @param query Query to be filtered, cannot be <code>null</code>.
* @param filter Filter to apply to query results, cannot be <code>null</code>.
*/
@@ -86,13 +85,15 @@
inner.addDetail(preBoost);
}
Filter f = FilteredQuery.this.filter;
- BitSet matches = f.bits(ir);
- if (matches.get(i))
+ DocIdSetIterator docIdSetIterator = f.getDocIdSet(ir).iterator();
+ if (docIdSetIterator.skipTo(i) && (docIdSetIterator.doc() == i)) {
return inner;
- Explanation result = new Explanation
- (0.0f, "failure to match filter: " + f.toString());
- result.addDetail(inner);
- return result;
+ } else {
+ Explanation result = new Explanation
+ (0.0f, "failure to match filter: " + f.toString());
+ result.addDetail(inner);
+ return result;
+ }
}
// return this query
@@ -100,50 +101,49 @@
// return a filtering scorer
public Scorer scorer (IndexReader indexReader) throws IOException {
- final Scorer scorer = weight.scorer (indexReader);
- final BitSet bitset = filter.bits (indexReader);
- return new Scorer (similarity) {
+ final Scorer scorer = weight.scorer(indexReader);
+ final DocIdSetIterator docIdSetIterator = filter.getDocIdSet(indexReader).iterator();
- public boolean next() throws IOException {
- do {
- if (! scorer.next()) {
+ return new Scorer(similarity) {
+
+ private boolean advanceToCommon() throws IOException {
+ while (scorer.doc() != docIdSetIterator.doc()) {
+ if (scorer.doc() < docIdSetIterator.doc()) {
+ if (!scorer.skipTo(docIdSetIterator.doc())) {
+ return false;
+ }
+ } else if (!docIdSetIterator.skipTo(scorer.doc())) {
return false;
}
- } while (! bitset.get(scorer.doc()));
- /* When skipTo() is allowed on scorer it should be used here
- * in combination with bitset.nextSetBit(...)
- * See the while loop in skipTo() below.
- */
+ }
return true;
}
+
+ public boolean next() throws IOException {
+ return docIdSetIterator.next() && scorer.next() && advanceToCommon();
+ }
+
public int doc() { return scorer.doc(); }
public boolean skipTo(int i) throws IOException {
- if (! scorer.skipTo(i)) {
- return false;
- }
- while (! bitset.get(scorer.doc())) {
- int nextFiltered = bitset.nextSetBit(scorer.doc() + 1);
- if (nextFiltered == -1) {
- return false;
- } else if (! scorer.skipTo(nextFiltered)) {
- return false;
- }
- }
- return true;
- }
+ return docIdSetIterator.skipTo(i)
+ && scorer.skipTo(docIdSetIterator.doc())
+ && advanceToCommon();
+ }
public float score() throws IOException { return getBoost() * scorer.score(); }
// add an explanation about whether the document was filtered
public Explanation explain (int i) throws IOException {
- Explanation exp = scorer.explain (i);
- exp.setValue(getBoost() * exp.getValue());
+ Explanation exp = scorer.explain(i);
- if (bitset.get(i))
+ if (docIdSetIterator.skipTo(i) && (docIdSetIterator.doc() == i)) {
exp.setDescription ("allowed by filter: "+exp.getDescription());
- else
+ exp.setValue(getBoost() * exp.getValue());
+ } else {
exp.setDescription ("removed by filter: "+exp.getDescription());
+ exp.setValue(0.0f);
+ }
return exp;
}
};
Index: src/java/org/apache/lucene/search/IndexSearcher.java
===================================================================
--- src/java/org/apache/lucene/search/IndexSearcher.java (revision 610038)
+++ src/java/org/apache/lucene/search/IndexSearcher.java (working copy)
@@ -128,22 +128,33 @@
// inherit javadoc
public void search(Weight weight, Filter filter,
final HitCollector results) throws IOException {
- HitCollector collector = results;
- if (filter != null) {
- final BitSet bits = filter.bits(reader);
- collector = new HitCollector() {
- public final void collect(int doc, float score) {
- if (bits.get(doc)) { // skip docs not in bits
- results.collect(doc, score);
- }
- }
- };
- }
Scorer scorer = weight.scorer(reader);
if (scorer == null)
return;
- scorer.score(collector);
+
+ if (filter == null) {
+ scorer.score(results);
+ return;
+ }
+
+ DocIdSetIterator docIdSetIterator = filter.getDocIdSet(reader).iterator(); // CHECKME: use ConjunctionScorer here?
+ boolean more = docIdSetIterator.next();
+ while (more) {
+ int filterDocId = docIdSetIterator.doc();
+ if (! scorer.skipTo(filterDocId)) {
+ more = false;
+ } else {
+ int scorerDocId = scorer.doc();
+ if (scorerDocId == filterDocId) { // permitted by filter
+ results.collect(scorerDocId, scorer.score());
+ more = docIdSetIterator.skipTo(scorerDocId + 1);
+ } else {
+ more = docIdSetIterator.skipTo(scorerDocId);
+ }
+ }
+ }
+
}
public Query rewrite(Query original) throws IOException {
Index: src/java/org/apache/lucene/search/PrefixFilter.java
===================================================================
--- src/java/org/apache/lucene/search/PrefixFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/PrefixFilter.java (working copy)
@@ -18,6 +18,7 @@
*/
import org.apache.lucene.search.Filter;
+import org.apache.lucene.util.OpenBitSet;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.TermEnum;
@@ -39,6 +40,9 @@
public Term getPrefix() { return prefix; }
+ /**
+ * @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
+ */
public BitSet bits(IndexReader reader) throws IOException {
final BitSet bitSet = new BitSet(reader.maxDoc());
new PrefixGenerator(prefix) {
@@ -48,6 +52,16 @@
}.generate(reader);
return bitSet;
}
+
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ final OpenBitSet bitSet = new OpenBitSet(reader.maxDoc());
+ new PrefixGenerator(prefix) {
+ public void handleDoc(int doc) {
+ bitSet.set(doc);
+ }
+ }.generate(reader);
+ return bitSet;
+ }
/** Prints a user-readable version of this query. */
public String toString () {
Index: src/java/org/apache/lucene/search/QueryWrapperFilter.java
===================================================================
--- src/java/org/apache/lucene/search/QueryWrapperFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/QueryWrapperFilter.java (working copy)
@@ -21,6 +21,7 @@
import java.util.BitSet;
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.util.OpenBitSet;
/**
* Constrains search results to only match those which also match a provided
@@ -44,6 +45,9 @@
this.query = query;
}
+ /**
+ * @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
+ */
public BitSet bits(IndexReader reader) throws IOException {
final BitSet bits = new BitSet(reader.maxDoc());
@@ -54,7 +58,18 @@
});
return bits;
}
+
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ final OpenBitSet bits = new OpenBitSet(reader.maxDoc());
+ new IndexSearcher(reader).search(query, new HitCollector() {
+ public final void collect(int doc, float score) {
+ bits.set(doc); // set bit for hit
+ }
+ });
+ return bits;
+ }
+
public String toString() {
return "QueryWrapperFilter(" + query + ")";
}
Index: src/java/org/apache/lucene/search/RangeFilter.java
===================================================================
--- src/java/org/apache/lucene/search/RangeFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/RangeFilter.java (working copy)
@@ -21,6 +21,7 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.util.OpenBitSet;
import java.io.IOException;
import java.util.BitSet;
@@ -94,6 +95,7 @@
* Returns a BitSet with true for documents which should be
* permitted in search results, and false for those that should
* not.
+ * @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
*/
public BitSet bits(IndexReader reader) throws IOException {
BitSet bits = new BitSet(reader.maxDoc());
@@ -152,6 +154,69 @@
return bits;
}
+ /**
+ * Returns a BitSet with true for documents which should be
+ * permitted in search results, and false for those that should
+ * not.
+ */
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ OpenBitSet bits = new OpenBitSet(reader.maxDoc());
+
+ TermEnum enumerator =
+ (null != lowerTerm
+ ? reader.terms(new Term(fieldName, lowerTerm))
+ : reader.terms(new Term(fieldName,"")));
+
+ try {
+
+ if (enumerator.term() == null) {
+ return bits;
+ }
+
+ boolean checkLower = false;
+ if (!includeLower) // make adjustments to set to exclusive
+ checkLower = true;
+
+ TermDocs termDocs = reader.termDocs();
+ try {
+
+ do {
+ Term term = enumerator.term();
+ if (term != null && term.field().equals(fieldName)) {
+ if (!checkLower || null==lowerTerm || term.text().compareTo(lowerTerm) > 0) {
+ checkLower = false;
+ if (upperTerm != null) {
+ int compare = upperTerm.compareTo(term.text());
+ /* if beyond the upper term, or is exclusive and
+ * this is equal to the upper term, break out */
+ if ((compare < 0) ||
+ (!includeUpper && compare==0)) {
+ break;
+ }
+ }
+ /* we have a good term, find the docs */
+
+ termDocs.seek(enumerator.term());
+ while (termDocs.next()) {
+ bits.set(termDocs.doc());
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ while (enumerator.next());
+
+ } finally {
+ termDocs.close();
+ }
+ } finally {
+ enumerator.close();
+ }
+
+ return bits;
+ }
+
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(fieldName);
Index: src/java/org/apache/lucene/search/RemoteCachingWrapperFilter.java
===================================================================
--- src/java/org/apache/lucene/search/RemoteCachingWrapperFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/RemoteCachingWrapperFilter.java (working copy)
@@ -50,9 +50,21 @@
* searcher side of a remote connection.
* @param reader the index reader for the Filter
* @return the bitset
+ * @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
*/
public BitSet bits(IndexReader reader) throws IOException {
Filter cachedFilter = FilterManager.getInstance().getFilter(filter);
return cachedFilter.bits(reader);
}
+
+ /**
+ * Uses the {@link FilterManager} to keep the cache for a filter on the
+ * searcher side of a remote connection.
+ * @param reader the index reader for the Filter
+ * @return the DocIdSet
+ */
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+ Filter cachedFilter = FilterManager.getInstance().getFilter(filter);
+ return cachedFilter.getDocIdSet(reader);
+ }
}
Index: src/java/org/apache/lucene/search/Scorer.java
===================================================================
--- src/java/org/apache/lucene/search/Scorer.java (revision 610038)
+++ src/java/org/apache/lucene/search/Scorer.java (working copy)
@@ -33,7 +33,7 @@
* </p>
* @see BooleanQuery#setAllowDocsOutOfOrder
*/
-public abstract class Scorer {
+public abstract class Scorer extends DocIdSetIterator {
private Similarity similarity;
/** Constructs a Scorer.
@@ -76,65 +76,12 @@
return true;
}
- /**
- * Advances to the document matching this Scorer with the lowest doc Id
- * greater than the current value of {@link #doc()} (or to the matching
- * document with the lowest doc Id if next has never been called on
- * this Scorer).
- *
- * <p>
- * When this method is used the {@link #explain(int)} method should not
- * be used.
- * </p>
- *
- * @return true iff there is another document matching the query.
- * @see BooleanQuery#setAllowDocsOutOfOrder
- */
- public abstract boolean next() throws IOException;
-
- /** Returns the current document number matching the query.
- * Initially invalid, until {@link #next()} is called the first time.
- */
- public abstract int doc();
-
/** Returns the score of the current document matching the query.
* Initially invalid, until {@link #next()} or {@link #skipTo(int)}
* is called the first time.
*/
public abstract float score() throws IOException;
- /**
- * Skips to the document matching this Scorer with the lowest doc Id
- * greater than or equal to a given target.
- *
- * <p>
- * The behavior of this method is undefined if the target specified is
- * less than or equal to the current value of {@link #doc()}.
- * <p>
- * Behaves as if written:
- * <pre>
- * boolean skipTo(int target) {
- * do {
- * if (!next())
- * return false;
- * } while (target > doc());
- * return true;
- * }
- * </pre>
- * Most implementations are considerably more efficient than that.
- * </p>
- *
- * <p>
- * When this method is used the {@link #explain(int)} method should not
- * be used.
- * </p>
- *
- * @param target The target document number.
- * @return true iff there is such a match.
- * @see BooleanQuery#setAllowDocsOutOfOrder
- */
- public abstract boolean skipTo(int target) throws IOException;
-
/** Returns an explanation of the score for a document.
* <br>When this method is used, the {@link #next()}, {@link #skipTo(int)} and
* {@link #score(HitCollector)} methods should not be used.
Index: src/java/org/apache/lucene/search/Searchable.java
===================================================================
--- src/java/org/apache/lucene/search/Searchable.java (revision 610038)
+++ src/java/org/apache/lucene/search/Searchable.java (working copy)
@@ -48,7 +48,7 @@
* non-high-scoring hits.
*
* @param weight to match documents
- * @param filter if non-null, a bitset used to eliminate some documents
+ * @param filter if non-null, used to permit documents to be collected.
* @param results to receive hits
* @throws BooleanQuery.TooManyClauses
*/
Index: src/java/org/apache/lucene/search/Searcher.java
===================================================================
--- src/java/org/apache/lucene/search/Searcher.java (revision 610038)
+++ src/java/org/apache/lucene/search/Searcher.java (working copy)
@@ -109,7 +109,7 @@
* non-high-scoring hits.
*
* @param query to match documents
- * @param filter if non-null, a bitset used to eliminate some documents
+ * @param filter if non-null, used to permit documents to be collected.
* @param results to receive hits
* @throws BooleanQuery.TooManyClauses
*/
Index: src/java/org/apache/lucene/search/SpanFilter.java
===================================================================
--- src/java/org/apache/lucene/search/SpanFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/SpanFilter.java (working copy)
@@ -30,7 +30,7 @@
public abstract class SpanFilter extends Filter{
/** Returns a SpanFilterResult with true for documents which should be permitted in
search results, and false for those that should not and Spans for where the true docs match.
- * @param reader The {@link org.apache.lucene.index.IndexReader} to load position and bitset information from
+ * @param reader The {@link org.apache.lucene.index.IndexReader} to load position and DocIdSet information from
* @return A {@link SpanFilterResult}
* @throws java.io.IOException if there was an issue accessing the necessary information
* */
Index: src/java/org/apache/lucene/search/SpanFilterResult.java
===================================================================
--- src/java/org/apache/lucene/search/SpanFilterResult.java (revision 610038)
+++ src/java/org/apache/lucene/search/SpanFilterResult.java (working copy)
@@ -28,20 +28,34 @@
*
**/
public class SpanFilterResult {
+ /** @deprecated */
private BitSet bits;
+
+ private DocIdSet docIdSet;
private List positions;//Spans spans;
/**
*
* @param bits The bits for the Filter
* @param positions A List of {@link org.apache.lucene.search.SpanFilterResult.PositionInfo} objects
+ * @deprecated Use {@link #SpanFilterResult(DocIdSet, List)} instead
*/
public SpanFilterResult(BitSet bits, List positions) {
this.bits = bits;
this.positions = positions;
}
-
+
/**
+ *
+ * @param docIdSet The DocIdSet for the Filter
+ * @param positions A List of {@link org.apache.lucene.search.SpanFilterResult.PositionInfo} objects
+ */
+ public SpanFilterResult(DocIdSet docIdSet, List positions) {
+ this.docIdSet = docIdSet;
+ this.positions = positions;
+ }
+
+ /**
* The first entry in the array corresponds to the first "on" bit.
* Entries are increasing by document order
* @return A List of PositionInfo objects
@@ -50,11 +64,17 @@
return positions;
}
+ /**
+ * @deprecated Use {@link #getDocIdSet()}
+ */
public BitSet getBits() {
return bits;
}
-
+ /** Returns the docIdSet */
+ public DocIdSet getDocIdSet() {
+ return docIdSet;
+ }
public static class PositionInfo {
private int doc;
Index: src/java/org/apache/lucene/search/SpanQueryFilter.java
===================================================================
--- src/java/org/apache/lucene/search/SpanQueryFilter.java (revision 610038)
+++ src/java/org/apache/lucene/search/SpanQueryFilter.java (working copy)
@@ -19,6 +19,7 @@
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.Spans;
+import org.apache.lucene.util.OpenBitSet;
import java.io.IOException;
import java.util.ArrayList;
@@ -54,15 +55,14 @@
this.query = query;
}
- public BitSet bits(IndexReader reader) throws IOException {
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
SpanFilterResult result = bitSpans(reader);
- return result.getBits();
+ return result.getDocIdSet();
}
-
public SpanFilterResult bitSpans(IndexReader reader) throws IOException {
- final BitSet bits = new BitSet(reader.maxDoc());
+ final OpenBitSet bits = new OpenBitSet(reader.maxDoc());
Spans spans = query.getSpans(reader);
List tmp = new ArrayList(20);
int currentDoc = -1;
Index: src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java
===================================================================
--- src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java (revision 610038)
+++ src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java (working copy)
@@ -43,13 +43,13 @@
this.shouldHaveCache = shouldHaveCache;
}
- public BitSet bits(IndexReader reader) throws IOException {
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
if (cache == null) {
cache = new WeakHashMap();
}
synchronized (cache) { // check cache
- BitSet cached = (BitSet) cache.get(reader);
+ DocIdSet cached = (DocIdSet) cache.get(reader);
if (shouldHaveCache) {
TestCase.assertNotNull("Cache should have data ", cached);
} else {
@@ -60,7 +60,7 @@
}
}
- final BitSet bits = filter.bits(reader);
+ final DocIdSet bits = filter.getDocIdSet(reader);
synchronized (cache) { // update cache
cache.put(reader, bits);
Index: src/test/org/apache/lucene/search/RemoteCachingWrapperFilterHelper.java
===================================================================
--- src/test/org/apache/lucene/search/RemoteCachingWrapperFilterHelper.java (revision 610038)
+++ src/test/org/apache/lucene/search/RemoteCachingWrapperFilterHelper.java (working copy)
@@ -42,7 +42,7 @@
this.shouldHaveCache = shouldHaveCache;
}
- public BitSet bits(IndexReader reader) throws IOException {
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
Filter cachedFilter = FilterManager.getInstance().getFilter(filter);
TestCase.assertNotNull("Filter should not be null", cachedFilter);
@@ -55,6 +55,6 @@
if (filter instanceof CachingWrapperFilterHelper) {
((CachingWrapperFilterHelper)cachedFilter).setShouldHaveCache(shouldHaveCache);
}
- return cachedFilter.bits(reader);
+ return cachedFilter.getDocIdSet(reader);
}
}
Index: src/test/org/apache/lucene/search/TestCachingWrapperFilter.java
===================================================================
--- src/test/org/apache/lucene/search/TestCachingWrapperFilter.java (revision 610038)
+++ src/test/org/apache/lucene/search/TestCachingWrapperFilter.java (working copy)
@@ -36,12 +36,12 @@
CachingWrapperFilter cacher = new CachingWrapperFilter(filter);
// first time, nested filter is called
- cacher.bits(reader);
+ cacher.getDocIdSet(reader);
assertTrue("first time", filter.wasCalled());
// second time, nested filter should not be called
filter.clear();
- cacher.bits(reader);
+ cacher.getDocIdSet(reader);
assertFalse("second time", filter.wasCalled());
reader.close();
Index: src/test/org/apache/lucene/search/TestRemoteCachingWrapperFilter.java
===================================================================
--- src/test/org/apache/lucene/search/TestRemoteCachingWrapperFilter.java (revision 610038)
+++ src/test/org/apache/lucene/search/TestRemoteCachingWrapperFilter.java (working copy)
@@ -90,7 +90,7 @@
public void testTermRemoteFilter() throws Exception {
- CachingWrapperFilterHelper cwfh = new CachingWrapperFilterHelper(new QueryFilter(new TermQuery(new Term("type", "a"))));
+ CachingWrapperFilterHelper cwfh = new CachingWrapperFilterHelper(new QueryWrapperFilter(new TermQuery(new Term("type", "a"))));
// This is what we are fixing - if one uses a CachingWrapperFilter(Helper) it will never
// cache the filter on the remote site
@@ -111,16 +111,16 @@
// assert that we get the same cached Filter, even if we create a new instance of RemoteCachingWrapperFilter(Helper)
// this should pass because the Filter parameters are the same, and the cache uses Filter's hashCode() as cache keys,
// and Filters' hashCode() builds on Filter parameters, not the Filter instance itself
- rcwfh = new RemoteCachingWrapperFilterHelper(new QueryFilter(new TermQuery(new Term("type", "a"))), false);
+ rcwfh = new RemoteCachingWrapperFilterHelper(new QueryWrapperFilter(new TermQuery(new Term("type", "a"))), false);
rcwfh.shouldHaveCache(false);
search(new TermQuery(new Term("test", "test")), rcwfh, 0, "A");
- rcwfh = new RemoteCachingWrapperFilterHelper(new QueryFilter(new TermQuery(new Term("type", "a"))), false);
+ rcwfh = new RemoteCachingWrapperFilterHelper(new QueryWrapperFilter(new TermQuery(new Term("type", "a"))), false);
rcwfh.shouldHaveCache(true);
search(new TermQuery(new Term("test", "test")), rcwfh, 0, "A");
// assert that we get a non-cached version of the Filter because this is a new Query (type:b)
- rcwfh = new RemoteCachingWrapperFilterHelper(new QueryFilter(new TermQuery(new Term("type", "b"))), false);
+ rcwfh = new RemoteCachingWrapperFilterHelper(new QueryWrapperFilter(new TermQuery(new Term("type", "b"))), false);
rcwfh.shouldHaveCache(false);
search(new TermQuery(new Term("type", "b")), rcwfh, 0, "B");
}
Index: src/test/org/apache/lucene/search/TestSpanQueryFilter.java
===================================================================
--- src/test/org/apache/lucene/search/TestSpanQueryFilter.java (revision 610038)
+++ src/test/org/apache/lucene/search/TestSpanQueryFilter.java (working copy)
@@ -55,20 +55,36 @@
SpanTermQuery query = new SpanTermQuery(new Term("field", English.intToEnglish(10).trim()));
SpanQueryFilter filter = new SpanQueryFilter(query);
SpanFilterResult result = filter.bitSpans(reader);
- BitSet bits = result.getBits();
- assertTrue("bits is null and it shouldn't be", bits != null);
- assertTrue("tenth bit is not on", bits.get(10));
+ DocIdSet docIdSet = result.getDocIdSet();
+ assertTrue("docIdSet is null and it shouldn't be", docIdSet != null);
+ assertContainsDocId("docIdSet doesn't contain docId 10", docIdSet, 10);
List spans = result.getPositions();
assertTrue("spans is null and it shouldn't be", spans != null);
- assertTrue("spans Size: " + spans.size() + " is not: " + bits.cardinality(), spans.size() == bits.cardinality());
+ int size = getDocIdSetSize(docIdSet);
+ assertTrue("spans Size: " + spans.size() + " is not: " + size, spans.size() == size);
for (Iterator iterator = spans.iterator(); iterator.hasNext();) {
SpanFilterResult.PositionInfo info = (SpanFilterResult.PositionInfo) iterator.next();
assertTrue("info is null and it shouldn't be", info != null);
//The doc should indicate the bit is on
- assertTrue("Bit is not on and it should be", bits.get(info.getDoc()));
+ assertContainsDocId("docIdSet doesn't contain docId " + info.getDoc(), docIdSet, info.getDoc());
//There should be two positions in each
assertTrue("info.getPositions() Size: " + info.getPositions().size() + " is not: " + 2, info.getPositions().size() == 2);
}
reader.close();
}
+
+ int getDocIdSetSize(DocIdSet docIdSet) throws Exception {
+ int size = 0;
+ DocIdSetIterator it = docIdSet.iterator();
+ while (it.next()) {
+ size++;
+ }
+ return size;
+ }
+
+ public void assertContainsDocId(String msg, DocIdSet docIdSet, int docId) throws Exception {
+ DocIdSetIterator it = docIdSet.iterator();
+ assertTrue(msg, it.skipTo(docId));
+ assertTrue(msg, it.doc() == docId);
+ }
}