You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2015/04/21 23:47:33 UTC

svn commit: r1675201 - in /lucene/dev/branches/branch_5x: ./ lucene/ lucene/core/ lucene/core/src/java/org/apache/lucene/search/ lucene/core/src/test/org/apache/lucene/search/ lucene/facet/ lucene/facet/src/java/org/apache/lucene/facet/range/ lucene/fa...

Author: jpountz
Date: Tue Apr 21 21:47:32 2015
New Revision: 1675201

URL: http://svn.apache.org/r1675201
Log:
LUCENE-6448: Make Filter a better Query citizen.

Modified:
    lucene/dev/branches/branch_5x/   (props changed)
    lucene/dev/branches/branch_5x/lucene/   (props changed)
    lucene/dev/branches/branch_5x/lucene/core/   (props changed)
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/CachingWrapperFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocTermOrdsRangeFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/Filter.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/LRUFilterCache.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/SingleDocTestFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredSearch.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestLRUFilterCache.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java   (contents, props changed)
    lucene/dev/branches/branch_5x/lucene/facet/   (props changed)
    lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
    lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java
    lucene/dev/branches/branch_5x/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
    lucene/dev/branches/branch_5x/lucene/join/   (props changed)
    lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/BitDocIdSetCachingWrapperFilter.java
    lucene/dev/branches/branch_5x/lucene/misc/   (props changed)
    lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/index/TestBlockJoinSorter.java
    lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java
    lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/BooleanFilter.java
    lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java
    lucene/dev/branches/branch_5x/lucene/sandbox/   (props changed)
    lucene/dev/branches/branch_5x/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java
    lucene/dev/branches/branch_5x/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java
    lucene/dev/branches/branch_5x/lucene/spatial/   (props changed)
    lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
    lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java
    lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeFilter.java
    lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
    lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/util/ValueSourceFilter.java
    lucene/dev/branches/branch_5x/lucene/suggest/   (props changed)
    lucene/dev/branches/branch_5x/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/SuggestFieldTest.java
    lucene/dev/branches/branch_5x/lucene/test-framework/   (props changed)
    lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
    lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/SearchEquivalenceTestBase.java

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/CachingWrapperFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/CachingWrapperFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/CachingWrapperFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/CachingWrapperFilter.java Tue Apr 21 21:47:32 2015
@@ -134,14 +134,16 @@ public class CachingWrapperFilter extend
 
   @Override
   public boolean equals(Object o) {
-    if (o == null || !getClass().equals(o.getClass())) return false;
+    if (super.equals(o) == false) {
+      return false;
+    }
     final CachingWrapperFilter other = (CachingWrapperFilter) o;
     return this.filter.equals(other.filter);
   }
 
   @Override
   public int hashCode() {
-    return (filter.hashCode() ^ getClass().hashCode());
+    return 31 * super.hashCode() + filter.hashCode();
   }
 
   @Override

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java Tue Apr 21 21:47:32 2015
@@ -50,16 +50,22 @@ public class ConstantScoreQuery extends
 
   @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;
   }
 

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocTermOrdsRangeFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocTermOrdsRangeFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocTermOrdsRangeFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocTermOrdsRangeFilter.java Tue Apr 21 21:47:32 2015
@@ -130,7 +130,7 @@ public abstract class DocTermOrdsRangeFi
   @Override
   public final boolean equals(Object o) {
     if (this == o) return true;
-    if (!(o instanceof DocTermOrdsRangeFilter)) return false;
+    if (super.equals(o) == false) return false;
     DocTermOrdsRangeFilter other = (DocTermOrdsRangeFilter) o;
 
     if (!this.field.equals(other.field)
@@ -144,7 +144,8 @@ public abstract class DocTermOrdsRangeFi
   
   @Override
   public final int hashCode() {
-    int h = field.hashCode();
+    int h = super.hashCode();
+    h = 31 * h + field.hashCode();
     h ^= (lowerVal != null) ? lowerVal.hashCode() : 550356204;
     h = (h << 1) | (h >>> 31);  // rotate to distinguish lower from upper
     h ^= (upperVal != null) ? upperVal.hashCode() : -1674416163;

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeFilter.java Tue Apr 21 21:47:32 2015
@@ -390,7 +390,7 @@ public abstract class DocValuesRangeFilt
   @SuppressWarnings({"rawtypes"})
   public final boolean equals(Object o) {
     if (this == o) return true;
-    if (!(o instanceof DocValuesRangeFilter)) return false;
+    if (super.equals(o) == false) return false;
     DocValuesRangeFilter other = (DocValuesRangeFilter) o;
 
     if (!this.field.equals(other.field)
@@ -404,7 +404,8 @@ public abstract class DocValuesRangeFilt
   
   @Override
   public final int hashCode() {
-    int h = field.hashCode();
+    int h = super.hashCode();
+    h = 31 * h + field.hashCode();
     h ^= (lowerVal != null) ? lowerVal.hashCode() : 550356204;
     h = (h << 1) | (h >>> 31);  // rotate to distinguish lower from upper
     h ^= (upperVal != null) ? upperVal.hashCode() : -1674416163;

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsFilter.java Tue Apr 21 21:47:32 2015
@@ -18,10 +18,11 @@ package org.apache.lucene.search;
  */
 
 import java.io.IOException;
+import java.util.Arrays;
 
-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.SortedDocValues;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
@@ -133,4 +134,21 @@ public class DocValuesTermsFilter extend
     }
     return sb.append(']').toString();
   }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (super.equals(obj) == false) {
+      return false;
+    }
+    DocValuesTermsFilter other = (DocValuesTermsFilter) obj;
+    return field.equals(other.field) && Arrays.equals(terms, other.terms);
+  }
+
+  @Override
+  public int hashCode() {
+    int h = super.hashCode();
+    h = 31 * h + field.hashCode();
+    h = 31 * h + Arrays.hashCode(terms);
+    return h;
+  }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java Tue Apr 21 21:47:32 2015
@@ -114,7 +114,7 @@ public class FieldValueFilter extends Fi
   @Override
   public int hashCode() {
     final int prime = 31;
-    int result = 1;
+    int result = super.hashCode();
     result = prime * result + ((field == null) ? 0 : field.hashCode());
     result = prime * result + (negate ? 1231 : 1237);
     return result;
@@ -124,10 +124,9 @@ public class FieldValueFilter extends Fi
   public boolean equals(Object obj) {
     if (this == obj)
       return true;
-    if (obj == null)
-      return false;
-    if (getClass() != obj.getClass())
+    if (super.equals(obj) == false) {
       return false;
+    }
     FieldValueFilter other = (FieldValueFilter) obj;
     if (field == null) {
       if (other.field != null)

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/Filter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/Filter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/Filter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/Filter.java Tue Apr 21 21:47:32 2015
@@ -64,19 +64,6 @@ public abstract class Filter extends Que
   //
 
   @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) {
 

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java Tue Apr 21 21:47:32 2015
@@ -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 */

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/LRUFilterCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/LRUFilterCache.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/LRUFilterCache.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/LRUFilterCache.java Tue Apr 21 21:47:32 2015
@@ -586,13 +586,13 @@ public class LRUFilterCache implements F
 
     @Override
     public boolean equals(Object obj) {
-      return obj instanceof CachingWrapperFilter
+      return super.equals(obj)
           && in.equals(((CachingWrapperFilter) obj).in);
     }
 
     @Override
     public int hashCode() {
-      return in.hashCode() ^ getClass().hashCode();
+      return 31 * super.hashCode() + in.hashCode();
     }
 
     @Override

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java Tue Apr 21 21:47:32 2015
@@ -60,16 +60,15 @@ public class MultiTermQueryWrapperFilter
   @SuppressWarnings({"rawtypes"})
   public final boolean equals(final Object o) {
     if (o==this) return true;
-    if (o==null) return false;
-    if (this.getClass().equals(o.getClass())) {
-      return this.query.equals( ((MultiTermQueryWrapperFilter)o).query );
+    if (super.equals(o) == false) {
+      return false;
     }
-    return false;
+    return this.query.equals( ((MultiTermQueryWrapperFilter)o).query );
   }
 
   @Override
   public final int hashCode() {
-    return query.hashCode();
+    return 31 * super.hashCode() + query.hashCode();
   }
 
   /** Returns the field name for this query */

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java Tue Apr 21 21:47:32 2015
@@ -81,13 +81,14 @@ public class QueryWrapperFilter extends
 
   @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();
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/SingleDocTestFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/SingleDocTestFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/SingleDocTestFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/SingleDocTestFilter.java Tue Apr 21 21:47:32 2015
@@ -43,4 +43,17 @@ public class SingleDocTestFilter extends
   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;
+  }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java Tue Apr 21 21:47:32 2015
@@ -153,6 +153,18 @@ public class TestConstantScoreQuery exte
       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 {

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java Tue Apr 21 21:47:32 2015
@@ -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;

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredSearch.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredSearch.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredSearch.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestFilteredSearch.java Tue Apr 21 21:47:32 2015
@@ -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
     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);
+    }
   }
 
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestLRUFilterCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestLRUFilterCache.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestLRUFilterCache.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestLRUFilterCache.java Tue Apr 21 21:47:32 2015
@@ -368,6 +368,10 @@ public class TestLRUFilterCache extends
   /** A filter that produces empty sets. */
   private static class DummyFilter extends Filter {
 
+    private static final AtomicLong ID_GENERATOR = new AtomicLong();
+
+    private final long id = ID_GENERATOR.getAndIncrement();
+
     @Override
     public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
       return null;
@@ -378,6 +382,16 @@ public class TestLRUFilterCache extends
       return "DummyFilter";
     }
 
+    @Override
+    public int hashCode() {
+      return 31 * super.hashCode() + new Long(id).hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return super.equals(obj) && id == ((DummyFilter) obj).id;
+    }
+
   }
 
   // Test what happens when the cache contains only filters and doc id sets

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java Tue Apr 21 21:47:32 2015
@@ -55,6 +55,18 @@ public class TestQueryWrapperFilter exte
       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 exte
     reader.close();
     dir.close();
   }
+
+  public void testBasics() {
+    QueryUtils.check(new QueryWrapperFilter(new TermQuery(new Term("foo", "bar"))));
+  }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java Tue Apr 21 21:47:32 2015
@@ -140,20 +140,41 @@ public class TestScorerPerf extends Luce
     }
   }
 
+  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();

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java Tue Apr 21 21:47:32 2015
@@ -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.Docume
 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 Luce
         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 Luce
   }
   
   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 Luce
     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;
+    }
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java (original)
+++ lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java Tue Apr 21 21:47:32 2015
@@ -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 R
     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;
+
+    ValueSourceFilter(DoubleRange range, Filter fastMatchFilter, ValueSource valueSource) {
+      this.range = range;
+      this.fastMatchFilter = fastMatchFilter;
+      this.valueSource = valueSource;
+    }
 
-      @Override
-      public String toString(String field) {
-        return "Filter(" + DoubleRange.this.toString() + ")";
+    @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 int hashCode() {
+      return 31 * Objects.hash(range, fastMatchFilter, valueSource) + super.hashCode();
+    }
 
-      @Override
-      public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
+    @Override
+    public String toString(String field) {
+      return "Filter(" + range.toString() + ")";
+    }
 
-        // TODO: this is just like ValueSourceScorer,
-        // ValueSourceFilter (spatial),
-        // ValueSourceRangeFilter (solr); also,
-        // https://issues.apache.org/jira/browse/LUCENE-4251
-
-        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;
-          }
-        } else {
-          fastMatchDocs = new DocIdSet() {
-            @Override
-            public long ramBytesUsed() {
-              return 0;
-            }
-            @Override
-            public DocIdSetIterator iterator() throws IOException {
-              return DocIdSetIterator.all(maxDoc);
-            }
-          };
-        }
+    @Override
+    public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
 
