mirror of https://github.com/apache/lucene.git
LUCENE-6448: Make Filter a better Query citizen.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1675199 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ef4c9ffc06
commit
1422c4607f
|
@ -50,16 +50,22 @@ public class ConstantScoreQuery extends Query {
|
|||
|
||||
@Override
|
||||
public Query rewrite(IndexReader reader) throws IOException {
|
||||
Query sub = query;
|
||||
if (sub instanceof QueryWrapperFilter) {
|
||||
sub = ((QueryWrapperFilter) sub).getQuery();
|
||||
Query rewritten = query.rewrite(reader);
|
||||
|
||||
if (rewritten.getClass() == getClass()) {
|
||||
if (getBoost() != rewritten.getBoost()) {
|
||||
rewritten = rewritten.clone();
|
||||
rewritten.setBoost(getBoost());
|
||||
}
|
||||
return rewritten;
|
||||
}
|
||||
Query rewritten = sub.rewrite(reader);
|
||||
|
||||
if (rewritten != query) {
|
||||
rewritten = new ConstantScoreQuery(rewritten);
|
||||
rewritten.setBoost(this.getBoost());
|
||||
return rewritten;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,19 +63,6 @@ public abstract class Filter extends Query {
|
|||
// Query compatibility
|
||||
//
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
// Query's default impl only compares boost but they do not matter in the
|
||||
// case of filters since it does not influence scores
|
||||
return this == that;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// Query's default impl returns a hash of the boost but this is irrelevant to filters
|
||||
return System.identityHashCode(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
|
||||
return new Weight(this) {
|
||||
|
|
|
@ -327,27 +327,27 @@ public class FilteredQuery extends Query {
|
|||
|
||||
@Override
|
||||
public Query rewrite(IndexReader reader) throws IOException {
|
||||
if (filter instanceof QueryWrapperFilter) {
|
||||
// In that case the filter does not implement random-access anyway so
|
||||
// we want to take advantage of approximations
|
||||
BooleanQuery rewritten = new BooleanQuery();
|
||||
rewritten.add(query, Occur.MUST);
|
||||
rewritten.add(((QueryWrapperFilter) filter).getQuery(), Occur.FILTER);
|
||||
rewritten.setBoost(getBoost());
|
||||
return rewritten;
|
||||
}
|
||||
|
||||
final Query queryRewritten = query.rewrite(reader);
|
||||
final Query filterRewritten = filter.rewrite(reader);
|
||||
|
||||
if (queryRewritten != query) {
|
||||
// rewrite to a new FilteredQuery wrapping the rewritten query
|
||||
final Query rewritten = new FilteredQuery(queryRewritten, filter, strategy);
|
||||
rewritten.setBoost(this.getBoost());
|
||||
return rewritten;
|
||||
} else {
|
||||
// nothing to rewrite, we are done!
|
||||
return this;
|
||||
if (queryRewritten != query || filterRewritten != filter) {
|
||||
// rewrite to a new FilteredQuery wrapping the rewritten query/filter
|
||||
if (filterRewritten instanceof Filter) {
|
||||
final Query rewritten = new FilteredQuery(queryRewritten, (Filter) filterRewritten, strategy);
|
||||
rewritten.setBoost(this.getBoost());
|
||||
return rewritten;
|
||||
} else {
|
||||
// In that case the filter does not implement random-access anyway so
|
||||
// we want to take advantage of approximations
|
||||
BooleanQuery rewritten = new BooleanQuery();
|
||||
rewritten.add(queryRewritten, Occur.MUST);
|
||||
rewritten.add(filterRewritten, Occur.FILTER);
|
||||
rewritten.setBoost(getBoost());
|
||||
return rewritten;
|
||||
}
|
||||
}
|
||||
// nothing to rewrite, we are done!
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns this FilteredQuery's (unfiltered) Query */
|
||||
|
|
|
@ -81,13 +81,14 @@ public class QueryWrapperFilter extends Filter {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof QueryWrapperFilter))
|
||||
if (super.equals(o) == false) {
|
||||
return false;
|
||||
}
|
||||
return this.query.equals(((QueryWrapperFilter)o).query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return query.hashCode() ^ 0x923F64B9;
|
||||
return 31 * super.hashCode() + query.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,4 +43,17 @@ public class SingleDocTestFilter extends Filter {
|
|||
public String toString(String field) {
|
||||
return "SingleDocTestFilter(" + doc + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return doc == ((SingleDocTestFilter) obj).doc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + doc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,6 +153,18 @@ public class TestConstantScoreQuery extends LuceneTestCase {
|
|||
return in.toString(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return in.equals(((FilterWrapper) obj).in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + in.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public void testConstantScoreQueryAndFilter() throws Exception {
|
||||
|
|
|
@ -24,20 +24,20 @@ import java.util.Random;
|
|||
import org.apache.lucene.analysis.MockAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Field.Store;
|
||||
import org.apache.lucene.document.SortedDocValuesField;
|
||||
import org.apache.lucene.document.StringField;
|
||||
import org.apache.lucene.document.Field.Store;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.LeafReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.PostingsEnum;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.FilteredQuery.FilterStrategy;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.lucene.search;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
|
@ -106,6 +107,19 @@ public class TestFilteredSearch extends LuceneTestCase {
|
|||
public String toString(String field) {
|
||||
return "SimpleDocIdSetFilter";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.equals(docs, ((SimpleDocIdSetFilter) obj).docs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + Arrays.hashCode(docs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,18 @@ public class TestQueryWrapperFilter extends LuceneTestCase {
|
|||
return in.toString(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return in.equals(((FilterWrapper) obj).in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + in.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBasic() throws Exception {
|
||||
|
@ -211,4 +223,8 @@ public class TestQueryWrapperFilter extends LuceneTestCase {
|
|||
reader.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
public void testBasics() {
|
||||
QueryUtils.check(new QueryWrapperFilter(new TermQuery(new Term("foo", "bar"))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,20 +140,41 @@ public class TestScorerPerf extends LuceneTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private static class BitSetFilter extends Filter {
|
||||
private final FixedBitSet docs;
|
||||
|
||||
BitSetFilter(FixedBitSet docs) {
|
||||
this.docs = docs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
|
||||
assertNull("acceptDocs should be null, as we have an index without deletions", acceptDocs);
|
||||
return new BitDocIdSet(docs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return "randomBitSetFilter";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return docs == ((BitSetFilter) obj).docs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + System.identityHashCode(docs);
|
||||
}
|
||||
}
|
||||
|
||||
FixedBitSet addClause(BooleanQuery bq, FixedBitSet result) {
|
||||
final FixedBitSet rnd = sets[random().nextInt(sets.length)];
|
||||
Query q = new ConstantScoreQuery(new Filter() {
|
||||
@Override
|
||||
public DocIdSet getDocIdSet (LeafReaderContext context, Bits acceptDocs) {
|
||||
assertNull("acceptDocs should be null, as we have an index without deletions", acceptDocs);
|
||||
return new BitDocIdSet(rnd);
|
||||
}
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return "randomBitSetFilter";
|
||||
}
|
||||
});
|
||||
Query q = new ConstantScoreQuery(new BitSetFilter(rnd));
|
||||
bq.add(q, BooleanClause.Occur.MUST);
|
||||
if (validate) {
|
||||
if (result==null) result = rnd.clone();
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
|||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -30,16 +31,16 @@ import org.apache.lucene.document.Document;
|
|||
import org.apache.lucene.document.NumericDocValuesField;
|
||||
import org.apache.lucene.document.SortedDocValuesField;
|
||||
import org.apache.lucene.document.StoredField;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.DocValues;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.NumericDocValues;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.util.TestUtil;
|
||||
|
@ -147,7 +148,7 @@ public class TestSortRandom extends LuceneTestCase {
|
|||
sort = new Sort(sf, SortField.FIELD_DOC);
|
||||
}
|
||||
final int hitCount = TestUtil.nextInt(random, 1, r.maxDoc() + 20);
|
||||
final RandomFilter f = new RandomFilter(random, random.nextFloat(), docValues);
|
||||
final RandomFilter f = new RandomFilter(random.nextLong(), random.nextFloat(), docValues);
|
||||
int queryType = random.nextInt(2);
|
||||
if (queryType == 0) {
|
||||
// force out of order
|
||||
|
@ -232,20 +233,21 @@ public class TestSortRandom extends LuceneTestCase {
|
|||
}
|
||||
|
||||
private static class RandomFilter extends Filter {
|
||||
private final Random random;
|
||||
private final long seed;
|
||||
private float density;
|
||||
private final List<BytesRef> docValues;
|
||||
public final List<BytesRef> matchValues = Collections.synchronizedList(new ArrayList<BytesRef>());
|
||||
|
||||
// density should be 0.0 ... 1.0
|
||||
public RandomFilter(Random random, float density, List<BytesRef> docValues) {
|
||||
this.random = random;
|
||||
public RandomFilter(long seed, float density, List<BytesRef> docValues) {
|
||||
this.seed = seed;
|
||||
this.density = density;
|
||||
this.docValues = docValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
|
||||
Random random = new Random(context.docBase ^ seed);
|
||||
final int maxDoc = context.reader().maxDoc();
|
||||
final NumericDocValues idSource = DocValues.getNumeric(context.reader(), "id");
|
||||
assertNotNull(idSource);
|
||||
|
@ -265,5 +267,22 @@ public class TestSortRandom extends LuceneTestCase {
|
|||
public String toString(String field) {
|
||||
return "RandomFilter(density=" + density + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
RandomFilter other = (RandomFilter) obj;
|
||||
return seed == other.seed && docValues == other.docValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = Objects.hash(seed, density);
|
||||
h = 31 * h + System.identityHashCode(docValues);
|
||||
h = 31 * h + super.hashCode();
|
||||
return h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.lucene.facet.range;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
|
@ -101,58 +102,85 @@ public final class DoubleRange extends Range {
|
|||
return "DoubleRange(" + minIncl + " to " + maxIncl + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter(final Filter fastMatchFilter, final ValueSource valueSource) {
|
||||
return new Filter() {
|
||||
private static class ValueSourceFilter extends Filter {
|
||||
private final DoubleRange range;
|
||||
private final Filter fastMatchFilter;
|
||||
private final ValueSource valueSource;
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return "Filter(" + DoubleRange.this.toString() + ")";
|
||||
ValueSourceFilter(DoubleRange range, Filter fastMatchFilter, ValueSource valueSource) {
|
||||
this.range = range;
|
||||
this.fastMatchFilter = fastMatchFilter;
|
||||
this.valueSource = valueSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
ValueSourceFilter other = (ValueSourceFilter) obj;
|
||||
return range.equals(other.range)
|
||||
&& Objects.equals(fastMatchFilter, other.fastMatchFilter)
|
||||
&& valueSource.equals(other.valueSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * Objects.hash(range, fastMatchFilter, valueSource) + super.hashCode();
|
||||
}
|
||||
|
||||
// TODO: this is just like ValueSourceScorer,
|
||||
// ValueSourceFilter (spatial),
|
||||
// ValueSourceRangeFilter (solr); also,
|
||||
// https://issues.apache.org/jira/browse/LUCENE-4251
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return "Filter(" + range.toString() + ")";
|
||||
}
|
||||
|
||||
final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
|
||||
|
||||
final int maxDoc = context.reader().maxDoc();
|
||||
// TODO: this is just like ValueSourceScorer,
|
||||
// ValueSourceFilter (spatial),
|
||||
// ValueSourceRangeFilter (solr); also,
|
||||
// https://issues.apache.org/jira/browse/LUCENE-4251
|
||||
|
||||
final DocIdSet fastMatchDocs;
|
||||
if (fastMatchFilter != null) {
|
||||
fastMatchDocs = fastMatchFilter.getDocIdSet(context, null);
|
||||
if (fastMatchDocs == null) {
|
||||
// No documents match
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
fastMatchDocs = new DocIdSet() {
|
||||
@Override
|
||||
public long ramBytesUsed() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public DocIdSetIterator iterator() throws IOException {
|
||||
return DocIdSetIterator.all(maxDoc);
|
||||
}
|
||||
};
|
||||
final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
|
||||
|
||||
final int maxDoc = context.reader().maxDoc();
|
||||
|
||||
final DocIdSet fastMatchDocs;
|
||||
if (fastMatchFilter != null) {
|
||||
fastMatchDocs = fastMatchFilter.getDocIdSet(context, null);
|
||||
if (fastMatchDocs == null) {
|
||||
// No documents match
|
||||
return null;
|
||||
}
|
||||
|
||||
return new FilteredDocIdSet(fastMatchDocs) {
|
||||
} else {
|
||||
fastMatchDocs = new DocIdSet() {
|
||||
@Override
|
||||
protected boolean match(int docID) {
|
||||
if (acceptDocs != null && acceptDocs.get(docID) == false) {
|
||||
return false;
|
||||
}
|
||||
return accept(values.doubleVal(docID));
|
||||
public long ramBytesUsed() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public DocIdSetIterator iterator() throws IOException {
|
||||
return DocIdSetIterator.all(maxDoc);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return new FilteredDocIdSet(fastMatchDocs) {
|
||||
@Override
|
||||
protected boolean match(int docID) {
|
||||
if (acceptDocs != null && acceptDocs.get(docID) == false) {
|
||||
return false;
|
||||
}
|
||||
return range.accept(values.doubleVal(docID));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter(final Filter fastMatchFilter, final ValueSource valueSource) {
|
||||
return new ValueSourceFilter(this, fastMatchFilter, valueSource);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.lucene.facet.range;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
|
@ -93,57 +94,84 @@ public final class LongRange extends Range {
|
|||
return "LongRange(" + minIncl + " to " + maxIncl + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter(final Filter fastMatchFilter, final ValueSource valueSource) {
|
||||
return new Filter() {
|
||||
private static class ValueSourceFilter extends Filter {
|
||||
private final LongRange range;
|
||||
private final Filter fastMatchFilter;
|
||||
private final ValueSource valueSource;
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return "Filter(" + LongRange.this.toString() + ")";
|
||||
ValueSourceFilter(LongRange range, Filter fastMatchFilter, ValueSource valueSource) {
|
||||
this.range = range;
|
||||
this.fastMatchFilter = fastMatchFilter;
|
||||
this.valueSource = valueSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
ValueSourceFilter other = (ValueSourceFilter) obj;
|
||||
return range.equals(other.range)
|
||||
&& Objects.equals(fastMatchFilter, other.fastMatchFilter)
|
||||
&& valueSource.equals(other.valueSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * Objects.hash(range, fastMatchFilter, valueSource) + super.hashCode();
|
||||
}
|
||||
|
||||
// TODO: this is just like ValueSourceScorer,
|
||||
// ValueSourceFilter (spatial),
|
||||
// ValueSourceRangeFilter (solr); also,
|
||||
// https://issues.apache.org/jira/browse/LUCENE-4251
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return "Filter(" + range.toString() + ")";
|
||||
}
|
||||
|
||||
final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
|
||||
|
||||
final int maxDoc = context.reader().maxDoc();
|
||||
// TODO: this is just like ValueSourceScorer,
|
||||
// ValueSourceFilter (spatial),
|
||||
// ValueSourceRangeFilter (solr); also,
|
||||
// https://issues.apache.org/jira/browse/LUCENE-4251
|
||||
|
||||
final DocIdSet fastMatchDocs;
|
||||
if (fastMatchFilter != null) {
|
||||
fastMatchDocs = fastMatchFilter.getDocIdSet(context, null);
|
||||
if (fastMatchDocs == null) {
|
||||
// No documents match
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
fastMatchDocs = new DocIdSet() {
|
||||
@Override
|
||||
public long ramBytesUsed() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public DocIdSetIterator iterator() throws IOException {
|
||||
return DocIdSetIterator.all(maxDoc);
|
||||
}
|
||||
};
|
||||
final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
|
||||
|
||||
final int maxDoc = context.reader().maxDoc();
|
||||
|
||||
final DocIdSet fastMatchDocs;
|
||||
if (fastMatchFilter != null) {
|
||||
fastMatchDocs = fastMatchFilter.getDocIdSet(context, null);
|
||||
if (fastMatchDocs == null) {
|
||||
// No documents match
|
||||
return null;
|
||||
}
|
||||
|
||||
return new FilteredDocIdSet(fastMatchDocs) {
|
||||
} else {
|
||||
fastMatchDocs = new DocIdSet() {
|
||||
@Override
|
||||
protected boolean match(int docID) {
|
||||
if (acceptDocs != null && acceptDocs.get(docID) == false) {
|
||||
return false;
|
||||
}
|
||||
return accept(values.longVal(docID));
|
||||
public long ramBytesUsed() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public DocIdSetIterator iterator() throws IOException {
|
||||
return DocIdSetIterator.all(maxDoc);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return new FilteredDocIdSet(fastMatchDocs) {
|
||||
@Override
|
||||
protected boolean match(int docID) {
|
||||
if (acceptDocs != null && acceptDocs.get(docID) == false) {
|
||||
return false;
|
||||
}
|
||||
return range.accept(values.longVal(docID));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter(final Filter fastMatchFilter, final ValueSource valueSource) {
|
||||
return new ValueSourceFilter(this, fastMatchFilter, valueSource);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
|||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.LeafReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
|
@ -55,19 +54,14 @@ import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
|||
import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
|
||||
import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
|
||||
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
|
||||
import org.apache.lucene.search.CachingWrapperQuery;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.QueryCachingPolicy;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.QueryWrapperFilter;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
import org.apache.lucene.util.TestUtil;
|
||||
|
||||
|
@ -849,6 +843,42 @@ public class TestRangeFacetCounts extends FacetTestCase {
|
|||
IOUtils.close(r, d);
|
||||
}
|
||||
|
||||
private static class UsedFilter extends Filter {
|
||||
|
||||
private final AtomicBoolean used;
|
||||
private final Filter in;
|
||||
|
||||
UsedFilter(Filter in, AtomicBoolean used) {
|
||||
this.in = in;
|
||||
this.used = used;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs)
|
||||
throws IOException {
|
||||
used.set(true);
|
||||
return in.getDocIdSet(context, acceptDocs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return in.toString(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return in.equals(((UsedFilter) obj).in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + in.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public void testCustomDoublesValueSource() throws Exception {
|
||||
Directory dir = newDirectory();
|
||||
RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
|
||||
|
@ -875,12 +905,12 @@ public class TestRangeFacetCounts extends FacetTestCase {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
return o != null && getClass() == o.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
throw new UnsupportedOperationException();
|
||||
return getClass().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -910,18 +940,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
|
|||
if (random().nextBoolean()) {
|
||||
// Sort of silly:
|
||||
final Filter in = new QueryWrapperFilter(new MatchAllDocsQuery());
|
||||
fastMatchFilter = new Filter() {
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs)
|
||||
throws IOException {
|
||||
filterWasUsed.set(true);
|
||||
return in.getDocIdSet(context, acceptDocs);
|
||||
}
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return in.toString(field);
|
||||
}
|
||||
};
|
||||
fastMatchFilter = new UsedFilter(in, filterWasUsed);
|
||||
} else {
|
||||
fastMatchFilter = null;
|
||||
}
|
||||
|
|
|
@ -87,13 +87,15 @@ public class BitDocIdSetCachingWrapperFilter extends BitDocIdSetFilter {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !getClass().equals(o.getClass())) return false;
|
||||
if (super.equals(o) == false) {
|
||||
return false;
|
||||
}
|
||||
final BitDocIdSetCachingWrapperFilter other = (BitDocIdSetCachingWrapperFilter) o;
|
||||
return this.filter.equals(other.filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (filter.hashCode() ^ getClass().hashCode());
|
||||
return 31 * super.hashCode() + filter.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,19 @@ public class TestBlockJoinSorter extends LuceneTestCase {
|
|||
return docIdSet == EMPTY ? null : BitsFilteredDocIdSet.wrap(docIdSet, acceptDocs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return filter.equals(((BitSetCachingWrapperFilter) obj).filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + filter.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return getClass().getName() + "(" + filter.toString(field) + ")";
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -32,9 +33,9 @@ import org.apache.lucene.document.Document;
|
|||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.IntField;
|
||||
import org.apache.lucene.document.StringField;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.DocValues;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.NumericDocValues;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
|
@ -51,9 +52,9 @@ import org.apache.lucene.search.SortField;
|
|||
import org.apache.lucene.search.TopFieldDocs;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.uninverting.UninvertingReader.Type;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.util.TestUtil;
|
||||
|
@ -163,7 +164,7 @@ public class TestFieldCacheSortRandom extends LuceneTestCase {
|
|||
sort = new Sort(sf, SortField.FIELD_DOC);
|
||||
}
|
||||
final int hitCount = TestUtil.nextInt(random, 1, r.maxDoc() + 20);
|
||||
final RandomFilter f = new RandomFilter(random, random.nextFloat(), docValues);
|
||||
final RandomFilter f = new RandomFilter(random.nextLong(), random.nextFloat(), docValues);
|
||||
int queryType = random.nextInt(3);
|
||||
if (queryType == 0) {
|
||||
// force out of order
|
||||
|
@ -266,20 +267,21 @@ public class TestFieldCacheSortRandom extends LuceneTestCase {
|
|||
}
|
||||
|
||||
private static class RandomFilter extends Filter {
|
||||
private final Random random;
|
||||
private final long seed;
|
||||
private float density;
|
||||
private final List<BytesRef> docValues;
|
||||
public final List<BytesRef> matchValues = Collections.synchronizedList(new ArrayList<BytesRef>());
|
||||
|
||||
// density should be 0.0 ... 1.0
|
||||
public RandomFilter(Random random, float density, List<BytesRef> docValues) {
|
||||
this.random = random;
|
||||
public RandomFilter(long seed, float density, List<BytesRef> docValues) {
|
||||
this.seed = seed;
|
||||
this.density = density;
|
||||
this.docValues = docValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
|
||||
Random random = new Random(seed ^ context.docBase);
|
||||
final int maxDoc = context.reader().maxDoc();
|
||||
final NumericDocValues idSource = DocValues.getNumeric(context.reader(), "id");
|
||||
assertNotNull(idSource);
|
||||
|
@ -299,5 +301,22 @@ public class TestFieldCacheSortRandom extends LuceneTestCase {
|
|||
public String toString(String field) {
|
||||
return "RandomFilter(density=" + density + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
RandomFilter other = (RandomFilter) obj;
|
||||
return seed == other.seed && docValues == other.docValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = Objects.hash(seed, density);
|
||||
h = 31 * h + System.identityHashCode(docValues);
|
||||
h = 31 * h + super.hashCode();
|
||||
return h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,7 +195,7 @@ public class DuplicateFilter extends Filter {
|
|||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if ((obj == null) || (obj.getClass() != this.getClass())) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ public class DuplicateFilter extends Filter {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 217;
|
||||
int hash = super.hashCode();
|
||||
hash = 31 * hash + keepMode.hashCode();
|
||||
hash = 31 * hash + processingMode.hashCode();
|
||||
hash = 31 * hash + fieldName.hashCode();
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -38,15 +39,15 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
|
|||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.StoredField;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
@ -651,6 +652,20 @@ public class TestTermAutomatonQuery extends LuceneTestCase {
|
|||
public String toString(String field) {
|
||||
return "RandomFilter(seed=" + seed + ",density=" + density + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
RandomFilter other = (RandomFilter) obj;
|
||||
return seed == other.seed && density == other.density;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), seed, density);
|
||||
}
|
||||
}
|
||||
|
||||
/** See if we can create a TAQ with cycles */
|
||||
|
|
|
@ -66,7 +66,6 @@ public class IntersectsRPTVerifyQuery extends Query {
|
|||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof IntersectsRPTVerifyQuery)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
IntersectsRPTVerifyQuery that = (IntersectsRPTVerifyQuery) o;
|
||||
|
|
|
@ -52,7 +52,7 @@ public abstract class AbstractPrefixTreeFilter extends Filter {
|
|||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!getClass().equals(o.getClass())) return false;
|
||||
if (super.equals(o) == false) return false;
|
||||
|
||||
AbstractPrefixTreeFilter that = (AbstractPrefixTreeFilter) o;
|
||||
|
||||
|
@ -65,7 +65,8 @@ public abstract class AbstractPrefixTreeFilter extends Filter {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = queryShape.hashCode();
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + queryShape.hashCode();
|
||||
result = 31 * result + fieldName.hashCode();
|
||||
result = 31 * result + detailLevel;
|
||||
return result;
|
||||
|
|
|
@ -62,19 +62,6 @@ public abstract class AbstractVisitingPrefixTreeFilter extends AbstractPrefixTre
|
|||
assert detailLevel <= grid.getMaxLevels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);//checks getClass == o.getClass & instanceof
|
||||
|
||||
//Ignore hasIndexedLeaves as it's fixed for a specific field, which super.equals compares
|
||||
//Ignore prefixGridScanLevel as it is merely a tuning parameter.
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract class designed to make it easy to implement predicates or
|
||||
* other operations on a {@link SpatialPrefixTree} indexed field. An instance
|
||||
|
|
|
@ -183,7 +183,7 @@ public class SerializedDVStrategy extends SpatialStrategy {
|
|||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (super.equals(o) == false) return false;
|
||||
|
||||
PredicateValueSourceFilter that = (PredicateValueSourceFilter) o;
|
||||
|
||||
|
@ -194,7 +194,7 @@ public class SerializedDVStrategy extends SpatialStrategy {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return predicateValueSource.hashCode();
|
||||
return super.hashCode() + 31 * predicateValueSource.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.lucene.search.FilteredDocIdSet;
|
|||
import org.apache.lucene.util.Bits;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Filter that matches all documents where a ValueSource is
|
||||
|
@ -72,4 +73,20 @@ public class ValueSourceFilter extends Filter {
|
|||
"max=" + max +
|
||||
")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
ValueSourceFilter other = (ValueSourceFilter) obj;
|
||||
return startingFilter.equals(other.startingFilter)
|
||||
&& source.equals(other.source)
|
||||
&& min == min && max == max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), startingFilter, source, min, max);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.apache.lucene.search.QueryWrapperFilter;
|
|||
import org.apache.lucene.search.ScoreDoc;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
|
@ -700,42 +701,46 @@ public class SuggestFieldTest extends LuceneTestCase {
|
|||
iw.close();
|
||||
}
|
||||
|
||||
private static class RandomAccessFilter extends Filter {
|
||||
|
||||
private final Filter in;
|
||||
|
||||
private RandomAccessFilter(Filter in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
|
||||
DocIdSet docIdSet = in.getDocIdSet(context, acceptDocs);
|
||||
DocIdSetIterator iterator = docIdSet.iterator();
|
||||
FixedBitSet bits = new FixedBitSet(context.reader().maxDoc());
|
||||
if (iterator != null) {
|
||||
bits.or(iterator);
|
||||
}
|
||||
return new BitDocIdSet(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return in.toString(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return in.equals(((RandomAccessFilter) obj).in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + in.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private static Filter randomAccessFilter(Filter filter) {
|
||||
return new Filter() {
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
|
||||
DocIdSet docIdSet = filter.getDocIdSet(context, acceptDocs);
|
||||
DocIdSetIterator iterator = docIdSet.iterator();
|
||||
FixedBitSet bits = new FixedBitSet(context.reader().maxDoc());
|
||||
if (iterator != null) {
|
||||
int doc;
|
||||
while((doc = iterator.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
|
||||
bits.set(doc);
|
||||
}
|
||||
}
|
||||
return new DocIdSet() {
|
||||
@Override
|
||||
public DocIdSetIterator iterator() throws IOException {
|
||||
return iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bits bits() throws IOException {
|
||||
return bits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long ramBytesUsed() {
|
||||
return docIdSet.ramBytesUsed();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return filter.toString(field);
|
||||
}
|
||||
};
|
||||
return new RandomAccessFilter(filter);
|
||||
}
|
||||
|
||||
private static class Entry {
|
||||
|
|
|
@ -50,6 +50,15 @@ public class QueryUtils {
|
|||
/** Check the types of things query objects should be able to do. */
|
||||
public static void check(Query q) {
|
||||
checkHashEquals(q);
|
||||
|
||||
if (q instanceof FilteredQuery) {
|
||||
// This is our best option to have coverage on filters since they are
|
||||
// rarely searched on directly
|
||||
// This hack can go away when FilteredQuery goes away too
|
||||
FilteredQuery filtered = (FilteredQuery) q;
|
||||
check(filtered.getQuery());
|
||||
check(filtered.getFilter());
|
||||
}
|
||||
}
|
||||
|
||||
/** check very basic hashCode and equals */
|
||||
|
|
|
@ -226,6 +226,20 @@ public abstract class SearchEquivalenceTestBase extends LuceneTestCase {
|
|||
public String toString(String field) {
|
||||
return "SlowQWF(" + query + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) == false) {
|
||||
return false;
|
||||
}
|
||||
return query.equals(((SlowWrapperFilter) obj).query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + query.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue