You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rj...@apache.org on 2015/03/31 07:22:50 UTC

svn commit: r1670257 [9/39] - in /lucene/dev/branches/lucene6271: ./ dev-tools/ dev-tools/idea/.idea/libraries/ dev-tools/scripts/ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous...

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java Tue Mar 31 05:22:40 2015
@@ -105,7 +105,7 @@ abstract class DisjunctionScorer extends
   }
 
   @Override
-  public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
+  public TwoPhaseIterator asTwoPhaseIterator() {
     boolean hasApproximation = false;
     for (ScorerWrapper w : subScorers) {
       if (w.twoPhaseView != null) {
@@ -119,15 +119,10 @@ abstract class DisjunctionScorer extends
       return null;
     }
 
-    return new TwoPhaseDocIdSetIterator() {
-
-      @Override
-      public DocIdSetIterator approximation() {
-        // note it is important to share the same pq as this scorer so that
-        // rebalancing the pq through the approximation will also rebalance
-        // the pq in this scorer.
-        return new DisjunctionDISIApproximation(subScorers);
-      }
+    // note it is important to share the same pq as this scorer so that
+    // rebalancing the pq through the approximation will also rebalance
+    // the pq in this scorer.
+    return new TwoPhaseIterator(new DisjunctionDISIApproximation(subScorers)) {
 
       @Override
       public boolean matches() throws IOException {
@@ -152,13 +147,16 @@ abstract class DisjunctionScorer extends
               previous = w;
             }
           }
-
-          // We need to explicitely set the list of top scorers to avoid the
-          // laziness of DisjunctionScorer.score() that would take all scorers
-          // positioned on the same doc as the top of the pq, including
-          // non-matching scorers
-          DisjunctionScorer.this.topScorers = topScorers;
+        } else {
+          // since we don't need scores, let's pretend we have a single match
+          topScorers.next = null;
         }
+
+        // We need to explicitely set the list of top scorers to avoid the
+        // laziness of DisjunctionScorer.score() that would take all scorers
+        // positioned on the same doc as the top of the pq, including
+        // non-matching scorers
+        DisjunctionScorer.this.topScorers = topScorers;
         return true;
       }
     };

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocIdSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocIdSet.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocIdSet.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocIdSet.java Tue Mar 31 05:22:40 2015
@@ -36,11 +36,6 @@ public abstract class DocIdSet implement
       return DocIdSetIterator.empty();
     }
     
-    @Override
-    public boolean isCacheable() {
-      return true;
-    }
-    
     // we explicitly provide no random access, as this filter is 100% sparse and iterator exits faster
     @Override
     public Bits bits() {
@@ -82,14 +77,4 @@ public abstract class DocIdSet implement
     return null;
   }
 
-  /**
-   * This method is a hint for {@link CachingWrapperFilter}, if this <code>DocIdSet</code>
-   * should be cached without copying it. The default is to return
-   * <code>false</code>. If you have an own <code>DocIdSet</code> implementation
-   * that does its iteration very effective and fast without doing disk I/O,
-   * override this method and return <code>true</code>.
-   */
-  public boolean isCacheable() {
-    return false;
-  }
 }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java Tue Mar 31 05:22:40 2015
@@ -85,7 +85,7 @@ public final class DocValuesRangeQuery e
         && Objects.equals(upperVal, that.upperVal)
         && includeLower == that.includeLower
         && includeUpper == that.includeUpper
-        && getBoost() == that.getBoost();
+        && super.equals(obj);
   }
 
   @Override
@@ -123,45 +123,10 @@ public final class DocValuesRangeQuery e
     if (lowerVal == null && upperVal == null) {
       throw new IllegalStateException("Both min and max values cannot be null, call rewrite first");
     }
-    return new Weight(DocValuesRangeQuery.this) {
-
-      private float queryNorm;
-      private float queryWeight;
-
-      @Override
-      public float getValueForNormalization() throws IOException {
-        queryWeight = getBoost();
-        return queryWeight * queryWeight;
-      }
-
-      @Override
-      public void normalize(float norm, float topLevelBoost) {
-        queryNorm = norm * topLevelBoost;
-        queryWeight *= queryNorm;
-      }
-
-      @Override
-      public Explanation explain(LeafReaderContext context, int doc) throws IOException {
-        final Scorer s = scorer(context, context.reader().getLiveDocs());
-        final boolean exists = (s != null && s.advance(doc) == doc);
-
-        final ComplexExplanation result = new ComplexExplanation();
-        if (exists) {
-          result.setDescription(DocValuesRangeQuery.this.toString() + ", product of:");
-          result.setValue(queryWeight);
-          result.setMatch(Boolean.TRUE);
-          result.addDetail(new Explanation(getBoost(), "boost"));
-          result.addDetail(new Explanation(queryNorm, "queryNorm"));
-        } else {
-          result.setDescription(DocValuesRangeQuery.this.toString() + " doesn't match id " + doc);
-          result.setValue(0);
-          result.setMatch(Boolean.FALSE);
-        }
-        return result;
-      }
+    return new ConstantScoreWeight(DocValuesRangeQuery.this) {
 
       @Override
-      public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
+      public Scorer scorer(LeafReaderContext context, Bits acceptDocs, float score) throws IOException {
 
         final Bits docsWithField = context.reader().getDocsWithField(field);
         if (docsWithField == null || docsWithField instanceof MatchNoBits) {
@@ -169,7 +134,7 @@ public final class DocValuesRangeQuery e
         }
 
         final DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
-        final TwoPhaseDocIdSetIterator twoPhaseRange;
+        final TwoPhaseIterator twoPhaseRange;
         if (lowerVal instanceof Long || upperVal instanceof Long) {
 
           final SortedNumericDocValues values = DocValues.getSortedNumeric(context.reader(), field);
@@ -240,33 +205,27 @@ public final class DocValuesRangeQuery e
           throw new AssertionError();
         }
 
-        return new RangeScorer(this, twoPhaseRange, queryWeight);
+        return new RangeScorer(this, twoPhaseRange, score);
       }
 
     };
   }
 
-  private static class TwoPhaseNumericRange extends TwoPhaseDocIdSetIterator {
+  private static class TwoPhaseNumericRange extends TwoPhaseIterator {
 
-    private final DocIdSetIterator approximation;
     private final SortedNumericDocValues values;
     private final long min, max;
     private final Bits acceptDocs;
 
     TwoPhaseNumericRange(SortedNumericDocValues values, long min, long max, DocIdSetIterator approximation, Bits acceptDocs) {
+      super(approximation);
       this.values = values;
       this.min = min;
       this.max = max;
-      this.approximation = approximation;
       this.acceptDocs = acceptDocs;
     }
 
     @Override
-    public DocIdSetIterator approximation() {
-      return approximation;
-    }
-
-    @Override
     public boolean matches() throws IOException {
       final int doc = approximation.docID();
       if (acceptDocs == null || acceptDocs.get(doc)) {
@@ -284,27 +243,21 @@ public final class DocValuesRangeQuery e
 
   }
 
-  private static class TwoPhaseOrdRange extends TwoPhaseDocIdSetIterator {
+  private static class TwoPhaseOrdRange extends TwoPhaseIterator {
 
-    private final DocIdSetIterator approximation;
     private final SortedSetDocValues values;
     private final long minOrd, maxOrd;
     private final Bits acceptDocs;
 
     TwoPhaseOrdRange(SortedSetDocValues values, long minOrd, long maxOrd, DocIdSetIterator approximation, Bits acceptDocs) {
+      super(approximation);
       this.values = values;
       this.minOrd = minOrd;
       this.maxOrd = maxOrd;
-      this.approximation = approximation;
       this.acceptDocs = acceptDocs;
     }
 
     @Override
-    public DocIdSetIterator approximation() {
-      return approximation;
-    }
-
-    @Override
     public boolean matches() throws IOException {
       final int doc = approximation.docID();
       if (acceptDocs == null || acceptDocs.get(doc)) {
@@ -322,19 +275,19 @@ public final class DocValuesRangeQuery e
 
   private static class RangeScorer extends Scorer {
 
-    private final TwoPhaseDocIdSetIterator twoPhaseRange;
+    private final TwoPhaseIterator twoPhaseRange;
     private final DocIdSetIterator disi;
     private final float score;
 
-    RangeScorer(Weight weight, TwoPhaseDocIdSetIterator twoPhaseRange, float score) {
+    RangeScorer(Weight weight, TwoPhaseIterator twoPhaseRange, float score) {
       super(weight);
       this.twoPhaseRange = twoPhaseRange;
-      this.disi = TwoPhaseDocIdSetIterator.asDocIdSetIterator(twoPhaseRange);
+      this.disi = TwoPhaseIterator.asDocIdSetIterator(twoPhaseRange);
       this.score = score;
     }
 
     @Override
-    public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
+    public TwoPhaseIterator asTwoPhaseIterator() {
       return twoPhaseRange;
     }
 

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java Tue Mar 31 05:22:40 2015
@@ -18,11 +18,12 @@ package org.apache.lucene.search;
  */
 
 import java.io.IOException;
+import java.util.Objects;
 
-import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.DocValues;
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.SortedDocValues;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.SortedSetDocValues;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.util.Bits;
@@ -38,19 +39,19 @@ public final class DocValuesRewriteMetho
   
   @Override
   public Query rewrite(IndexReader reader, MultiTermQuery query) {
-    Query result = new ConstantScoreQuery(new MultiTermQueryDocValuesWrapperFilter(query));
+    Query result = new ConstantScoreQuery(new MultiTermQueryDocValuesWrapper(query));
     result.setBoost(query.getBoost());
     return result;
   }
   
-  static class MultiTermQueryDocValuesWrapperFilter extends Filter {
+  static class MultiTermQueryDocValuesWrapper extends Query {
     
     protected final MultiTermQuery query;
     
     /**
      * Wrap a {@link MultiTermQuery} as a Filter.
      */
-    protected MultiTermQueryDocValuesWrapperFilter(MultiTermQuery query) {
+    protected MultiTermQueryDocValuesWrapper(MultiTermQuery query) {
       this.query = query;
     }
     
@@ -65,97 +66,145 @@ public final class DocValuesRewriteMetho
       if (o==this) return true;
       if (o==null) return false;
       if (this.getClass().equals(o.getClass())) {
-        return this.query.equals( ((MultiTermQueryDocValuesWrapperFilter)o).query );
+        final MultiTermQueryDocValuesWrapper that = (MultiTermQueryDocValuesWrapper) o;
+        return this.query.equals(that.query) && this.getBoost() == that.getBoost();
       }
       return false;
     }
     
     @Override
     public final int hashCode() {
-      return query.hashCode();
+      return Objects.hash(getClass(), query, getBoost());
     }
     
     /** Returns the field name for this query */
     public final String getField() { return query.getField(); }
     
-    /**
-     * Returns a DocIdSet with documents that should be permitted in search
-     * results.
-     */
     @Override
-    public DocIdSet getDocIdSet(LeafReaderContext context, final Bits acceptDocs) throws IOException {
-      final SortedDocValues fcsi = DocValues.getSorted(context.reader(), query.field);
-      // Cannot use FixedBitSet because we require long index (ord):
-      final LongBitSet termSet = new LongBitSet(fcsi.getValueCount());
-      TermsEnum termsEnum = query.getTermsEnum(new Terms() {
-        
-        @Override
-        public TermsEnum iterator(TermsEnum reuse) {
-          return fcsi.termsEnum();
-        }
-
-        @Override
-        public long getSumTotalTermFreq() {
-          return -1;
-        }
-
-        @Override
-        public long getSumDocFreq() {
-          return -1;
-        }
-
-        @Override
-        public int getDocCount() {
-          return -1;
-        }
-
+    public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+      return new ConstantScoreWeight(this) {
         @Override
-        public long size() {
-          return -1;
-        }
-
-        @Override
-        public boolean hasFreqs() {
-          return false;
-        }
-
-        @Override
-        public boolean hasOffsets() {
-          return false;
-        }
-
-        @Override
-        public boolean hasPositions() {
-          return false;
-        }
-        
-        @Override
-        public boolean hasPayloads() {
-          return false;
-        }
-      });
-      
-      assert termsEnum != null;
-      if (termsEnum.next() != null) {
-        // fill into a bitset
-        do {
-          long ord = termsEnum.ord();
-          if (ord >= 0) {
-            termSet.set(ord);
+        Scorer scorer(LeafReaderContext context, Bits acceptDocs, float score) throws IOException {
+          final SortedSetDocValues fcsi = DocValues.getSortedSet(context.reader(), query.field);
+          TermsEnum termsEnum = query.getTermsEnum(new Terms() {
+            
+            @Override
+            public TermsEnum iterator(TermsEnum reuse) {
+              return fcsi.termsEnum();
+            }
+
+            @Override
+            public long getSumTotalTermFreq() {
+              return -1;
+            }
+
+            @Override
+            public long getSumDocFreq() {
+              return -1;
+            }
+
+            @Override
+            public int getDocCount() {
+              return -1;
+            }
+
+            @Override
+            public long size() {
+              return -1;
+            }
+
+            @Override
+            public boolean hasFreqs() {
+              return false;
+            }
+
+            @Override
+            public boolean hasOffsets() {
+              return false;
+            }
+
+            @Override
+            public boolean hasPositions() {
+              return false;
+            }
+            
+            @Override
+            public boolean hasPayloads() {
+              return false;
+            }
+          });
+          
+          assert termsEnum != null;
+          if (termsEnum.next() == null) {
+            // no matching terms
+            return null;
           }
-        } while (termsEnum.next() != null);
-      } else {
-        return null;
-      }
-      
-      return new DocValuesDocIdSet(context.reader().maxDoc(), acceptDocs) {
-        @Override
-        protected final boolean matchDoc(int doc) throws ArrayIndexOutOfBoundsException {
-          int ord = fcsi.getOrd(doc);
-          if (ord == -1) {
-            return false;
-          }
-          return termSet.get(ord);
+          // fill into a bitset
+          // Cannot use FixedBitSet because we require long index (ord):
+          final LongBitSet termSet = new LongBitSet(fcsi.getValueCount());
+          do {
+            long ord = termsEnum.ord();
+            if (ord >= 0) {
+              termSet.set(ord);
+            }
+          } while (termsEnum.next() != null);
+          
+          final DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
+          final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approximation) {
+            @Override
+            public boolean matches() throws IOException {
+              final int doc = approximation.docID();
+              if (acceptDocs != null && acceptDocs.get(doc) == false) {
+                return false;
+              }
+              fcsi.setDocument(doc);
+              for (long ord = fcsi.nextOrd(); ord != SortedSetDocValues.NO_MORE_ORDS; ord = fcsi.nextOrd()) {
+                if (termSet.get(ord)) {
+                  return true;
+                }
+              }
+              return false;
+            }
+          };
+          final DocIdSetIterator disi = TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator);
+          return new Scorer(this) {
+
+            @Override
+            public TwoPhaseIterator asTwoPhaseIterator() {
+              return twoPhaseIterator;
+            }
+
+            @Override
+            public float score() throws IOException {
+              return score;
+            }
+
+            @Override
+            public int freq() throws IOException {
+              return 1;
+            }
+
+            @Override
+            public int docID() {
+              return disi.docID();
+            }
+
+            @Override
+            public int nextDoc() throws IOException {
+              return disi.nextDoc();
+            }
+
+            @Override
+            public int advance(int target) throws IOException {
+              return disi.advance(target);
+            }
+
+            @Override
+            public long cost() {
+              return disi.cost();
+            }
+
+          };
         }
       };
     }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java Tue Mar 31 05:22:40 2015
@@ -62,18 +62,12 @@ final class ExactPhraseScorer extends Sc
   }
 
   @Override
-  public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
-    return new TwoPhaseDocIdSetIterator() {
-
+  public TwoPhaseIterator asTwoPhaseIterator() {
+    return new TwoPhaseIterator(conjunction) {
       @Override
       public boolean matches() throws IOException {
         return phraseFreq() > 0;
       }
-
-      @Override
-      public DocIdSetIterator approximation() {
-        return conjunction;
-      }
     };
   }
 

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java Tue Mar 31 05:22:40 2015
@@ -46,7 +46,7 @@ public final class FieldValueQuery exten
       return false;
     }
     final FieldValueQuery that = (FieldValueQuery) obj;
-    return field.equals(that.field) && getBoost() == that.getBoost();
+    return super.equals(obj) && field.equals(that.field);
   }
 
   @Override
@@ -61,52 +61,17 @@ public final class FieldValueQuery exten
 
   @Override
   public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-    return new Weight(this) {
-
-      private float queryNorm;
-      private float queryWeight;
-
-      @Override
-      public float getValueForNormalization() throws IOException {
-        queryWeight = getBoost();
-        return queryWeight * queryWeight;
-      }
-
-      @Override
-      public void normalize(float norm, float topLevelBoost) {
-        queryNorm = norm * topLevelBoost;
-        queryWeight *= queryNorm;
-      }
+    return new ConstantScoreWeight(this) {
 
       @Override
-      public Explanation explain(LeafReaderContext context, int doc) throws IOException {
-        final Scorer s = scorer(context, context.reader().getLiveDocs());
-        final boolean exists = (s != null && s.advance(doc) == doc);
-
-        final ComplexExplanation result = new ComplexExplanation();
-        if (exists) {
-          result.setDescription(FieldValueQuery.this.toString() + ", product of:");
-          result.setValue(queryWeight);
-          result.setMatch(Boolean.TRUE);
-          result.addDetail(new Explanation(getBoost(), "boost"));
-          result.addDetail(new Explanation(queryNorm, "queryNorm"));
-        } else {
-          result.setDescription(FieldValueQuery.this.toString() + " doesn't match id " + doc);
-          result.setValue(0);
-          result.setMatch(Boolean.FALSE);
-        }
-        return result;
-      }
-
-      @Override
-      public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
+      public Scorer scorer(LeafReaderContext context, Bits acceptDocs, float score) throws IOException {
         final Bits docsWithField = context.reader().getDocsWithField(field);
         if (docsWithField == null || docsWithField instanceof MatchNoBits) {
           return null;
         }
 
         final DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
-        final TwoPhaseDocIdSetIterator twoPhaseIterator = new TwoPhaseDocIdSetIterator() {
+        final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approximation) {
 
           @Override
           public boolean matches() throws IOException {
@@ -120,17 +85,13 @@ public final class FieldValueQuery exten
             return true;
           }
 
-          @Override
-          public DocIdSetIterator approximation() {
-            return approximation;
-          }
         };
-        final DocIdSetIterator disi = TwoPhaseDocIdSetIterator.asDocIdSetIterator(twoPhaseIterator);
+        final DocIdSetIterator disi = TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator);
 
         return new Scorer(this) {
 
           @Override
-          public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
+          public TwoPhaseIterator asTwoPhaseIterator() {
             return twoPhaseIterator;
           }
 
@@ -161,7 +122,7 @@ public final class FieldValueQuery exten
 
           @Override
           public float score() throws IOException {
-            return queryWeight;
+            return score;
           }
         };
       }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Filter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Filter.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Filter.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Filter.java Tue Mar 31 05:22:40 2015
@@ -63,7 +63,7 @@ public abstract class Filter extends Que
 
   @Override
   public boolean equals(Object that) {
-    // Query's default impl only compares boots but they do not matter in the
+    // 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;
   }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilterScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilterScorer.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilterScorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilterScorer.java Tue Mar 31 05:22:40 2015
@@ -62,17 +62,17 @@ public abstract class FilterScorer exten
   }
 
   @Override
-  public int docID() {
+  public final int docID() {
     return in.docID();
   }
 
   @Override
-  public int nextDoc() throws IOException {
+  public final int nextDoc() throws IOException {
     return in.nextDoc();
   }
 
   @Override
-  public int advance(int target) throws IOException {
+  public final int advance(int target) throws IOException {
     return in.advance(target);
   }
 
@@ -80,5 +80,9 @@ public abstract class FilterScorer exten
   public long cost() {
     return in.cost();
   }
-
+  
+  @Override
+  public final TwoPhaseIterator asTwoPhaseIterator() {
+    return in.asTwoPhaseIterator();
+  }
 }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java Tue Mar 31 05:22:40 2015
@@ -58,12 +58,6 @@ public abstract class FilteredDocIdSet e
     return _innerSet;
   }
 
-  /** This DocIdSet implementation is cacheable if the inner set is cacheable. */
-  @Override
-  public boolean isCacheable() {
-    return _innerSet.isCacheable();
-  }
-
   @Override
   public long ramBytesUsed() {
     return RamUsageEstimator.NUM_BYTES_OBJECT_REF + _innerSet.ramBytesUsed();

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java Tue Mar 31 05:22:40 2015
@@ -18,6 +18,7 @@ package org.apache.lucene.search;
  */
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
@@ -25,6 +26,7 @@ import java.util.Set;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.ToStringUtils;
 
@@ -36,7 +38,7 @@ import org.apache.lucene.util.ToStringUt
  * query is used in a search - use a CachingWrapperFilter to avoid
  * regenerating the bits every time.
  * @since   1.4
- * @see     CachingWrapperFilter
+ * @see     CachingWrapperQuery
  */
 public class FilteredQuery extends Query {
 
@@ -64,10 +66,15 @@ public class FilteredQuery extends Query
    * @see FilterStrategy
    */
   public FilteredQuery(Query query, Filter filter, FilterStrategy strategy) {
-    if (query == null || filter == null)
-      throw new IllegalArgumentException("Query and filter cannot be null.");
-    if (strategy == null)
-      throw new IllegalArgumentException("FilterStrategy can not be null");
+    if (query == null) {
+      throw new IllegalArgumentException("Query must not be be null.");
+    }
+    if (filter == null) {
+      throw new IllegalArgumentException("Filter must not be be null.");
+    }
+    if (strategy == null) {
+      throw new IllegalArgumentException("FilterStrategy must not be null");
+    }
     this.strategy = strategy;
     this.query = query;
     this.filter = filter;
@@ -148,13 +155,12 @@ public class FilteredQuery extends Query
    * than document scoring or if the filter has a linear running time to compute
    * the next matching doc like exact geo distances.
    */
-  private static final class QueryFirstScorer extends FilterScorer {
+  private static final class QueryFirstScorer extends Scorer {
     private final Scorer scorer;
-    private int scorerDoc = -1;
     private final Bits filterBits;
 
     protected QueryFirstScorer(Weight weight, Bits filterBits, Scorer other) {
-      super(other, weight);
+      super(weight);
       this.scorer = other;
       this.filterBits = filterBits;
     }
@@ -164,8 +170,8 @@ public class FilteredQuery extends Query
       int doc;
       for(;;) {
         doc = scorer.nextDoc();
-        if (doc == Scorer.NO_MORE_DOCS || filterBits.get(doc)) {
-          return scorerDoc = doc;
+        if (doc == DocIdSetIterator.NO_MORE_DOCS || filterBits.get(doc)) {
+          return doc;
         }
       } 
     }
@@ -173,15 +179,31 @@ public class FilteredQuery extends Query
     @Override
     public int advance(int target) throws IOException {
       int doc = scorer.advance(target);
-      if (doc != Scorer.NO_MORE_DOCS && !filterBits.get(doc)) {
-        return scorerDoc = nextDoc();
+      if (doc != DocIdSetIterator.NO_MORE_DOCS && !filterBits.get(doc)) {
+        return nextDoc();
       } else {
-        return scorerDoc = doc;
+        return doc;
       }
     }
+    
     @Override
     public int docID() {
-      return scorerDoc;
+      return scorer.docID();
+    }
+
+    @Override
+    public float score() throws IOException {
+      return scorer.score();
+    }
+
+    @Override
+    public int freq() throws IOException {
+      return scorer.freq();
+    }
+
+    @Override
+    public long cost() {
+      return scorer.cost();
     }
 
     @Override
@@ -189,6 +211,28 @@ public class FilteredQuery extends Query
       return Collections.singleton(new ChildScorer(scorer, "FILTERED"));
     }
 
+    @Override
+    public TwoPhaseIterator asTwoPhaseIterator() {    
+      TwoPhaseIterator inner = scorer.asTwoPhaseIterator();
+      if (inner != null) {
+        // we are like a simplified conjunction here, handle the nested case:
+        return new TwoPhaseIterator(inner.approximation()) {
+          @Override
+          public boolean matches() throws IOException {
+            // check the approximation matches first, then check bits last.
+            return inner.matches() && filterBits.get(scorer.docID());
+          }
+        };
+      } else {
+        // scorer doesnt have an approximation, just use it, to force bits applied last.
+        return new TwoPhaseIterator(scorer) {
+          @Override
+          public boolean matches() throws IOException {
+            return filterBits.get(scorer.docID());
+          }
+        };
+      }
+    }
   }
 
   private static class QueryFirstBulkScorer extends BulkScorer {
@@ -236,53 +280,29 @@ public class FilteredQuery extends Query
    * jumping past the target document. When both land on the same document, it's
    * collected.
    */
-  private static final class LeapFrogScorer extends FilterScorer {
-    private final DocIdSetIterator secondary;
-    private final DocIdSetIterator primary;
+  private static final class LeapFrogScorer extends Scorer {
+    private final ConjunctionDISI conjunction;
     private final Scorer scorer;
-    private int primaryDoc = -1;
-    private int secondaryDoc = -1;
 
     protected LeapFrogScorer(Weight weight, DocIdSetIterator primary, DocIdSetIterator secondary, Scorer scorer) {
-      super(scorer, weight);
-      this.primary = primary;
-      this.secondary = secondary;
+      super(weight);
+      conjunction = ConjunctionDISI.intersect(Arrays.asList(primary, secondary));
       this.scorer = scorer;
     }
 
-    private final int advanceToNextCommonDoc() throws IOException {
-      for (;;) {
-        if (secondaryDoc < primaryDoc) {
-          secondaryDoc = secondary.advance(primaryDoc);
-        } else if (secondaryDoc == primaryDoc) {
-          return primaryDoc;
-        } else {
-          primaryDoc = primary.advance(secondaryDoc);
-        }
-      }
-    }
-
     @Override
-    public final int nextDoc() throws IOException {
-      primaryDoc = primaryNext();
-      return advanceToNextCommonDoc();
-    }
-    
-    protected int primaryNext() throws IOException {
-      return primary.nextDoc();
+    public int nextDoc() throws IOException {
+      return conjunction.nextDoc();
     }
     
     @Override
     public final int advance(int target) throws IOException {
-      if (target > primaryDoc) {
-        primaryDoc = primary.advance(target);
-      }
-      return advanceToNextCommonDoc();
+      return conjunction.advance(target);
     }
 
     @Override
     public final int docID() {
-      return secondaryDoc;
+      return conjunction.docID();
     }
 
     @Override
@@ -292,15 +312,37 @@ public class FilteredQuery extends Query
 
     @Override
     public long cost() {
-      return Math.min(primary.cost(), secondary.cost());
+      return conjunction.cost();
+    }
+
+    @Override
+    public float score() throws IOException {
+      return scorer.score();
+    }
+
+    @Override
+    public int freq() throws IOException {
+      return scorer.freq();
+    }
+
+    @Override
+    public TwoPhaseIterator asTwoPhaseIterator() {
+      return conjunction.asTwoPhaseIterator();
     }
   }
   
-  /** Rewrites the query. If the wrapped is an instance of
-   * {@link MatchAllDocsQuery} it returns a {@link ConstantScoreQuery}. Otherwise
-   * it returns a new {@code FilteredQuery} wrapping the rewritten 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);
     
     if (queryRewritten != query) {

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java Tue Mar 31 05:22:40 2015
@@ -20,7 +20,10 @@ package org.apache.lucene.search;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -70,6 +73,11 @@ import org.apache.lucene.util.ThreadInte
  * use your own (non-Lucene) objects instead.</p>
  */
 public class IndexSearcher {
+
+  // disabled by default
+  private static QueryCache DEFAULT_QUERY_CACHE = null;
+  private static QueryCachingPolicy DEFAULT_CACHING_POLICY = new UsageTrackingQueryCachingPolicy();
+
   final IndexReader reader; // package private for testing!
   
   // NOTE: these members might change in incompatible ways
@@ -84,7 +92,10 @@ public class IndexSearcher {
 
   // the default Similarity
   private static final Similarity defaultSimilarity = new DefaultSimilarity();
-  
+
+  private QueryCache queryCache = DEFAULT_QUERY_CACHE;
+  private QueryCachingPolicy queryCachingPolicy = DEFAULT_CACHING_POLICY;
+
   /**
    * Expert: returns a default Similarity instance.
    * In general, this method is only called to initialize searchers and writers.
@@ -95,7 +106,23 @@ public class IndexSearcher {
   public static Similarity getDefaultSimilarity() {
     return defaultSimilarity;
   }
-  
+
+  /**
+   * Expert: set the default {@link QueryCache} instance.
+   * @lucene.internal
+   */
+  public static void setDefaultQueryCache(QueryCache defaultQueryCache) {
+    DEFAULT_QUERY_CACHE = defaultQueryCache;
+  }
+
+  /**
+   * Expert: set the default {@link QueryCachingPolicy} instance.
+   * @lucene.internal
+   */
+  public static void setDefaultQueryCachingPolicy(QueryCachingPolicy defaultQueryCachingPolicy) {
+    DEFAULT_CACHING_POLICY = defaultQueryCachingPolicy;
+  }
+
   /** The Similarity implementation used by this searcher. */
   private Similarity similarity = defaultSimilarity;
 
@@ -154,7 +181,32 @@ public class IndexSearcher {
   public IndexSearcher(IndexReaderContext context) {
     this(context, null);
   }
-  
+
+  /**
+   * Set the {@link QueryCache} to use when scores are not needed.
+   * A value of {@code null} indicates that query matches should never be
+   * cached. This method should be called <b>before</b> starting using this
+   * {@link IndexSearcher}.
+   * <p>NOTE: When using a query cache, queries should not be modified after
+   * they have been passed to IndexSearcher.
+   * @see QueryCache
+   * @lucene.experimental
+   */
+  public void setQueryCache(QueryCache queryCache) {
+    this.queryCache = queryCache;
+  }
+
+  /**
+   * Set the {@link QueryCachingPolicy} to use for query caching.
+   * This method should be called <b>before</b> starting using this
+   * {@link IndexSearcher}.
+   * @see QueryCachingPolicy
+   * @lucene.experimental
+   */
+  public void setQueryCachingPolicy(QueryCachingPolicy queryCachingPolicy) {
+    this.queryCachingPolicy = Objects.requireNonNull(queryCachingPolicy);
+  }
+
   /**
    * Expert: Creates an array of leaf slices each holding a subset of the given leaves.
    * Each {@link LeafSlice} is executed in a single thread. By default there
@@ -209,6 +261,30 @@ public class IndexSearcher {
     return similarity;
   }
 
+  /**
+   * Count how many documents match the given query.
+   */
+  public int count(Query query) throws IOException {
+    final CollectorManager<TotalHitCountCollector, Integer> collectorManager = new CollectorManager<TotalHitCountCollector, Integer>() {
+
+      @Override
+      public TotalHitCountCollector newCollector() throws IOException {
+        return new TotalHitCountCollector();
+      }
+
+      @Override
+      public Integer reduce(Collection<TotalHitCountCollector> collectors) throws IOException {
+        int total = 0;
+        for (TotalHitCountCollector collector : collectors) {
+          total += collector.getTotalHits();
+        }
+        return total;
+      }
+
+    };
+    return search(query, collectorManager);
+  }
+
   /** Finds the top <code>n</code>
    * hits for <code>query</code> where all results are after a previous 
    * result (<code>after</code>).
@@ -228,47 +304,30 @@ public class IndexSearcher {
     }
     numHits = Math.min(numHits, limit);
 
-    if (executor == null) {
-      final TopScoreDocCollector collector = TopScoreDocCollector.create(numHits, after);
-      search(query, collector);
-      return collector.topDocs();
-    } else {
-      final TopScoreDocCollector[] collectors = new TopScoreDocCollector[leafSlices.length];
-      boolean needsScores = false;
-      for (int i = 0; i < leafSlices.length; ++i) {
-        collectors[i] = TopScoreDocCollector.create(numHits, after);
-        needsScores |= collectors[i].needsScores();
-      }
+    final int cappedNumHits = Math.min(numHits, limit);
 
-      final Weight weight = createNormalizedWeight(query, needsScores);
-      final List<Future<TopDocs>> topDocsFutures = new ArrayList<>(leafSlices.length);
-      for (int i = 0; i < leafSlices.length; ++i) {
-        final LeafReaderContext[] leaves = leafSlices[i].leaves;
-        final TopScoreDocCollector collector = collectors[i];
-        topDocsFutures.add(executor.submit(new Callable<TopDocs>() {
-          @Override
-          public TopDocs call() throws Exception {
-            search(Arrays.asList(leaves), weight, collector);
-            return collector.topDocs();
-          }
-        }));
+    final CollectorManager<TopScoreDocCollector, TopDocs> manager = new CollectorManager<TopScoreDocCollector, TopDocs>() {
+
+      @Override
+      public TopScoreDocCollector newCollector() throws IOException {
+        return TopScoreDocCollector.create(cappedNumHits, after);
       }
 
-      final TopDocs[] topDocs = new TopDocs[leafSlices.length];
-      for (int i = 0; i < topDocs.length; ++i) {
-        try {
-          topDocs[i] = topDocsFutures.get(i).get();
-        } catch (InterruptedException e) {
-          throw new ThreadInterruptedException(e);
-        } catch (ExecutionException e) {
-          throw new RuntimeException(e);
+      @Override
+      public TopDocs reduce(Collection<TopScoreDocCollector> collectors) throws IOException {
+        final TopDocs[] topDocs = new TopDocs[collectors.size()];
+        int i = 0;
+        for (TopScoreDocCollector collector : collectors) {
+          topDocs[i++] = collector.topDocs();
         }
+        return TopDocs.merge(cappedNumHits, topDocs);
       }
 
-      return TopDocs.merge(numHits, topDocs);
-    }
+    };
+
+    return search(query, manager);
   }
-  
+
   /** Finds the top <code>n</code>
    * hits for <code>query</code>.
    *
@@ -324,7 +383,7 @@ public class IndexSearcher {
   }
 
   /** Finds the top <code>n</code>
-   * hits for <code>query</code> where all results are after a previous 
+   * hits for <code>query</code> where all results are after a previous
    * result (<code>after</code>).
    * <p>
    * By passing the bottom result from a previous page as <code>after</code>,
@@ -339,7 +398,7 @@ public class IndexSearcher {
   }
 
   /** Finds the top <code>n</code>
-   * hits for <code>query</code> where all results are after a previous 
+   * hits for <code>query</code> where all results are after a previous
    * result (<code>after</code>), allowing control over
    * whether hit scores and max score should be computed.
    * <p>
@@ -371,39 +430,72 @@ public class IndexSearcher {
       throw new IllegalArgumentException("after.doc exceeds the number of documents in the reader: after.doc="
           + after.doc + " limit=" + limit);
     }
-    numHits = Math.min(numHits, limit);
+    final int cappedNumHits = Math.min(numHits, limit);
+
+    final CollectorManager<TopFieldCollector, TopFieldDocs> manager = new CollectorManager<TopFieldCollector, TopFieldDocs>() {
+
+      @Override
+      public TopFieldCollector newCollector() throws IOException {
+        final boolean fillFields = true;
+        return TopFieldCollector.create(sort, cappedNumHits, after, fillFields, doDocScores, doMaxScore);
+      }
 
-    final boolean fillFields = true;
+      @Override
+      public TopFieldDocs reduce(Collection<TopFieldCollector> collectors) throws IOException {
+        final TopFieldDocs[] topDocs = new TopFieldDocs[collectors.size()];
+        int i = 0;
+        for (TopFieldCollector collector : collectors) {
+          topDocs[i++] = collector.topDocs();
+        }
+        return TopDocs.merge(sort, cappedNumHits, topDocs);
+      }
+
+    };
+
+    return search(query, manager);
+  }
+
+ /**
+  * Lower-level search API.
+  * Search all leaves using the given {@link CollectorManager}. In contrast
+  * to {@link #search(Query, Collector)}, this method will use the searcher's
+  * {@link ExecutorService} in order to parallelize execution of the collection
+  * on the configured {@link #leafSlices}.
+  * @see CollectorManager
+  * @lucene.experimental
+  */
+  public <C extends Collector, T> T search(Query query, CollectorManager<C, T> collectorManager) throws IOException {
     if (executor == null) {
-      final TopFieldCollector collector = TopFieldCollector.create(sort, numHits, after, fillFields, doDocScores, doMaxScore);
+      final C collector = collectorManager.newCollector();
       search(query, collector);
-      return collector.topDocs();
+      return collectorManager.reduce(Collections.singletonList(collector));
     } else {
-      final TopFieldCollector[] collectors = new TopFieldCollector[leafSlices.length];
+      final List<C> collectors = new ArrayList<>(leafSlices.length);
       boolean needsScores = false;
       for (int i = 0; i < leafSlices.length; ++i) {
-        collectors[i] = TopFieldCollector.create(sort, numHits, after, fillFields, doDocScores, doMaxScore);
-        needsScores |= collectors[i].needsScores();
+        final C collector = collectorManager.newCollector();
+        collectors.add(collector);
+        needsScores |= collector.needsScores();
       }
 
       final Weight weight = createNormalizedWeight(query, needsScores);
-      final List<Future<TopFieldDocs>> topDocsFutures = new ArrayList<>(leafSlices.length);
+      final List<Future<C>> topDocsFutures = new ArrayList<>(leafSlices.length);
       for (int i = 0; i < leafSlices.length; ++i) {
         final LeafReaderContext[] leaves = leafSlices[i].leaves;
-        final TopFieldCollector collector = collectors[i];
-        topDocsFutures.add(executor.submit(new Callable<TopFieldDocs>() {
+        final C collector = collectors.get(i);
+        topDocsFutures.add(executor.submit(new Callable<C>() {
           @Override
-          public TopFieldDocs call() throws Exception {
+          public C call() throws Exception {
             search(Arrays.asList(leaves), weight, collector);
-            return collector.topDocs();
+            return collector;
           }
         }));
       }
 
-      final TopFieldDocs[] topDocs = new TopFieldDocs[leafSlices.length];
-      for (int i = 0; i < topDocs.length; ++i) {
+      final List<C> collectedCollectors = new ArrayList<>();
+      for (Future<C> future : topDocsFutures) {
         try {
-          topDocs[i] = topDocsFutures.get(i).get();
+          collectedCollectors.add(future.get());
         } catch (InterruptedException e) {
           throw new ThreadInterruptedException(e);
         } catch (ExecutionException e) {
@@ -411,7 +503,7 @@ public class IndexSearcher {
         }
       }
 
-      return TopDocs.merge(sort, numHits, topDocs);
+      return collectorManager.reduce(collectors);
     }
   }
 
@@ -515,7 +607,7 @@ public class IndexSearcher {
    */
   public Weight createNormalizedWeight(Query query, boolean needsScores) throws IOException {
     query = rewrite(query);
-    Weight weight = query.createWeight(this, needsScores);
+    Weight weight = createWeight(query, needsScores);
     float v = weight.getValueForNormalization();
     float norm = getSimilarity().queryNorm(v);
     if (Float.isInfinite(norm) || Float.isNaN(norm)) {
@@ -524,7 +616,21 @@ public class IndexSearcher {
     weight.normalize(norm, 1.0f);
     return weight;
   }
-  
+
+  /**
+   * Creates a {@link Weight} for the given query, potentially adding caching
+   * if possible and configured.
+   * @lucene.experimental
+   */
+  public Weight createWeight(Query query, boolean needsScores) throws IOException {
+    final QueryCache queryCache = this.queryCache;
+    Weight weight = query.createWeight(this, needsScores);
+    if (needsScores == false && queryCache != null) {
+      weight = queryCache.doCache(weight, queryCachingPolicy);
+    }
+    return weight;
+  }
+
   /**
    * Returns this searchers the top-level {@link IndexReaderContext}.
    * @see IndexReader#getContext()

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java Tue Mar 31 05:22:40 2015
@@ -144,17 +144,4 @@ public class MatchAllDocsQuery extends Q
     buffer.append(ToStringUtils.boost(getBoost()));
     return buffer.toString();
   }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!(o instanceof MatchAllDocsQuery))
-      return false;
-    MatchAllDocsQuery other = (MatchAllDocsQuery) o;
-    return this.getBoost() == other.getBoost();
-  }
-
-  @Override
-  public int hashCode() {
-    return Float.floatToIntBits(getBoost()) ^ 0x1AA71190;
-  }
 }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java Tue Mar 31 05:22:40 2015
@@ -358,7 +358,7 @@ public class MultiPhraseQuery extends Qu
   public boolean equals(Object o) {
     if (!(o instanceof MultiPhraseQuery)) return false;
     MultiPhraseQuery other = (MultiPhraseQuery)o;
-    return this.getBoost() == other.getBoost()
+    return super.equals(o)
       && this.slop == other.slop
       && termArraysEquals(this.termArrays, other.termArrays)
       && this.positions.equals(other.positions);
@@ -367,11 +367,10 @@ public class MultiPhraseQuery extends Qu
   /** Returns a hash code value for this object.*/
   @Override
   public int hashCode() {
-    return Float.floatToIntBits(getBoost())
+    return super.hashCode()
       ^ slop
       ^ termArraysHashCode()
-      ^ positions.hashCode()
-      ^ 0x4AC65113;
+      ^ positions.hashCode();
   }
   
   // Breakout calculation of the termArrays hashcode

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java Tue Mar 31 05:22:40 2015
@@ -39,17 +39,17 @@ import org.apache.lucene.util.AttributeS
  * matched.
  *
  * <p><b>NOTE</b>: if {@link #setRewriteMethod} is either
- * {@link #CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE} or {@link
- * #SCORING_BOOLEAN_QUERY_REWRITE}, you may encounter a
+ * {@link #CONSTANT_SCORE_BOOLEAN_REWRITE} or {@link
+ * #SCORING_BOOLEAN_REWRITE}, you may encounter a
  * {@link BooleanQuery.TooManyClauses} exception during
  * searching, which happens when the number of terms to be
  * searched exceeds {@link
  * BooleanQuery#getMaxClauseCount()}.  Setting {@link
- * #setRewriteMethod} to {@link #CONSTANT_SCORE_FILTER_REWRITE}
+ * #setRewriteMethod} to {@link #CONSTANT_SCORE_REWRITE}
  * prevents this.
  *
  * <p>The recommended rewrite method is {@link
- * #CONSTANT_SCORE_FILTER_REWRITE}: it doesn't spend CPU
+ * #CONSTANT_SCORE_REWRITE}: it doesn't spend CPU
  * computing unhelpful scores, and is the most
  * performant rewrite method given the query. If you
  * need scoring (like {@link FuzzyQuery}, use
@@ -58,12 +58,12 @@ import org.apache.lucene.util.AttributeS
  * and not hit this limitation.
  *
  * Note that org.apache.lucene.queryparser.classic.QueryParser produces
- * MultiTermQueries using {@link #CONSTANT_SCORE_FILTER_REWRITE}
+ * MultiTermQueries using {@link #CONSTANT_SCORE_REWRITE}
  * by default.
  */
 public abstract class MultiTermQuery extends Query {
   protected final String field;
-  protected RewriteMethod rewriteMethod = CONSTANT_SCORE_FILTER_REWRITE;
+  protected RewriteMethod rewriteMethod = CONSTANT_SCORE_REWRITE;
 
   /** Abstract class that defines how the query is rewritten. */
   public static abstract class RewriteMethod {
@@ -89,10 +89,10 @@ public abstract class MultiTermQuery ext
    *  exception.
    *
    *  @see #setRewriteMethod */
-  public static final RewriteMethod CONSTANT_SCORE_FILTER_REWRITE = new RewriteMethod() {
+  public static final RewriteMethod CONSTANT_SCORE_REWRITE = new RewriteMethod() {
     @Override
     public Query rewrite(IndexReader reader, MultiTermQuery query) {
-      Query result = new ConstantScoreQuery(new MultiTermQueryWrapperFilter<>(query));
+      Query result = new MultiTermQueryConstantScoreWrapper<>(query);
       result.setBoost(query.getBoost());
       return result;
     }
@@ -104,16 +104,16 @@ public abstract class MultiTermQuery ext
    *  query.  Note that typically such scores are
    *  meaningless to the user, and require non-trivial CPU
    *  to compute, so it's almost always better to use {@link
-   *  #CONSTANT_SCORE_FILTER_REWRITE} instead.
+   *  #CONSTANT_SCORE_REWRITE} instead.
    *
    *  <p><b>NOTE</b>: This rewrite method will hit {@link
    *  BooleanQuery.TooManyClauses} if the number of terms
    *  exceeds {@link BooleanQuery#getMaxClauseCount}.
    *
    *  @see #setRewriteMethod */
-  public final static RewriteMethod SCORING_BOOLEAN_QUERY_REWRITE = ScoringRewrite.SCORING_BOOLEAN_QUERY_REWRITE;
+  public final static RewriteMethod SCORING_BOOLEAN_REWRITE = ScoringRewrite.SCORING_BOOLEAN_REWRITE;
   
-  /** Like {@link #SCORING_BOOLEAN_QUERY_REWRITE} except
+  /** Like {@link #SCORING_BOOLEAN_REWRITE} except
    *  scores are not computed.  Instead, each matching
    *  document receives a constant score equal to the
    *  query's boost.
@@ -123,7 +123,7 @@ public abstract class MultiTermQuery ext
    *  exceeds {@link BooleanQuery#getMaxClauseCount}.
    *
    *  @see #setRewriteMethod */
-  public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE = ScoringRewrite.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE;
+  public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_REWRITE = ScoringRewrite.CONSTANT_SCORE_BOOLEAN_REWRITE;
 
   /**
    * A rewrite method that first translates each term into
@@ -288,7 +288,7 @@ public abstract class MultiTermQuery ext
     if (getClass() != obj.getClass())
       return false;
     MultiTermQuery other = (MultiTermQuery) obj;
-    if (Float.floatToIntBits(getBoost()) != Float.floatToIntBits(other.getBoost()))
+    if (!super.equals(obj))
       return false;
     if (!rewriteMethod.equals(other.rewriteMethod)) {
       return false;

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java Tue Mar 31 05:22:40 2015
@@ -41,9 +41,7 @@ import org.apache.lucene.index.Term; //
  * numeric values using {@link IntField}, {@link
  * FloatField}, {@link LongField} or {@link DoubleField} (expert: {@link
  * NumericTokenStream}).  If your terms are instead textual,
- * you should use {@link TermRangeQuery}.  {@link
- * NumericRangeFilter} is the filter equivalent of this
- * query.</p>
+ * you should use {@link TermRangeQuery}.</p>
  *
  * <p>You create a new NumericRangeQuery with the static
  * factory methods, eg:
@@ -72,7 +70,7 @@ import org.apache.lucene.index.Term; //
  * details.
  *
  * <p>This query defaults to {@linkplain
- * MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE}.
+ * MultiTermQuery#CONSTANT_SCORE_REWRITE}.
  * With precision steps of &le;4, this query can be run with
  * one of the BooleanQuery rewrite methods without changing
  * BooleanQuery's default max clause count.

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java Tue Mar 31 05:22:40 2015
@@ -429,7 +429,7 @@ public class PhraseQuery extends Query {
     if (!(o instanceof PhraseQuery))
       return false;
     PhraseQuery other = (PhraseQuery)o;
-    return (this.getBoost() == other.getBoost())
+    return super.equals(o)
       && (this.slop == other.slop)
       &&  this.terms.equals(other.terms)
       && this.positions.equals(other.positions);
@@ -438,7 +438,7 @@ public class PhraseQuery extends Query {
   /** Returns a hash code value for this object.*/
   @Override
   public int hashCode() {
-    return Float.floatToIntBits(getBoost())
+    return super.hashCode()
       ^ slop
       ^ terms.hashCode()
       ^ positions.hashCode();

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PrefixQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PrefixQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PrefixQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/PrefixQuery.java Tue Mar 31 05:22:40 2015
@@ -19,41 +19,52 @@ package org.apache.lucene.search;
 
 import java.io.IOException;
 
-import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.util.AttributeSource;
+import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.ToStringUtils;
+import org.apache.lucene.util.automaton.Automaton;
 
 /** A Query that matches documents containing terms with a specified prefix. A PrefixQuery
  * is built by QueryParser for input like <code>app*</code>.
  *
  * <p>This query uses the {@link
- * MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE}
+ * MultiTermQuery#CONSTANT_SCORE_REWRITE}
  * rewrite method. */
-public class PrefixQuery extends MultiTermQuery {
-  private Term prefix;
+public class PrefixQuery extends AutomatonQuery {
 
   /** Constructs a query for terms starting with <code>prefix</code>. */
   public PrefixQuery(Term prefix) {
-    super(prefix.field());
-    this.prefix = prefix;
+    // It's OK to pass unlimited maxDeterminizedStates: the automaton is born small and determinized:
+    super(prefix, toAutomaton(prefix.bytes()), Integer.MAX_VALUE, true);
+    if (prefix == null) {
+      throw new NullPointerException("prefix cannot be null");
+    }
   }
 
-  /** Returns the prefix of this query. */
-  public Term getPrefix() { return prefix; }
-  
-  @Override  
-  protected TermsEnum getTermsEnum(Terms terms, AttributeSource atts) throws IOException {
-    TermsEnum tenum = terms.iterator(null);
-    
-    if (prefix.bytes().length == 0) {
-      // no prefix -- match all terms for this field:
-      return tenum;
+  /** Build an automaton accepting all terms with the specified prefix. */
+  public static Automaton toAutomaton(BytesRef prefix) {
+    Automaton automaton = new Automaton();
+    int lastState = automaton.createState();
+    for(int i=0;i<prefix.length;i++) {
+      int state = automaton.createState();
+      automaton.addTransition(lastState, state, prefix.bytes[prefix.offset+i]&0xff);
+      lastState = state;
     }
-    return new PrefixTermsEnum(tenum, prefix.bytes());
+    automaton.setAccept(lastState, true);
+    automaton.addTransition(lastState, lastState, 0, 255);
+    automaton.finishState();
+    assert automaton.isDeterministic();
+    return automaton;
   }
 
+  /** Returns the prefix of this query. */
+  public Term getPrefix() {
+    return term;
+  }
+  
   /** Prints a user-readable version of this query. */
   @Override
   public String toString(String field) {
@@ -62,7 +73,7 @@ public class PrefixQuery extends MultiTe
       buffer.append(getField());
       buffer.append(":");
     }
-    buffer.append(prefix.text());
+    buffer.append(term.text());
     buffer.append('*');
     buffer.append(ToStringUtils.boost(getBoost()));
     return buffer.toString();
@@ -72,25 +83,23 @@ public class PrefixQuery extends MultiTe
   public int hashCode() {
     final int prime = 31;
     int result = super.hashCode();
-    result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
+    result = prime * result + term.hashCode();
     return result;
   }
 
   @Override
   public boolean equals(Object obj) {
-    if (this == obj)
+    if (this == obj) {
       return true;
-    if (!super.equals(obj))
-      return false;
-    if (getClass() != obj.getClass())
+    }
+    if (!super.equals(obj)) {
       return false;
+    }
+    // super.equals() ensures we are the same class
     PrefixQuery other = (PrefixQuery) obj;
-    if (prefix == null) {
-      if (other.prefix != null)
-        return false;
-    } else if (!prefix.equals(other.prefix))
+    if (!term.equals(other.term)) {
       return false;
+    }
     return true;
   }
-
 }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Query.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Query.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Query.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Query.java Tue Mar 31 05:22:40 2015
@@ -97,7 +97,7 @@ public abstract class Query implements C
    */
   public void extractTerms(Set<Term> terms) {
     // needs to be implemented by query subclasses
-    throw new UnsupportedOperationException();
+    throw new UnsupportedOperationException(getClass().getName());
   }
 
   /** Returns a clone of this query. */
@@ -112,10 +112,7 @@ public abstract class Query implements C
 
   @Override
   public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + Float.floatToIntBits(boost);
-    return result;
+    return Float.floatToIntBits(getBoost()) ^ getClass().hashCode();
   }
 
   @Override

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java Tue Mar 31 05:22:40 2015
@@ -17,12 +17,12 @@ package org.apache.lucene.search;
  * limitations under the License.
  */
 
-import org.apache.lucene.index.PostingsEnum;
+import java.io.IOException;
+
+import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.util.Bits;
 
-import java.io.IOException;
-
 /** 
  * Constrains search results to only match those which also match a provided
  * query.  
@@ -44,6 +44,13 @@ public class QueryWrapperFilter extends
     this.query = query;
   }
   
+  @Override
+  public Query rewrite(IndexReader reader) throws IOException {
+    ConstantScoreQuery rewritten = new ConstantScoreQuery(query);
+    rewritten.setBoost(0);
+    return rewritten;
+  }
+  
   /** returns the inner Query */
   public final Query getQuery() {
     return query;

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java Tue Mar 31 05:22:40 2015
@@ -27,22 +27,22 @@ import java.util.Collections;
  * This <code>Scorer</code> implements {@link Scorer#advance(int)},
  * and it uses the advance() on the given scorers.
  */
-class ReqExclScorer extends FilterScorer {
+class ReqExclScorer extends Scorer {
 
   private final Scorer reqScorer;
   // approximations of the scorers, or the scorers themselves if they don't support approximations
   private final DocIdSetIterator reqApproximation;
   private final DocIdSetIterator exclApproximation;
   // two-phase views of the scorers, or null if they do not support approximations
-  private final TwoPhaseDocIdSetIterator reqTwoPhaseIterator;
-  private final TwoPhaseDocIdSetIterator exclTwoPhaseIterator;
+  private final TwoPhaseIterator reqTwoPhaseIterator;
+  private final TwoPhaseIterator exclTwoPhaseIterator;
 
   /** Construct a <code>ReqExclScorer</code>.
    * @param reqScorer The scorer that must match, except where
    * @param exclScorer indicates exclusion.
    */
   public ReqExclScorer(Scorer reqScorer, Scorer exclScorer) {
-    super(reqScorer);
+    super(reqScorer.weight);
     this.reqScorer = reqScorer;
     reqTwoPhaseIterator = reqScorer.asTwoPhaseIterator();
     if (reqTwoPhaseIterator == null) {
@@ -63,9 +63,9 @@ class ReqExclScorer extends FilterScorer
     return toNonExcluded(reqApproximation.nextDoc());
   }
 
-  /** Confirms whether or not the given {@link TwoPhaseDocIdSetIterator}
+  /** Confirms whether or not the given {@link TwoPhaseIterator}
    *  matches on the current document. */
-  private static boolean matches(TwoPhaseDocIdSetIterator it) throws IOException {
+  private static boolean matches(TwoPhaseIterator it) throws IOException {
     return it == null || it.matches();
   }
 
@@ -76,8 +76,8 @@ class ReqExclScorer extends FilterScorer
    *   - it does NOT call matches() on req if the excl approximation is exact
    *     and is on the same doc ID as the req approximation */
   private static boolean matches(int doc, int exclDoc,
-      TwoPhaseDocIdSetIterator reqTwoPhaseIterator,
-      TwoPhaseDocIdSetIterator exclTwoPhaseIterator) throws IOException {
+      TwoPhaseIterator reqTwoPhaseIterator,
+      TwoPhaseIterator exclTwoPhaseIterator) throws IOException {
     assert exclDoc >= doc;
     if (doc == exclDoc && matches(exclTwoPhaseIterator)) {
       return false;
@@ -106,10 +106,16 @@ class ReqExclScorer extends FilterScorer
     return reqScorer.docID();
   }
 
-  /** Returns the score of the current document matching the query.
-   * Initially invalid, until {@link #nextDoc()} is called the first time.
-   * @return The score of the required scorer.
-   */
+  @Override
+  public int freq() throws IOException {
+    return reqScorer.freq();
+  }
+
+  @Override
+  public long cost() {
+    return reqScorer.cost();
+  }
+
   @Override
   public float score() throws IOException {
     return reqScorer.score(); // reqScorer may be null when next() or skipTo() already return false
@@ -126,16 +132,11 @@ class ReqExclScorer extends FilterScorer
   }
 
   @Override
-  public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
+  public TwoPhaseIterator asTwoPhaseIterator() {
     if (reqTwoPhaseIterator == null) {
       return null;
     }
-    return new TwoPhaseDocIdSetIterator() {
-
-      @Override
-      public DocIdSetIterator approximation() {
-        return reqApproximation;
-      }
+    return new TwoPhaseIterator(reqApproximation) {
 
       @Override
       public boolean matches() throws IOException {

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java Tue Mar 31 05:22:40 2015
@@ -48,7 +48,7 @@ class ReqOptSumScorer extends Scorer {
   }
 
   @Override
-  public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
+  public TwoPhaseIterator asTwoPhaseIterator() {
     return reqScorer.asTwoPhaseIterator();
   }
 

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Scorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Scorer.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Scorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/Scorer.java Tue Mar 31 05:22:40 2015
@@ -102,12 +102,12 @@ public abstract class Scorer extends Doc
   }
 
   /**
-   * Optional method: Return a {@link TwoPhaseDocIdSetIterator} view of this
+   * Optional method: Return a {@link TwoPhaseIterator} view of this
    * {@link Scorer}. A return value of {@code null} indicates that
    * two-phase iteration is not supported.
    *
-   * Note that the returned {@link TwoPhaseDocIdSetIterator}'s
-   * {@link TwoPhaseDocIdSetIterator#approximation() approximation} must
+   * Note that the returned {@link TwoPhaseIterator}'s
+   * {@link TwoPhaseIterator#approximation() approximation} must
    * advance synchronously with this iterator: advancing the approximation must
    * advance this iterator and vice-versa.
    *
@@ -116,7 +116,7 @@ public abstract class Scorer extends Doc
    *
    * The default implementation returns {@code null}.
    */
-  public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
+  public TwoPhaseIterator asTwoPhaseIterator() {
     return null;
   }
 }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScorerPriorityQueue.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScorerPriorityQueue.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScorerPriorityQueue.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScorerPriorityQueue.java Tue Mar 31 05:22:40 2015
@@ -40,7 +40,7 @@ final class ScorerPriorityQueue implemen
     final DocIdSetIterator approximation;
     // A two-phase view of the scorer, or null if the scorer does not support
     // two-phase iteration
-    final TwoPhaseDocIdSetIterator twoPhaseView;
+    final TwoPhaseIterator twoPhaseView;
 
     ScorerWrapper(Scorer scorer) {
       this.scorer = scorer;

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java Tue Mar 31 05:22:40 2015
@@ -45,14 +45,14 @@ public abstract class ScoringRewrite<Q e
    *  query.  Note that typically such scores are
    *  meaningless to the user, and require non-trivial CPU
    *  to compute, so it's almost always better to use {@link
-   *  MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE} instead.
+   *  MultiTermQuery#CONSTANT_SCORE_REWRITE} instead.
    *
    *  <p><b>NOTE</b>: This rewrite method will hit {@link
    *  BooleanQuery.TooManyClauses} if the number of terms
    *  exceeds {@link BooleanQuery#getMaxClauseCount}.
    *
    *  @see MultiTermQuery#setRewriteMethod */
-  public final static ScoringRewrite<BooleanQuery> SCORING_BOOLEAN_QUERY_REWRITE = new ScoringRewrite<BooleanQuery>() {
+  public final static ScoringRewrite<BooleanQuery> SCORING_BOOLEAN_REWRITE = new ScoringRewrite<BooleanQuery>() {
     @Override
     protected BooleanQuery getTopLevelQuery() {
       return new BooleanQuery(true);
@@ -73,7 +73,7 @@ public abstract class ScoringRewrite<Q e
     }
   };
   
-  /** Like {@link #SCORING_BOOLEAN_QUERY_REWRITE} except
+  /** Like {@link #SCORING_BOOLEAN_REWRITE} except
    *  scores are not computed.  Instead, each matching
    *  document receives a constant score equal to the
    *  query's boost.
@@ -83,10 +83,10 @@ public abstract class ScoringRewrite<Q e
    *  exceeds {@link BooleanQuery#getMaxClauseCount}.
    *
    *  @see MultiTermQuery#setRewriteMethod */
-  public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE = new RewriteMethod() {
+  public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_REWRITE = new RewriteMethod() {
     @Override
     public Query rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
-      final BooleanQuery bq = SCORING_BOOLEAN_QUERY_REWRITE.rewrite(reader, query);
+      final BooleanQuery bq = SCORING_BOOLEAN_REWRITE.rewrite(reader, query);
       // strip the scores off
       final Query result = new ConstantScoreQuery(bq);
       result.setBoost(query.getBoost());

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java Tue Mar 31 05:22:40 2015
@@ -589,13 +589,8 @@ final class SloppyPhraseScorer extends S
   public String toString() { return "scorer(" + weight + ")"; }
 
   @Override
-  public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
-    return new TwoPhaseDocIdSetIterator() {
-      @Override
-      public DocIdSetIterator approximation() {
-        return conjunction;
-      }
-
+  public TwoPhaseIterator asTwoPhaseIterator() {
+    return new TwoPhaseIterator(conjunction) {
       @Override
       public boolean matches() throws IOException {
         sloppyFreq = phraseFreq(); // check for phrase

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermQuery.java Tue Mar 31 05:22:40 2015
@@ -210,14 +210,11 @@ public class TermQuery extends Query {
   public boolean equals(Object o) {
     if (!(o instanceof TermQuery)) return false;
     TermQuery other = (TermQuery) o;
-    return (this.getBoost() == other.getBoost())
-        && this.term.equals(other.term);
+    return super.equals(o) && this.term.equals(other.term);
   }
-  
-  /** Returns a hash code value for this object. */
+
   @Override
   public int hashCode() {
-    return Float.floatToIntBits(getBoost()) ^ term.hashCode();
+    return super.hashCode() ^ term.hashCode();
   }
-  
 }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermRangeQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermRangeQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermRangeQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/TermRangeQuery.java Tue Mar 31 05:22:40 2015
@@ -35,7 +35,7 @@ import org.apache.lucene.util.ToStringUt
  * for numerical ranges; use {@link NumericRangeQuery} instead.
  *
  * <p>This query uses the {@link
- * MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE}
+ * MultiTermQuery#CONSTANT_SCORE_REWRITE}
  * rewrite method.
  * @since 2.9
  */

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/WildcardQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/WildcardQuery.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/WildcardQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/WildcardQuery.java Tue Mar 31 05:22:40 2015
@@ -35,7 +35,7 @@ import org.apache.lucene.util.automaton.
  * a Wildcard term should not start with the wildcard <code>*</code>
  * 
  * <p>This query uses the {@link
- * MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE}
+ * MultiTermQuery#CONSTANT_SCORE_REWRITE}
  * rewrite method.
  *
  * @see AutomatonQuery

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/similarities/DefaultSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/similarities/DefaultSimilarity.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/similarities/DefaultSimilarity.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/similarities/DefaultSimilarity.java Tue Mar 31 05:22:40 2015
@@ -29,7 +29,7 @@ import org.apache.lucene.util.SmallFloat
  * {@link #decodeNormValue(long) decoded} back to a float <i>norm</i> value.
  * This encoding/decoding, while reducing index size, comes with the price of
  * precision loss - it is not guaranteed that <i>decode(encode(x)) = x</i>. For
- * instance, <i>decode(encode(0.89)) = 0.75</i>.
+ * instance, <i>decode(encode(0.89)) = 0.875</i>.
  * <p>
  * Compression of norm values to a single byte saves memory at search time,
  * because once a field is referenced at search time, its norms - for all

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/ByteBufferIndexInput.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/ByteBufferIndexInput.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/ByteBufferIndexInput.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/ByteBufferIndexInput.java Tue Mar 31 05:22:40 2015
@@ -281,10 +281,9 @@ abstract class ByteBufferIndexInput exte
     }
 
     final ByteBuffer newBuffers[] = buildSlice(buffers, offset, length);
-    final String newResourceDescription = (sliceDescription == null) ? toString() : (toString() + " [slice=" + sliceDescription + "]");
     final int ofs = (int) (offset & chunkSizeMask);
     
-    final ByteBufferIndexInput clone = newCloneInstance(newResourceDescription, newBuffers, ofs, length);
+    final ByteBufferIndexInput clone = newCloneInstance(getFullSliceDescription(sliceDescription), newBuffers, ofs, length);
     clone.isClone = true;
 
     // register the new clone in our clone list to clean it up on closing:
@@ -384,6 +383,7 @@ abstract class ByteBufferIndexInput exte
    * Pass in an implementation of this interface to cleanup ByteBuffers.
    * MMapDirectory implements this to allow unmapping of bytebuffers with private Java APIs.
    */
+  @FunctionalInterface
   static interface BufferCleaner {
     void freeBuffer(ByteBufferIndexInput parent, ByteBuffer b) throws IOException;
   }

Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/DataInput.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/DataInput.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/DataInput.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/store/DataInput.java Tue Mar 31 05:22:40 2015
@@ -19,10 +19,13 @@ package org.apache.lucene.store;
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 import org.apache.lucene.util.BitUtil;
 
@@ -254,7 +257,11 @@ public abstract class DataInput implemen
   }
 
   /** Reads a Map&lt;String,String&gt; previously written
-   *  with {@link DataOutput#writeStringStringMap(Map)}. */
+   *  with {@link DataOutput#writeStringStringMap(Map)}. 
+   *  @deprecated Only for reading existing formats. Encode maps with 
+   *  {@link DataOutput#writeMapOfStrings(Map)} instead.
+   */
+  @Deprecated
   public Map<String,String> readStringStringMap() throws IOException {
     final Map<String,String> map = new HashMap<>();
     final int count = readInt();
@@ -266,9 +273,34 @@ public abstract class DataInput implemen
 
     return map;
   }
+  
+  /** 
+   * Reads a Map&lt;String,String&gt; previously written
+   * with {@link DataOutput#writeMapOfStrings(Map)}. 
+   * @return An immutable map containing the written contents.
+   */
+  public Map<String,String> readMapOfStrings() throws IOException {
+    int count = readVInt();
+    if (count == 0) {
+      return Collections.emptyMap();
+    } else if (count == 1) {
+      return Collections.singletonMap(readString(), readString());
+    } else {
+      Map<String,String> map = count > 10 ? new HashMap<>() : new TreeMap<>();
+      for (int i = 0; i < count; i++) {
+        final String key = readString();
+        final String val = readString();
+        map.put(key, val);
+      }
+      return Collections.unmodifiableMap(map);
+    }
+  }
 
   /** Reads a Set&lt;String&gt; previously written
-   *  with {@link DataOutput#writeStringSet(Set)}. */
+   *  with {@link DataOutput#writeStringSet(Set)}. 
+   *  @deprecated Only for reading existing formats. Encode maps with 
+   *  {@link DataOutput#writeSetOfStrings(Set)} instead. */
+  @Deprecated
   public Set<String> readStringSet() throws IOException {
     final Set<String> set = new HashSet<>();
     final int count = readInt();
@@ -278,6 +310,26 @@ public abstract class DataInput implemen
 
     return set;
   }
+  
+  /** 
+   * Reads a Set&lt;String&gt; previously written
+   * with {@link DataOutput#writeSetOfStrings(Set)}. 
+   * @return An immutable set containing the written contents.
+   */
+  public Set<String> readSetOfStrings() throws IOException {
+    int count = readVInt();
+    if (count == 0) {
+      return Collections.emptySet();
+    } else if (count == 1) {
+      return Collections.singleton(readString());
+    } else {
+      Set<String> set = count > 10 ? new HashSet<>() : new TreeSet<>();
+      for (int i = 0; i < count; i++) {
+        set.add(readString());
+      }
+      return Collections.unmodifiableSet(set);
+    }
+  }
 
   /**
    * Skip over <code>numBytes</code> bytes. The contract on this method is that it