| 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); |
| + } |
| } |