-        return new FilteredDocIdSet(fastMatchDocs) {
+      // TODO: this is just like ValueSourceScorer,
+      // ValueSourceFilter (spatial),
+      // ValueSourceRangeFilter (solr); also,
+      // https://issues.apache.org/jira/browse/LUCENE-4251
+
+      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;
+        }
+      } 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);
   }
 }
 

Modified: lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java (original)
+++ lucene/dev/branches/branch_5x/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java Tue Apr 21 21:47:32 2015
@@ -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 Ran
     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;
+
+    ValueSourceFilter(LongRange range, Filter fastMatchFilter, ValueSource valueSource) {
+      this.range = range;
+      this.fastMatchFilter = fastMatchFilter;
+      this.valueSource = valueSource;
+    }
 
-      @Override
-      public String toString(String field) {
-        return "Filter(" + LongRange.this.toString() + ")";
+    @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
-
-        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;
-          }
-        } else {
-          fastMatchDocs = new DocIdSet() {
-            @Override
-            public long ramBytesUsed() {
-              return 0;
-            }
-            @Override
-            public DocIdSetIterator iterator() throws IOException {
-              return DocIdSetIterator.all(maxDoc);
-            }
-          };
-        }
+    @Override
+    public String toString(String field) {
+      return "Filter(" + range.toString() + ")";
+    }
+
+    @Override
+    public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
 
-        return new FilteredDocIdSet(fastMatchDocs) {
+      // TODO: this is just like ValueSourceScorer,
+      // ValueSourceFilter (spatial),
+      // ValueSourceRangeFilter (solr); also,
+      // https://issues.apache.org/jira/browse/LUCENE-4251
+
+      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;
+        }
+      } 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);
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java (original)
+++ lucene/dev/branches/branch_5x/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java Tue Apr 21 21:47:32 2015
@@ -46,7 +46,6 @@ import org.apache.lucene.facet.taxonomy.
 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.functio
 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 extend
     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 extend
 
         @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 extend
     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;
     }

Modified: lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/BitDocIdSetCachingWrapperFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/BitDocIdSetCachingWrapperFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/BitDocIdSetCachingWrapperFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/BitDocIdSetCachingWrapperFilter.java Tue Apr 21 21:47:32 2015
@@ -87,13 +87,15 @@ public class BitDocIdSetCachingWrapperFi
 
   @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();
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/index/TestBlockJoinSorter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/index/TestBlockJoinSorter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/index/TestBlockJoinSorter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/index/TestBlockJoinSorter.java Tue Apr 21 21:47:32 2015
@@ -88,6 +88,19 @@ public class TestBlockJoinSorter extends
     }
 
     @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) + ")";
     }

Modified: lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java (original)
+++ lucene/dev/branches/branch_5x/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java Tue Apr 21 21:47:32 2015
@@ -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.Docume
 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.SortFiel
 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 ex
         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 ex
   }
   
   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 ex
     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;
+    }
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/BooleanFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/BooleanFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/BooleanFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/BooleanFilter.java Tue Apr 21 21:47:32 2015
@@ -148,7 +148,7 @@ public class BooleanFilter extends Filte
       return true;
     }
 
-    if ((obj == null) || (obj.getClass() != this.getClass())) {
+    if (super.equals(obj) == false) {
       return false;
     }
 
@@ -158,7 +158,7 @@ public class BooleanFilter extends Filte
 
   @Override
   public int hashCode() {
-    return 657153718 ^ clauses.hashCode();
+    return 31 * super.hashCode() + clauses.hashCode();
   }
   
   /** Prints a user-readable version of this Filter. */

Modified: lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java Tue Apr 21 21:47:32 2015
@@ -230,7 +230,7 @@ public final class TermsFilter extends F
     if (this == obj) {
       return true;
     }
-    if ((obj == null) || (obj.getClass() != this.getClass())) {
+    if (super.equals(obj) == false) {
       return false;
     }
     
@@ -249,7 +249,7 @@ public final class TermsFilter extends F
 
   @Override
   public int hashCode() {
-    return hashCode;
+    return 31 * super.hashCode() + hashCode;
   }
   
   @Override

Modified: lucene/dev/branches/branch_5x/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java Tue Apr 21 21:47:32 2015
@@ -195,7 +195,7 @@ public class DuplicateFilter extends Fil
     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 Fil
 
   @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();

Modified: lucene/dev/branches/branch_5x/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java (original)
+++ lucene/dev/branches/branch_5x/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java Tue Apr 21 21:47:32 2015
@@ -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.tokena
 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 exte
     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 */

Modified: lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java Tue Apr 21 21:47:32 2015
@@ -66,7 +66,6 @@ public class IntersectsRPTVerifyQuery ex
   @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;

Modified: lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java Tue Apr 21 21:47:32 2015
@@ -52,7 +52,7 @@ public abstract class AbstractPrefixTree
   @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 AbstractPrefixTree
 
   @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;

Modified: lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeFilter.java Tue Apr 21 21:47:32 2015
@@ -62,19 +62,6 @@ public abstract class AbstractVisitingPr
     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

Modified: lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java Tue Apr 21 21:47:32 2015
@@ -183,7 +183,7 @@ public class SerializedDVStrategy extend
     @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 extend
 
     @Override
     public int hashCode() {
-      return predicateValueSource.hashCode();
+      return super.hashCode() + 31 * predicateValueSource.hashCode();
     }
     
     @Override

Modified: lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/util/ValueSourceFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/util/ValueSourceFilter.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/util/ValueSourceFilter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/util/ValueSourceFilter.java Tue Apr 21 21:47:32 2015
@@ -26,6 +26,7 @@ import org.apache.lucene.search.Filtered
 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 F
              "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);
+  }
 }

Modified: lucene/dev/branches/branch_5x/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/SuggestFieldTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/SuggestFieldTest.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/SuggestFieldTest.java (original)
+++ lucene/dev/branches/branch_5x/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/SuggestFieldTest.java Tue Apr 21 21:47:32 2015
@@ -54,6 +54,7 @@ import org.apache.lucene.search.QueryWra
 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;
@@ -690,42 +691,46 @@ public class SuggestFieldTest extends Lu
     iw.close();
   }
 
-  private static Filter randomAccessFilter(final Filter filter) {
-    return new Filter() {
-      @Override
-      public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
-        final DocIdSet docIdSet = filter.getDocIdSet(context, acceptDocs);
-        final DocIdSetIterator iterator = docIdSet.iterator();
-        final 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;
-          }
+  private static class RandomAccessFilter extends Filter {
 
-          @Override
-          public Bits bits() throws IOException {
-            return bits;
-          }
+    private final Filter in;
 
-          @Override
-          public long ramBytesUsed() {
-            return docIdSet.ramBytesUsed();
-          }
-        };
+    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 filter.toString(field);
+    @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 RandomAccessFilter(filter);
   }
 
   private static class Entry {

Modified: lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java (original)
+++ lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java Tue Apr 21 21:47:32 2015
@@ -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 */

Modified: lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/SearchEquivalenceTestBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/SearchEquivalenceTestBase.java?rev=1675201&r1=1675200&r2=1675201&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/SearchEquivalenceTestBase.java (original)
+++ lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/search/SearchEquivalenceTestBase.java Tue Apr 21 21:47:32 2015
@@ -226,6 +226,20 @@ public abstract class SearchEquivalenceT
     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();
+    }
+
   }
 
   /**