You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2018/05/08 21:15:06 UTC

[20/50] [abbrv] lucene-solr:jira/solr-11779: LUCENE-8142: Make postings APIs expose raw impacts rather than scores.

LUCENE-8142: Make postings APIs expose raw impacts rather than scores.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/af680af7
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/af680af7
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/af680af7

Branch: refs/heads/jira/solr-11779
Commit: af680af77f3f80c779e038a0ad8a136c9dcb9f5d
Parents: 555b7ef
Author: Adrien Grand <jp...@gmail.com>
Authored: Wed May 2 11:52:36 2018 +0200
Committer: Adrien Grand <jp...@gmail.com>
Committed: Wed May 2 14:49:32 2018 +0200

----------------------------------------------------------------------
 .../codecs/blockterms/BlockTermsReader.java     |   7 +-
 .../blocktreeords/OrdsIntersectTermsEnum.java   |   5 +-
 .../blocktreeords/OrdsSegmentTermsEnum.java     |   5 +-
 .../bloom/BloomFilteringPostingsFormat.java     |   7 +-
 .../codecs/memory/DirectPostingsFormat.java     |   9 +-
 .../lucene/codecs/memory/FSTOrdTermsReader.java |   7 +-
 .../lucene/codecs/memory/FSTTermsReader.java    |   5 +-
 .../codecs/memory/MemoryDocValuesProducer.java  |   7 +-
 .../codecs/memory/MemoryPostingsFormat.java     |   7 +-
 .../simpletext/SimpleTextFieldsReader.java      |   5 +-
 .../simpletext/SimpleTextTermVectorsReader.java |   7 +-
 .../codecs/CompetitiveFreqNormAccumulator.java  | 163 -------------
 .../codecs/CompetitiveImpactAccumulator.java    | 127 ++++++++++
 .../lucene/codecs/PostingsReaderBase.java       |   3 +-
 .../codecs/blocktree/IntersectTermsEnum.java    |   5 +-
 .../codecs/blocktree/SegmentTermsEnum.java      |   5 +-
 .../CompressingTermVectorsReader.java           |   6 +-
 .../codecs/lucene50/Lucene50PostingsReader.java |  39 ++-
 .../codecs/lucene50/Lucene50PostingsWriter.java |   4 +-
 .../lucene50/Lucene50ScoreSkipReader.java       | 141 +++++++----
 .../codecs/lucene50/Lucene50SkipReader.java     |   3 +-
 .../codecs/lucene50/Lucene50SkipWriter.java     |  36 +--
 .../lucene70/Lucene70DocValuesProducer.java     |   3 +-
 .../apache/lucene/document/FeatureQuery.java    |   8 +-
 .../org/apache/lucene/index/CheckIndex.java     | 152 ++++++++----
 .../apache/lucene/index/FilterLeafReader.java   |   5 +-
 .../apache/lucene/index/FilteredTermsEnum.java  |   5 +-
 .../org/apache/lucene/index/FreqProxFields.java |   3 +-
 .../java/org/apache/lucene/index/Impact.java    |  61 +++++
 .../java/org/apache/lucene/index/Impacts.java   |  51 ++++
 .../org/apache/lucene/index/ImpactsEnum.java    |  39 +--
 .../org/apache/lucene/index/MultiTermsEnum.java |   5 +-
 .../apache/lucene/index/SlowImpactsEnum.java    |  39 ++-
 .../lucene/index/SortedDocValuesTermsEnum.java  |   3 +-
 .../index/SortedSetDocValuesTermsEnum.java      |   3 +-
 .../java/org/apache/lucene/index/TermsEnum.java |   7 +-
 .../search/BlockMaxConjunctionScorer.java       |   3 +
 .../apache/lucene/search/FuzzyTermsEnum.java    |   5 +-
 .../org/apache/lucene/search/MaxScoreCache.java | 138 +++++++++++
 .../java/org/apache/lucene/search/Scorer.java   |   4 +-
 .../org/apache/lucene/search/TermScorer.java    |  40 ++-
 .../org/apache/lucene/search/WANDScorer.java    |   1 +
 .../TestCompetitiveFreqNormAccumulator.java     |  44 ++--
 .../lucene50/TestBlockPostingsFormat.java       |  57 +++--
 .../org/apache/lucene/index/TestCodecs.java     |   3 +-
 .../apache/lucene/index/memory/MemoryIndex.java |   5 +-
 .../idversion/IDVersionPostingsReader.java      |   5 +-
 .../idversion/IDVersionSegmentTermsEnum.java    |   5 +-
 .../codecs/ramonly/RAMOnlyPostingsFormat.java   |   5 +-
 .../lucene/index/AssertingLeafReader.java       |  55 ++++-
 .../lucene/index/RandomPostingsTester.java      | 241 ++++++++++---------
 .../apache/lucene/search/AssertingScorer.java   |   1 +
 .../org/apache/lucene/search/CheckHits.java     |   2 +-
 .../org/apache/solr/query/SolrRangeQuery.java   |   5 +-
 .../apache/solr/uninverting/DocTermOrds.java    |   5 +-
 55 files changed, 1004 insertions(+), 607 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java
index a405ccb..4260dc3 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java
@@ -30,16 +30,15 @@ import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.codecs.FieldsProducer;
 import org.apache.lucene.codecs.PostingsReaderBase;
 import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.FieldInfo;
 import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.IndexFileNames;
 import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.SegmentReadState;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.Accountable;
@@ -661,9 +660,9 @@ public class BlockTermsReader extends FieldsProducer {
       }
 
       @Override
-      public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+      public ImpactsEnum impacts(int flags) throws IOException {
         decodeMetaData();
-        return postingsReader.impacts(fieldInfo, state, scorer, flags);
+        return postingsReader.impacts(fieldInfo, state, flags);
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java b/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java
index fdb54df..a892549 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java
@@ -24,7 +24,6 @@ import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.BytesRef;
@@ -208,9 +207,9 @@ final class OrdsIntersectTermsEnum extends TermsEnum {
   }
 
   @Override
-  public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+  public ImpactsEnum impacts(int flags) throws IOException {
     currentFrame.decodeMetaData();
-    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.termState, scorer, flags);
+    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.termState, flags);
   }
 
   private int getState() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java b/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java
index 8d55a1d..bd67adc 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java
@@ -29,7 +29,6 @@ import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.ArrayUtil;
@@ -936,7 +935,7 @@ public final class OrdsSegmentTermsEnum extends TermsEnum {
   }
 
   @Override
-  public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+  public ImpactsEnum impacts(int flags) throws IOException {
     assert !eof;
     //if (DEBUG) {
     //System.out.println("BTTR.docs seg=" + segment);
@@ -945,7 +944,7 @@ public final class OrdsSegmentTermsEnum extends TermsEnum {
     //if (DEBUG) {
     //System.out.println("  state=" + currentFrame.state);
     //}
-    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.state, scorer, flags);
+    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.state, flags);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java b/lucene/codecs/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java
index b826102..28febf3 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java
@@ -32,16 +32,15 @@ import org.apache.lucene.codecs.FieldsProducer;
 import org.apache.lucene.codecs.NormsProducer;
 import org.apache.lucene.codecs.PostingsFormat;
 import org.apache.lucene.codecs.bloom.FuzzySet.ContainsResult;
-import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.FieldInfo;
 import org.apache.lucene.index.Fields;
 import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.IndexFileNames;
+import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.SegmentReadState;
 import org.apache.lucene.index.SegmentWriteState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.DataOutput;
 import org.apache.lucene.store.IndexOutput;
@@ -375,8 +374,8 @@ public final class BloomFilteringPostingsFormat extends PostingsFormat {
       }
 
       @Override
-      public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-        return delegate().impacts(scorer, flags);
+      public ImpactsEnum impacts(int flags) throws IOException {
+        return delegate().impacts(flags);
       }
     }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java
index 901e1ae..6c8853d 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java
@@ -39,7 +39,6 @@ import org.apache.lucene.index.SlowImpactsEnum;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.RAMOutputStream;
 import org.apache.lucene.util.Accountable;
@@ -948,8 +947,8 @@ public final class DirectPostingsFormat extends PostingsFormat {
       }
 
       @Override
-      public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-        return new SlowImpactsEnum(postings(null, flags), scorer.score(Float.MAX_VALUE, 1));
+      public ImpactsEnum impacts(int flags) throws IOException {
+        return new SlowImpactsEnum(postings(null, flags));
       }
     }
 
@@ -1503,8 +1502,8 @@ public final class DirectPostingsFormat extends PostingsFormat {
       }
 
       @Override
-      public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-        return new SlowImpactsEnum(postings(null, flags), scorer.score(Float.MAX_VALUE, 1));
+      public ImpactsEnum impacts(int flags) throws IOException {
+        return new SlowImpactsEnum(postings(null, flags));
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTOrdTermsReader.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTOrdTermsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTOrdTermsReader.java
index 4ecf4d6..2b948ff 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTOrdTermsReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTOrdTermsReader.java
@@ -31,18 +31,17 @@ import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.codecs.FieldsProducer;
 import org.apache.lucene.codecs.PostingsReaderBase;
 import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.FieldInfo;
 import org.apache.lucene.index.FieldInfos;
 import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.IndexFileNames;
 import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.SegmentInfo;
 import org.apache.lucene.index.SegmentReadState;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.IndexInput;
@@ -435,9 +434,9 @@ public class FSTOrdTermsReader extends FieldsProducer {
       }
 
       @Override
-      public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+      public ImpactsEnum impacts(int flags) throws IOException {
         decodeMetaData();
-        return postingsReader.impacts(fieldInfo, state, scorer, flags);
+        return postingsReader.impacts(fieldInfo, state, flags);
       }
 
       // TODO: this can be achieved by making use of Util.getByOutput()

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsReader.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsReader.java
index b1b61e1..7afbc7c 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsReader.java
@@ -42,7 +42,6 @@ import org.apache.lucene.index.SegmentReadState;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.Accountable;
@@ -301,9 +300,9 @@ public class FSTTermsReader extends FieldsProducer {
       }
 
       @Override
-      public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+      public ImpactsEnum impacts(int flags) throws IOException {
         decodeMetaData();
-        return postingsReader.impacts(fieldInfo, state, scorer, flags);
+        return postingsReader.impacts(fieldInfo, state, flags);
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
index 855002c..ac81360 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
@@ -29,7 +29,6 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.codecs.DocValuesProducer;
 import org.apache.lucene.index.*;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.IndexInput;
@@ -44,11 +43,11 @@ import org.apache.lucene.util.IntsRef;
 import org.apache.lucene.util.IntsRefBuilder;
 import org.apache.lucene.util.PagedBytes;
 import org.apache.lucene.util.RamUsageEstimator;
-import org.apache.lucene.util.fst.BytesRefFSTEnum.InputOutput;
 import org.apache.lucene.util.fst.BytesRefFSTEnum;
+import org.apache.lucene.util.fst.BytesRefFSTEnum.InputOutput;
+import org.apache.lucene.util.fst.FST;
 import org.apache.lucene.util.fst.FST.Arc;
 import org.apache.lucene.util.fst.FST.BytesReader;
-import org.apache.lucene.util.fst.FST;
 import org.apache.lucene.util.fst.PositiveIntOutputs;
 import org.apache.lucene.util.fst.Util;
 import org.apache.lucene.util.packed.BlockPackedReader;
@@ -871,7 +870,7 @@ class MemoryDocValuesProducer extends DocValuesProducer {
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+    public ImpactsEnum impacts(int flags) throws IOException {
       throw new UnsupportedOperationException();
     }
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java
index 0df7d92..2433de7 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java
@@ -31,19 +31,18 @@ import org.apache.lucene.codecs.NormsProducer;
 import org.apache.lucene.codecs.PostingsFormat;
 import org.apache.lucene.codecs.TermStats;
 import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.FieldInfo;
 import org.apache.lucene.index.FieldInfos;
 import org.apache.lucene.index.Fields;
 import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.IndexFileNames;
 import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.SegmentReadState;
 import org.apache.lucene.index.SegmentWriteState;
 import org.apache.lucene.index.SlowImpactsEnum;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.IOContext;
@@ -819,8 +818,8 @@ public final class MemoryPostingsFormat extends PostingsFormat {
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-      return new SlowImpactsEnum(postings(null, flags), scorer.score(Float.MAX_VALUE, 1));
+    public ImpactsEnum impacts(int flags) throws IOException {
+      return new SlowImpactsEnum(postings(null, flags));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java
index cbd79de..743dc4f 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java
@@ -36,7 +36,6 @@ import org.apache.lucene.index.SegmentReadState;
 import org.apache.lucene.index.SlowImpactsEnum;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.BufferedChecksumIndexInput;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.IndexInput;
@@ -234,8 +233,8 @@ class SimpleTextFieldsReader extends FieldsProducer {
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-      return new SlowImpactsEnum(postings(null, flags), scorer.score(Float.MAX_VALUE, 1));
+    public ImpactsEnum impacts(int flags) throws IOException {
+      return new SlowImpactsEnum(postings(null, flags));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
index ee0757d..a306e8c 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
@@ -25,15 +25,14 @@ import java.util.SortedMap;
 import java.util.TreeMap;
 
 import org.apache.lucene.codecs.TermVectorsReader;
-import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.Fields;
 import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.IndexFileNames;
+import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.SegmentInfo;
 import org.apache.lucene.index.SlowImpactsEnum;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.BufferedChecksumIndexInput;
 import org.apache.lucene.store.ChecksumIndexInput;
@@ -414,8 +413,8 @@ public class SimpleTextTermVectorsReader extends TermVectorsReader {
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-      return new SlowImpactsEnum(postings(null, PostingsEnum.FREQS), scorer.score(Float.MAX_VALUE, 1));
+    public ImpactsEnum impacts(int flags) throws IOException {
+      return new SlowImpactsEnum(postings(null, PostingsEnum.FREQS));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveFreqNormAccumulator.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveFreqNormAccumulator.java b/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveFreqNormAccumulator.java
deleted file mode 100644
index 3dd9d35..0000000
--- a/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveFreqNormAccumulator.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.codecs;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * This class accumulates the (freq, norm) pairs that may produce competitive scores.
- */
-public final class CompetitiveFreqNormAccumulator {
-
-  // We speed up accumulation for common norm values by first computing
-  // the max freq for all norms in -128..127
-  private final int[] maxFreqs;
-  private boolean dirty;
-  private final TreeSet<FreqAndNorm> freqNormPairs;
-
-  /** Sole constructor. */
-  public CompetitiveFreqNormAccumulator() {
-    maxFreqs = new int[256];
-    Comparator<FreqAndNorm> comparator = new Comparator<CompetitiveFreqNormAccumulator.FreqAndNorm>() {
-      @Override
-      public int compare(FreqAndNorm o1, FreqAndNorm o2) {
-        // greater freqs compare greater
-        int cmp = Integer.compare(o1.freq, o2.freq);
-        if (cmp == 0) {
-          // greater norms compare lower
-          cmp = Long.compareUnsigned(o2.norm, o1.norm);
-        }
-        return cmp;
-      }
-    };
-    freqNormPairs = new TreeSet<>(comparator);
-  }
-
-  /** Reset to the same state it was in after creation. */
-  public void clear() {
-    Arrays.fill(maxFreqs, 0);
-    dirty = false;
-    freqNormPairs.clear();
-  }
-
-  /**
-   * A (freq, norm) pair.
-   */
-  public static class FreqAndNorm {
-    /** Doc-term frequency. */
-    public final int freq;
-    /** Normalization factor. */
-    public final long norm;
-
-    /** Sole constructor. */
-    public FreqAndNorm(int freq, long norm) {
-      this.freq = freq;
-      this.norm = norm;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj == null || obj instanceof FreqAndNorm == false) {
-        return false;
-      }
-      FreqAndNorm that = (FreqAndNorm) obj;
-      return freq == that.freq && norm == that.norm;
-    }
-
-    @Override
-    public int hashCode() {
-      int h = getClass().hashCode();
-      h = 31 * h + freq;
-      h = 31 * h + Long.hashCode(norm);
-      return h;
-    }
-
-    @Override
-    public String toString() {
-      return "{" + freq + "," + norm + "}";
-    }
-  }
-
-  /** Accumulate a (freq,norm) pair, updating this structure if there is no
-   *  equivalent or more competitive entry already. */
-  public void add(int freq, long norm) {
-    if (norm >= Byte.MIN_VALUE && norm <= Byte.MAX_VALUE) {
-      int index = Byte.toUnsignedInt((byte) norm);
-      maxFreqs[index] = Math.max(maxFreqs[index], freq); 
-      dirty = true;
-    } else {
-      add(new FreqAndNorm(freq, norm));
-    }
-  }
-
-  /** Merge {@code acc} into this. */
-  public void addAll(CompetitiveFreqNormAccumulator acc) {
-    for (FreqAndNorm entry : acc.getCompetitiveFreqNormPairs()) {
-      add(entry);
-    }
-  }
-
-  /** Get the set of competitive freq and norm pairs, orderer by increasing freq and norm. */
-  public SortedSet<FreqAndNorm> getCompetitiveFreqNormPairs() {
-    if (dirty) {
-      for (int i = 0; i < maxFreqs.length; ++i) {
-        if (maxFreqs[i] > 0) {
-          add(new FreqAndNorm(maxFreqs[i], (byte) i));
-          maxFreqs[i] = 0;
-        }
-      }
-      dirty = false;
-    }
-    return Collections.unmodifiableSortedSet(freqNormPairs);
-  }
-
-  private void add(FreqAndNorm newEntry) {
-    FreqAndNorm next = freqNormPairs.ceiling(newEntry);
-    if (next == null) {
-      // nothing is more competitive
-      freqNormPairs.add(newEntry);
-    } else if (Long.compareUnsigned(next.norm, newEntry.norm) <= 0) {
-      // we already have this entry or more competitive entries in the tree
-      return;
-    } else {
-      // some entries have a greater freq but a less competitive norm, so we
-      // don't know which one will trigger greater scores, still add to the tree
-      freqNormPairs.add(newEntry);
-    }
-
-    for (Iterator<FreqAndNorm> it = freqNormPairs.headSet(newEntry, false).descendingIterator(); it.hasNext(); ) {
-      FreqAndNorm entry = it.next();
-      if (Long.compareUnsigned(entry.norm, newEntry.norm) >= 0) {
-        // less competitive
-        it.remove();
-      } else {
-        // lesser freq but better norm, further entries are not comparable
-        break;
-      }
-    }
-  }
-
-  @Override
-  public String toString() {
-    return getCompetitiveFreqNormPairs().toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveImpactAccumulator.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveImpactAccumulator.java b/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveImpactAccumulator.java
new file mode 100644
index 0000000..34f7d79
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/codecs/CompetitiveImpactAccumulator.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.codecs;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.lucene.index.Impact;
+
+/**
+ * This class accumulates the (freq, norm) pairs that may produce competitive scores.
+ */
+public final class CompetitiveImpactAccumulator {
+
+  // We speed up accumulation for common norm values by first computing
+  // the max freq for all norms in -128..127
+  private final int[] maxFreqs;
+  private boolean dirty;
+  private final TreeSet<Impact> freqNormPairs;
+
+  /** Sole constructor. */
+  public CompetitiveImpactAccumulator() {
+    maxFreqs = new int[256];
+    Comparator<Impact> comparator = new Comparator<Impact>() {
+      @Override
+      public int compare(Impact o1, Impact o2) {
+        // greater freqs compare greater
+        int cmp = Integer.compare(o1.freq, o2.freq);
+        if (cmp == 0) {
+          // greater norms compare lower
+          cmp = Long.compareUnsigned(o2.norm, o1.norm);
+        }
+        return cmp;
+      }
+    };
+    freqNormPairs = new TreeSet<>(comparator);
+  }
+
+  /** Reset to the same state it was in after creation. */
+  public void clear() {
+    Arrays.fill(maxFreqs, 0);
+    dirty = false;
+    freqNormPairs.clear();
+  }
+
+  /** Accumulate a (freq,norm) pair, updating this structure if there is no
+   *  equivalent or more competitive entry already. */
+  public void add(int freq, long norm) {
+    if (norm >= Byte.MIN_VALUE && norm <= Byte.MAX_VALUE) {
+      int index = Byte.toUnsignedInt((byte) norm);
+      maxFreqs[index] = Math.max(maxFreqs[index], freq); 
+      dirty = true;
+    } else {
+      add(new Impact(freq, norm));
+    }
+  }
+
+  /** Merge {@code acc} into this. */
+  public void addAll(CompetitiveImpactAccumulator acc) {
+    for (Impact entry : acc.getCompetitiveFreqNormPairs()) {
+      add(entry);
+    }
+  }
+
+  /** Get the set of competitive freq and norm pairs, orderer by increasing freq and norm. */
+  public SortedSet<Impact> getCompetitiveFreqNormPairs() {
+    if (dirty) {
+      for (int i = 0; i < maxFreqs.length; ++i) {
+        if (maxFreqs[i] > 0) {
+          add(new Impact(maxFreqs[i], (byte) i));
+          maxFreqs[i] = 0;
+        }
+      }
+      dirty = false;
+    }
+    return Collections.unmodifiableSortedSet(freqNormPairs);
+  }
+
+  private void add(Impact newEntry) {
+    Impact next = freqNormPairs.ceiling(newEntry);
+    if (next == null) {
+      // nothing is more competitive
+      freqNormPairs.add(newEntry);
+    } else if (Long.compareUnsigned(next.norm, newEntry.norm) <= 0) {
+      // we already have this entry or more competitive entries in the tree
+      return;
+    } else {
+      // some entries have a greater freq but a less competitive norm, so we
+      // don't know which one will trigger greater scores, still add to the tree
+      freqNormPairs.add(newEntry);
+    }
+
+    for (Iterator<Impact> it = freqNormPairs.headSet(newEntry, false).descendingIterator(); it.hasNext(); ) {
+      Impact entry = it.next();
+      if (Long.compareUnsigned(entry.norm, newEntry.norm) >= 0) {
+        // less competitive
+        it.remove();
+      } else {
+        // lesser freq but better norm, further entries are not comparable
+        break;
+      }
+    }
+  }
+
+  @Override
+  public String toString() {
+    return getCompetitiveFreqNormPairs().toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/PostingsReaderBase.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/PostingsReaderBase.java b/lucene/core/src/java/org/apache/lucene/codecs/PostingsReaderBase.java
index ca403fa..4fed1a0 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/PostingsReaderBase.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/PostingsReaderBase.java
@@ -24,7 +24,6 @@ import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.FieldInfo;
 import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.SegmentReadState;
-import org.apache.lucene.search.similarities.Similarity;
 import org.apache.lucene.store.DataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.Accountable;
@@ -72,7 +71,7 @@ public abstract class PostingsReaderBase implements Closeable, Accountable {
    * Return a {@link ImpactsEnum} that computes impacts with {@code scorer}.
    * @see #postings(FieldInfo, BlockTermState, PostingsEnum, int)
    */
-  public abstract ImpactsEnum impacts(FieldInfo fieldInfo, BlockTermState state, Similarity.SimScorer scorer, int flags) throws IOException;
+  public abstract ImpactsEnum impacts(FieldInfo fieldInfo, BlockTermState state, int flags) throws IOException;
 
   /** 
    * Checks consistency of this reader.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/blocktree/IntersectTermsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/blocktree/IntersectTermsEnum.java b/lucene/core/src/java/org/apache/lucene/codecs/blocktree/IntersectTermsEnum.java
index 6bccddc..bbd7e7b 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/blocktree/IntersectTermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/blocktree/IntersectTermsEnum.java
@@ -24,7 +24,6 @@ import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.BytesRef;
@@ -235,9 +234,9 @@ final class IntersectTermsEnum extends TermsEnum {
   }
 
   @Override
-  public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+  public ImpactsEnum impacts(int flags) throws IOException {
     currentFrame.decodeMetaData();
-    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.termState, scorer, flags);
+    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.termState, flags);
   }
 
   private int getState() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/blocktree/SegmentTermsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/blocktree/SegmentTermsEnum.java b/lucene/core/src/java/org/apache/lucene/codecs/blocktree/SegmentTermsEnum.java
index ef83f49..327c181 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/blocktree/SegmentTermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/blocktree/SegmentTermsEnum.java
@@ -25,7 +25,6 @@ import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.ArrayUtil;
@@ -1005,7 +1004,7 @@ final class SegmentTermsEnum extends TermsEnum {
   }
 
   @Override
-  public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+  public ImpactsEnum impacts(int flags) throws IOException {
     assert !eof;
     //if (DEBUG) {
     //System.out.println("BTTR.docs seg=" + segment);
@@ -1014,7 +1013,7 @@ final class SegmentTermsEnum extends TermsEnum {
     //if (DEBUG) {
     //System.out.println("  state=" + currentFrame.state);
     //}
-    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.state, scorer, flags);
+    return fr.parent.postingsReader.impacts(fr.fieldInfo, currentFrame.state, flags);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java
index a0f5292..cbe1050 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java
@@ -37,7 +37,6 @@ import org.apache.lucene.index.IndexFileNames;
 import org.apache.lucene.index.SegmentInfo;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.ChecksumIndexInput;
@@ -946,10 +945,9 @@ public final class CompressingTermVectorsReader extends TermVectorsReader implem
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+    public ImpactsEnum impacts(int flags) throws IOException {
       final PostingsEnum delegate = postings(null, PostingsEnum.FREQS);
-      final float maxScore = scorer.score(Float.MAX_VALUE, 1);
-      return new SlowImpactsEnum(delegate, maxScore);
+      return new SlowImpactsEnum(delegate);
     }
 
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java
index 62c7f3f..ede8bdd 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java
@@ -19,20 +19,19 @@ package org.apache.lucene.codecs.lucene50;
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.Objects;
 
 import org.apache.lucene.codecs.BlockTermState;
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.codecs.PostingsReaderBase;
 import org.apache.lucene.codecs.lucene50.Lucene50PostingsFormat.IntBlockTermState;
 import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.Impacts;
 import org.apache.lucene.index.ImpactsEnum;
 import org.apache.lucene.index.IndexFileNames;
 import org.apache.lucene.index.IndexOptions;
 import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.SegmentReadState;
 import org.apache.lucene.index.SlowImpactsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.DataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.ArrayUtil;
@@ -239,13 +238,12 @@ public final class Lucene50PostingsReader extends PostingsReaderBase {
   }
 
   @Override
-  public ImpactsEnum impacts(FieldInfo fieldInfo, BlockTermState state, SimScorer scorer, int flags) throws IOException {
-    Objects.requireNonNull(scorer);
+  public ImpactsEnum impacts(FieldInfo fieldInfo, BlockTermState state, int flags) throws IOException {
     if (state.docFreq <= BLOCK_SIZE || version < Lucene50PostingsFormat.VERSION_IMPACT_SKIP_DATA) {
       // no skip data
-      return new SlowImpactsEnum(postings(fieldInfo, state, null, flags), scorer.score(Float.MAX_VALUE, 1));
+      return new SlowImpactsEnum(postings(fieldInfo, state, null, flags));
     }
-    return new BlockImpactsEverythingEnum(fieldInfo, (IntBlockTermState) state, scorer, flags);
+    return new BlockImpactsEverythingEnum(fieldInfo, (IntBlockTermState) state, flags);
   }
 
   final class BlockDocsEnum extends PostingsEnum {
@@ -1367,7 +1365,7 @@ public final class Lucene50PostingsReader extends PostingsReaderBase {
     
     private long seekTo = -1;
     
-    public BlockImpactsEverythingEnum(FieldInfo fieldInfo, IntBlockTermState termState, SimScorer scorer, int flags) throws IOException {
+    public BlockImpactsEverythingEnum(FieldInfo fieldInfo, IntBlockTermState termState, int flags) throws IOException {
       indexHasFreq = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) >= 0;
       indexHasPos = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
       indexHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
@@ -1440,8 +1438,7 @@ public final class Lucene50PostingsReader extends PostingsReaderBase {
           MAX_SKIP_LEVELS,
           indexHasPos,
           indexHasOffsets,
-          indexHasPayloads,
-          scorer);
+          indexHasPayloads);
       skipper.init(docTermStartFP+termState.skipOffset, docTermStartFP, posTermStartFP, payTermStartFP, docFreq);
 
       if (indexHasFreq == false) {
@@ -1544,17 +1541,7 @@ public final class Lucene50PostingsReader extends PostingsReaderBase {
     }
 
     @Override
-    public int nextDoc() throws IOException {
-      return advance(doc + 1);
-    }
-
-    @Override
-    public float getMaxScore(int upTo) throws IOException {
-      return skipper.getMaxScore(upTo);
-    }
-
-    @Override
-    public int advanceShallow(int target) throws IOException {
+    public void advanceShallow(int target) throws IOException {
       if (target > nextSkipDoc) {
         // always plus one to fix the result, since skip position in Lucene50SkipReader 
         // is a little different from MultiLevelSkipListReader
@@ -1580,7 +1567,17 @@ public final class Lucene50PostingsReader extends PostingsReaderBase {
         nextSkipDoc = skipper.getNextSkipDoc();
       }
       assert nextSkipDoc >= target;
-      return nextSkipDoc;
+    }
+
+    @Override
+    public Impacts getImpacts() throws IOException {
+      advanceShallow(doc);
+      return skipper.getImpacts();
+    }
+
+    @Override
+    public int nextDoc() throws IOException {
+      return advance(doc + 1);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsWriter.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsWriter.java
index 06b9a0c..a600e61 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsWriter.java
@@ -31,7 +31,7 @@ import java.io.IOException;
 
 import org.apache.lucene.codecs.BlockTermState;
 import org.apache.lucene.codecs.CodecUtil;
-import org.apache.lucene.codecs.CompetitiveFreqNormAccumulator;
+import org.apache.lucene.codecs.CompetitiveImpactAccumulator;
 import org.apache.lucene.codecs.PushPostingsWriterBase;
 import org.apache.lucene.codecs.lucene50.Lucene50PostingsFormat.IntBlockTermState;
 import org.apache.lucene.index.CorruptIndexException;
@@ -101,7 +101,7 @@ public final class Lucene50PostingsWriter extends PushPostingsWriterBase {
 
   private boolean fieldHasNorms;
   private NumericDocValues norms;
-  private final CompetitiveFreqNormAccumulator competitiveFreqNormAccumulator = new CompetitiveFreqNormAccumulator();
+  private final CompetitiveImpactAccumulator competitiveFreqNormAccumulator = new CompetitiveImpactAccumulator();
 
   /** Creates a postings writer */
   public Lucene50PostingsWriter(SegmentWriteState state) throws IOException {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50ScoreSkipReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50ScoreSkipReader.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50ScoreSkipReader.java
index cb1f54a..ad69616 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50ScoreSkipReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50ScoreSkipReader.java
@@ -17,90 +17,143 @@
 package org.apache.lucene.codecs.lucene50;
 
 import java.io.IOException;
+import java.util.AbstractList;
 import java.util.Arrays;
-import java.util.Objects;
+import java.util.List;
+import java.util.RandomAccess;
 
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
+import org.apache.lucene.index.Impact;
+import org.apache.lucene.index.Impacts;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.ArrayUtil;
 
 final class Lucene50ScoreSkipReader extends Lucene50SkipReader {
 
-  private final SimScorer scorer;
-  private final float[] maxScore;
-  private final byte[][] impacts;
-  private final int[] impactsLength;
-  private final float globalMaxScore;
+  private final byte[][] impactData;
+  private final int[] impactDataLength;
   private final ByteArrayDataInput badi = new ByteArrayDataInput();
+  private final Impacts impacts;
+  private int numLevels = 1;
+  private final MutableImpactList[] perLevelImpacts;
 
   public Lucene50ScoreSkipReader(int version, IndexInput skipStream, int maxSkipLevels,
-      boolean hasPos, boolean hasOffsets, boolean hasPayloads, SimScorer scorer) {
+      boolean hasPos, boolean hasOffsets, boolean hasPayloads) {
     super(version, skipStream, maxSkipLevels, hasPos, hasOffsets, hasPayloads);
     if (version < Lucene50PostingsFormat.VERSION_IMPACT_SKIP_DATA) {
       throw new IllegalStateException("Cannot skip based on scores if impacts are not indexed");
     }
-    this.scorer = Objects.requireNonNull(scorer);
-    this.maxScore = new float[maxSkipLevels];
-    this.impacts = new byte[maxSkipLevels][];
-    Arrays.fill(impacts, new byte[0]);
-    this.impactsLength = new int[maxSkipLevels];
-    this.globalMaxScore = scorer.score(Float.MAX_VALUE, 1);
-  }
+    this.impactData = new byte[maxSkipLevels][];
+    Arrays.fill(impactData, new byte[0]);
+    this.impactDataLength = new int[maxSkipLevels];
+    this.perLevelImpacts = new MutableImpactList[maxSkipLevels];
+    for (int i = 0; i < perLevelImpacts.length; ++i) {
+      perLevelImpacts[i] = new MutableImpactList();
+    }
+    impacts = new Impacts() {
 
-  @Override
-  public void init(long skipPointer, long docBasePointer, long posBasePointer, long payBasePointer, int df) throws IOException {
-    super.init(skipPointer, docBasePointer, posBasePointer, payBasePointer, df);
-    Arrays.fill(impactsLength, 0);
-    Arrays.fill(maxScore, globalMaxScore);
-  }
+      @Override
+      public int numLevels() {
+        return numLevels;
+      }
 
-  /** Upper bound of scores up to {@code upTo} included. */
-  public float getMaxScore(int upTo) throws IOException {
-    for (int level = 0; level < numberOfSkipLevels; ++level) {
-      if (upTo <= skipDoc[level]) {
-        return maxScore(level);
+      @Override
+      public int getDocIdUpTo(int level) {
+        return skipDoc[level];
       }
-    }
-    return globalMaxScore;
+
+      @Override
+      public List<Impact> getImpacts(int level) {
+        assert level < numLevels;
+        if (impactDataLength[level] > 0) {
+          badi.reset(impactData[level], 0, impactDataLength[level]);
+          perLevelImpacts[level] = readImpacts(badi, perLevelImpacts[level]);
+          impactDataLength[level] = 0;
+        }
+        return perLevelImpacts[level];
+      }
+    };
   }
 
-  private float maxScore(int level) throws IOException {
-    assert level < numberOfSkipLevels;
-    if (impactsLength[level] > 0) {
-      badi.reset(impacts[level], 0, impactsLength[level]);
-      maxScore[level] = readImpacts(badi, scorer);
-      impactsLength[level] = 0;
+  @Override
+  public int skipTo(int target) throws IOException {
+    int result = super.skipTo(target);
+    if (numberOfSkipLevels > 0) {
+      numLevels = numberOfSkipLevels;
+    } else {
+      // End of postings don't have skip data anymore, so we fill with dummy data
+      // like SlowImpactsEnum.
+      numLevels = 1;
+      perLevelImpacts[0].length = 1;
+      perLevelImpacts[0].impacts[0].freq = Integer.MAX_VALUE;
+      perLevelImpacts[0].impacts[0].norm = 1L;
+      impactDataLength[0] = 0;
     }
-    return maxScore[level];
+    return result;
+  }
+
+  Impacts getImpacts() {
+    return impacts;
   }
 
   @Override
   protected void readImpacts(int level, IndexInput skipStream) throws IOException {
     int length = skipStream.readVInt();
-    if (impacts[level].length < length) {
-      impacts[level] = new byte[ArrayUtil.oversize(length, Byte.BYTES)];
+    if (impactData[level].length < length) {
+      impactData[level] = new byte[ArrayUtil.oversize(length, Byte.BYTES)];
     }
-    skipStream.readBytes(impacts[level], 0, length);
-    impactsLength[level] = length;
+    skipStream.readBytes(impactData[level], 0, length);
+    impactDataLength[level] = length;
   }
 
-  static float readImpacts(ByteArrayDataInput in, SimScorer scorer) throws IOException {
+  static MutableImpactList readImpacts(ByteArrayDataInput in, MutableImpactList reuse) {
+    int maxNumImpacts = in.length(); // at most one impact per byte
+    if (reuse.impacts.length < maxNumImpacts) {
+      int oldLength = reuse.impacts.length;
+      reuse.impacts = ArrayUtil.grow(reuse.impacts, maxNumImpacts);
+      for (int i = oldLength; i < reuse.impacts.length; ++i) {
+        reuse.impacts[i] = new Impact(Integer.MAX_VALUE, 1L);
+      }
+    }
+
     int freq = 0;
     long norm = 0;
-    float maxScore = 0;
+    int length = 0;
     while (in.getPosition() < in.length()) {
       int freqDelta = in.readVInt();
       if ((freqDelta & 0x01) != 0) {
         freq += 1 + (freqDelta >>> 1);
-        norm += 1 + in.readZLong();
+        try {
+          norm += 1 + in.readZLong();
+        } catch (IOException e) {
+          throw new RuntimeException(e); // cannot happen on a BADI
+        }
       } else {
         freq += 1 + (freqDelta >>> 1);
         norm++;
       }
-      maxScore = Math.max(maxScore, scorer.score(freq, norm));
+      Impact impact = reuse.impacts[length];
+      impact.freq = freq;
+      impact.norm = norm;
+      length++;
+    }
+    reuse.length = length;
+    return reuse;
+  }
+
+  static class MutableImpactList extends AbstractList<Impact> implements RandomAccess {
+    int length = 1;
+    Impact[] impacts = new Impact[] { new Impact(Integer.MAX_VALUE, 1L) };
+
+    @Override
+    public Impact get(int index) {
+      return impacts[index];
+    }
+
+    @Override
+    public int size() {
+      return length;
     }
-    return maxScore;
   }
 
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipReader.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipReader.java
index b92cd42..ebddde0 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipReader.java
@@ -200,8 +200,7 @@ class Lucene50SkipReader extends MultiLevelSkipListReader {
     return delta;
   }
 
-  // The default impl skips impacts since they are only useful if we have a SimScorer
-  // to compute the scores that impacts map to.
+  // The default impl skips impacts
   protected void readImpacts(int level, IndexInput skipStream) throws IOException {
     if (version >= Lucene50PostingsFormat.VERSION_IMPACT_SKIP_DATA) {
       // The base implementation skips impacts, they are not used

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipWriter.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipWriter.java
index cc94ed0..37044b5 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SkipWriter.java
@@ -22,9 +22,9 @@ import java.util.Arrays;
 import java.util.Set;
 import java.util.SortedSet;
 
-import org.apache.lucene.codecs.CompetitiveFreqNormAccumulator;
-import org.apache.lucene.codecs.CompetitiveFreqNormAccumulator.FreqAndNorm;
+import org.apache.lucene.codecs.CompetitiveImpactAccumulator;
 import org.apache.lucene.codecs.MultiLevelSkipListWriter;
+import org.apache.lucene.index.Impact;
 import org.apache.lucene.store.IndexOutput;
 import org.apache.lucene.store.RAMOutputStream;
 
@@ -65,7 +65,7 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
   private long curPayPointer;
   private int curPosBufferUpto;
   private int curPayloadByteUpto;
-  private CompetitiveFreqNormAccumulator[] curCompetitiveFreqNorms;
+  private CompetitiveImpactAccumulator[] curCompetitiveFreqNorms;
   private boolean fieldHasPositions;
   private boolean fieldHasOffsets;
   private boolean fieldHasPayloads;
@@ -85,9 +85,9 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
       }
       lastPayloadByteUpto = new int[maxSkipLevels];
     }
-    curCompetitiveFreqNorms = new CompetitiveFreqNormAccumulator[maxSkipLevels];
+    curCompetitiveFreqNorms = new CompetitiveImpactAccumulator[maxSkipLevels];
     for (int i = 0; i < maxSkipLevels; ++i) {
-      curCompetitiveFreqNorms[i] = new CompetitiveFreqNormAccumulator();
+      curCompetitiveFreqNorms[i] = new CompetitiveImpactAccumulator();
     }
   }
 
@@ -116,7 +116,7 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
       }
     }
     if (initialized) {
-      for (CompetitiveFreqNormAccumulator acc : curCompetitiveFreqNorms) {
+      for (CompetitiveImpactAccumulator acc : curCompetitiveFreqNorms) {
         acc.clear();
       }
     }
@@ -139,7 +139,7 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
       }
       // sets of competitive freq,norm pairs should be empty at this point
       assert Arrays.stream(curCompetitiveFreqNorms)
-          .map(CompetitiveFreqNormAccumulator::getCompetitiveFreqNormPairs)
+          .map(CompetitiveImpactAccumulator::getCompetitiveFreqNormPairs)
           .mapToInt(Set::size)
           .sum() == 0;
       initialized = true;
@@ -149,7 +149,7 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
   /**
    * Sets the values for the current skip data. 
    */
-  public void bufferSkip(int doc, CompetitiveFreqNormAccumulator competitiveFreqNorms,
+  public void bufferSkip(int doc, CompetitiveImpactAccumulator competitiveFreqNorms,
       int numDocs, long posFP, long payFP, int posBufferUpto, int payloadByteUpto) throws IOException {
     initSkip();
     this.curDoc = doc;
@@ -191,7 +191,7 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
       }
     }
 
-    CompetitiveFreqNormAccumulator competitiveFreqNorms = curCompetitiveFreqNorms[level];
+    CompetitiveImpactAccumulator competitiveFreqNorms = curCompetitiveFreqNorms[level];
     assert competitiveFreqNorms.getCompetitiveFreqNormPairs().size() > 0;
     if (level + 1 < numberOfSkipLevels) {
       curCompetitiveFreqNorms[level + 1].addAll(competitiveFreqNorms);
@@ -203,14 +203,14 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
     competitiveFreqNorms.clear();
   }
 
-  static void writeImpacts(CompetitiveFreqNormAccumulator acc, IndexOutput out) throws IOException {
-    SortedSet<FreqAndNorm> freqAndNorms = acc.getCompetitiveFreqNormPairs();
-    FreqAndNorm previous = new FreqAndNorm(0, 0);
-    for (FreqAndNorm freqAndNorm : freqAndNorms) {
-      assert freqAndNorm.freq > previous.freq;
-      assert Long.compareUnsigned(freqAndNorm.norm, previous.norm) > 0;
-      int freqDelta = freqAndNorm.freq - previous.freq - 1;
-      long normDelta = freqAndNorm.norm - previous.norm - 1;
+  static void writeImpacts(CompetitiveImpactAccumulator acc, IndexOutput out) throws IOException {
+    SortedSet<Impact> impacts = acc.getCompetitiveFreqNormPairs();
+    Impact previous = new Impact(0, 0);
+    for (Impact impact : impacts) {
+      assert impact.freq > previous.freq;
+      assert Long.compareUnsigned(impact.norm, previous.norm) > 0;
+      int freqDelta = impact.freq - previous.freq - 1;
+      long normDelta = impact.norm - previous.norm - 1;
       if (normDelta == 0) {
         // most of time, norm only increases by 1, so we can fold everything in a single byte
         out.writeVInt(freqDelta << 1);
@@ -218,7 +218,7 @@ final class Lucene50SkipWriter extends MultiLevelSkipListWriter {
         out.writeVInt((freqDelta << 1) | 1);
         out.writeZLong(normDelta);
       }
-      previous = freqAndNorm;
+      previous = impact;
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesProducer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesProducer.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesProducer.java
index 7bea274..b0f6e84 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesProducer.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesProducer.java
@@ -38,7 +38,6 @@ import org.apache.lucene.index.SortedNumericDocValues;
 import org.apache.lucene.index.SortedSetDocValues;
 import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.index.TermsEnum.SeekStatus;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.store.RandomAccessInput;
@@ -1160,7 +1159,7 @@ final class Lucene70DocValuesProducer extends DocValuesProducer implements Close
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+    public ImpactsEnum impacts(int flags) throws IOException {
       throw new UnsupportedOperationException();
     }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java
index 841b2ad..2b38712 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java
@@ -30,6 +30,7 @@ import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MaxScoreCache;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
@@ -114,7 +115,8 @@ final class FeatureQuery extends Query {
         }
 
         SimScorer scorer = function.scorer(fieldName, boost);
-        ImpactsEnum impacts = termsEnum.impacts(scorer, PostingsEnum.FREQS);
+        ImpactsEnum impacts = termsEnum.impacts(PostingsEnum.FREQS);
+        MaxScoreCache maxScoreCache = new MaxScoreCache(impacts, scorer);
 
         return new Scorer(this) {
 
@@ -135,12 +137,12 @@ final class FeatureQuery extends Query {
 
           @Override
           public int advanceShallow(int target) throws IOException {
-            return impacts.advanceShallow(target);
+            return maxScoreCache.advanceShallow(target);
           }
 
           @Override
           public float getMaxScore(int upTo) throws IOException {
-            return impacts.getMaxScore(upTo);
+            return maxScoreCache.getMaxScore(upTo);
           }
 
         };

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
index 9126b1d..ca27066 100644
--- a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
+++ b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Deque;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
@@ -48,7 +49,6 @@ import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.LeafFieldComparator;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.FSDirectory;
@@ -1602,58 +1602,45 @@ public final class CheckIndex implements Closeable {
         // Checking score blocks is heavy, we only do it on long postings lists, on every 1024th term
         // or if slow checks are enabled.
         if (doSlowChecks || docFreq > 1024 || (status.termCount + status.delTermCount) % 1024 == 0) {
-          // Test score blocks
-          // We only score on freq to keep things simple and not pull norms
-          SimScorer scorer = new SimScorer(field) {
-            @Override
-            public float score(float freq, long norm) {
-              return freq;
-            }
-          };
-
           // First check max scores and block uptos
           // But only if slok checks are enabled since we visit all docs
           if (doSlowChecks) {
             int max = -1;
-            float maxScore = 0;
-            ImpactsEnum impacts = termsEnum.impacts(scorer, PostingsEnum.FREQS);
+            int maxFreq = 0;
+            ImpactsEnum impactsEnum = termsEnum.impacts(PostingsEnum.FREQS);
             postings = termsEnum.postings(postings, PostingsEnum.FREQS);
-            for (int doc = impacts.nextDoc(); ; doc = impacts.nextDoc()) {
+            for (int doc = impactsEnum.nextDoc(); ; doc = impactsEnum.nextDoc()) {
               if (postings.nextDoc() != doc) {
                 throw new RuntimeException("Wrong next doc: " + doc + ", expected " + postings.docID());
               }
               if (doc == DocIdSetIterator.NO_MORE_DOCS) {
                 break;
               }
-              if (postings.freq() != impacts.freq()) {
-                throw new RuntimeException("Wrong freq, expected " + postings.freq() + ", but got " + impacts.freq());
+              if (postings.freq() != impactsEnum.freq()) {
+                throw new RuntimeException("Wrong freq, expected " + postings.freq() + ", but got " + impactsEnum.freq());
               }
               if (doc > max) {
-                max = impacts.advanceShallow(doc);
-                if (max < doc) {
-                  throw new RuntimeException("max block doc id " + max + " must be greater than the target: " + doc);
-                }
-                maxScore = impacts.getMaxScore(max);
-              }
-              int max2 = impacts.advanceShallow(doc);
-              if (max != max2) {
-                throw new RuntimeException("max is not stable, initially had " + max + " but now " + max2);
+                impactsEnum.advanceShallow(doc);
+                Impacts impacts = impactsEnum.getImpacts();
+                checkImpacts(impacts, doc);
+                max = impacts.getDocIdUpTo(0);
+                List<Impact> impacts0 = impacts.getImpacts(0);
+                maxFreq = impacts0.get(impacts0.size() - 1).freq;
               }
-              float score = scorer.score(impacts.freq(), 1);
-              if (score > maxScore) {
-                throw new RuntimeException("score " + score + " is greater than the max score " + maxScore);
+              if (impactsEnum.freq() > maxFreq) {
+                throw new RuntimeException("freq " + impactsEnum.freq() + " is greater than the max freq according to impacts " + maxFreq);
               }
             }
           }
 
           // Now check advancing
-          ImpactsEnum impacts = termsEnum.impacts(scorer, PostingsEnum.FREQS);
+          ImpactsEnum impactsEnum = termsEnum.impacts(PostingsEnum.FREQS);
           postings = termsEnum.postings(postings, PostingsEnum.FREQS);
 
           int max = -1;
-          float maxScore = 0;
+          int maxFreq = 0;
           while (true) {
-            int doc = impacts.docID();
+            int doc = impactsEnum.docID();
             boolean advance;
             int target;
             if (((field.hashCode() + doc) & 1) == 1) {
@@ -1662,23 +1649,29 @@ public final class CheckIndex implements Closeable {
             } else {
               advance = true;
               int delta = Math.min(1 + ((31 * field.hashCode() + doc) & 0x1ff), DocIdSetIterator.NO_MORE_DOCS - doc);
-              target = impacts.docID() + delta;
+              target = impactsEnum.docID() + delta;
             }
 
             if (target > max && target % 2 == 1) {
               int delta = Math.min((31 * field.hashCode() + target) & 0x1ff, DocIdSetIterator.NO_MORE_DOCS - target);
               max = target + delta;
-              int m = impacts.advanceShallow(target);
-              if (m < target) {
-                throw new RuntimeException("Block max doc: " + m + " is less than the target " + target);
+              impactsEnum.advanceShallow(target);
+              Impacts impacts = impactsEnum.getImpacts();
+              checkImpacts(impacts, doc);
+              maxFreq = Integer.MAX_VALUE;
+              for (int level = 0; level < impacts.numLevels(); ++level) {
+                if (impacts.getDocIdUpTo(level) >= max) {
+                  List<Impact> perLevelImpacts = impacts.getImpacts(level);
+                  maxFreq = perLevelImpacts.get(perLevelImpacts.size() - 1).freq;
+                  break;
+                }
               }
-              maxScore = impacts.getMaxScore(max);
             }
 
             if (advance) {
-              doc = impacts.advance(target);
+              doc = impactsEnum.advance(target);
             } else {
-              doc = impacts.nextDoc();
+              doc = impactsEnum.nextDoc();
             }
 
             if (postings.advance(target) != doc) {
@@ -1687,23 +1680,28 @@ public final class CheckIndex implements Closeable {
             if (doc == DocIdSetIterator.NO_MORE_DOCS) {
               break;
             }
-            if (postings.freq() != impacts.freq()) {
-              throw new RuntimeException("Wrong freq, expected " + postings.freq() + ", but got " + impacts.freq());
+            if (postings.freq() != impactsEnum.freq()) {
+              throw new RuntimeException("Wrong freq, expected " + postings.freq() + ", but got " + impactsEnum.freq());
             }
   
             if (doc >= max) {
               int delta = Math.min((31 * field.hashCode() + target & 0x1ff), DocIdSetIterator.NO_MORE_DOCS - doc);
               max = doc + delta;
-              int m = impacts.advanceShallow(doc);
-              if (m < doc) {
-                throw new RuntimeException("Block max doc: " + m + " is less than the target " + doc);
+              impactsEnum.advanceShallow(doc);
+              Impacts impacts = impactsEnum.getImpacts();
+              checkImpacts(impacts, doc);
+              maxFreq = Integer.MAX_VALUE;
+              for (int level = 0; level < impacts.numLevels(); ++level) {
+                if (impacts.getDocIdUpTo(level) >= max) {
+                  List<Impact> perLevelImpacts = impacts.getImpacts(level);
+                  maxFreq = perLevelImpacts.get(perLevelImpacts.size() - 1).freq;
+                  break;
+                }
               }
-              maxScore = impacts.getMaxScore(max);
             }
 
-            float score = scorer.score(impacts.freq(), 1);
-            if (score > maxScore) {
-              throw new RuntimeException("score " + score + " is greater than the max score " + maxScore);
+            if (impactsEnum.freq() > maxFreq) {
+              throw new RuntimeException("Term frequency " + impactsEnum.freq() + " is greater than the max freq according to impacts " + maxFreq);
             }
           }
         }
@@ -1850,6 +1848,68 @@ public final class CheckIndex implements Closeable {
     return status;
   }
 
+  static void checkImpacts(Impacts impacts, int lastTarget) {
+    final int numLevels = impacts.numLevels();
+    if (numLevels < 1) {
+      throw new RuntimeException("The number of levels must be >= 1, got " + numLevels);
+    }
+
+    int docIdUpTo0 = impacts.getDocIdUpTo(0);
+    if (docIdUpTo0 < lastTarget) {
+      throw new RuntimeException("getDocIdUpTo returned " + docIdUpTo0 + " on level 0, which is less than the target " + lastTarget);
+    }
+
+    for (int level = 1; level < numLevels; ++level) {
+      int docIdUpTo = impacts.getDocIdUpTo(level);
+      int previousDocIdUpTo = impacts.getDocIdUpTo(level - 1);
+      if (docIdUpTo < previousDocIdUpTo) {
+        throw new RuntimeException("Decreasing return for getDocIdUpTo: level " + (level-1) + " returned " + previousDocIdUpTo
+            + " but level " + level + " returned " + docIdUpTo + " for target " + lastTarget);
+      }
+    }
+
+    for (int level = 0; level < numLevels; ++level) {
+      List<Impact> perLevelImpacts = impacts.getImpacts(level);
+      if (perLevelImpacts.isEmpty()) {
+        throw new RuntimeException("Got empty list of impacts on level " + level);
+      }
+      Impact first = perLevelImpacts.get(0);
+      if (first.freq < 1) {
+        throw new RuntimeException("First impact had a freq <= 0: " + first);
+      }
+      if (first.norm == 0) {
+        throw new RuntimeException("First impact had a norm == 0: " + first);
+      }
+      // Impacts must be in increasing order of norm AND freq
+      Impact previous = first;
+      for (int i = 1; i < perLevelImpacts.size(); ++i) {
+        Impact impact = perLevelImpacts.get(i);
+        if (impact.freq <= previous.freq || Long.compareUnsigned(impact.norm, previous.norm) <= 0) {
+          throw new RuntimeException("Impacts are not ordered or contain dups, got " + previous + " then " + impact);
+        }
+      }
+      if (level > 0) {
+        // Make sure that impacts at level N trigger better scores than an level N-1
+        Iterator<Impact> previousIt = impacts.getImpacts(level-1).iterator();
+        previous = previousIt.next();
+        Iterator<Impact> it = perLevelImpacts.iterator();
+        Impact impact = it.next();
+        while (previousIt.hasNext()) {
+          previous = previousIt.next();
+          if (previous.freq <= impact.freq && Long.compareUnsigned(previous.norm, impact.norm) >= 0) {
+            // previous triggers a lower score than the current impact, all good
+            continue;
+          }
+          if (it.hasNext() == false) {
+            throw new RuntimeException("Found impact " + previous + " on level " + (level-1) + " but no impact on level "
+                + level + " triggers a better score: " + perLevelImpacts);
+          }
+          impact = it.next();
+        }
+      }
+    }
+  }
+
   /**
    * Test the term index.
    * @lucene.experimental

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
index 4a9b660..3d86bee 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
@@ -20,7 +20,6 @@ package org.apache.lucene.index;
 import java.io.IOException;
 import java.util.Iterator;
 
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.util.AttributeSource;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
@@ -216,8 +215,8 @@ public abstract class FilterLeafReader extends LeafReader {
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-      return in.impacts(scorer, flags);
+    public ImpactsEnum impacts(int flags) throws IOException {
+      return in.impacts(flags);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/FilteredTermsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/FilteredTermsEnum.java b/lucene/core/src/java/org/apache/lucene/index/FilteredTermsEnum.java
index 61392c3a..72ca421 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FilteredTermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FilteredTermsEnum.java
@@ -20,7 +20,6 @@ package org.apache.lucene.index;
 import java.io.IOException;
 
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.util.AttributeSource;
 
 /**
@@ -184,8 +183,8 @@ public abstract class FilteredTermsEnum extends TermsEnum {
   }
 
   @Override
-  public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
-    return tenum.impacts(scorer, flags);
+  public ImpactsEnum impacts(int flags) throws IOException {
+    return tenum.impacts(flags);
   }
 
   /** This enum does not support seeking!

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/FreqProxFields.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/FreqProxFields.java b/lucene/core/src/java/org/apache/lucene/index/FreqProxFields.java
index c3e7d71..f902022 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FreqProxFields.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FreqProxFields.java
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.lucene.index.FreqProxTermsWriterPerField.FreqProxPostingsArray;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.util.AttributeSource;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
@@ -275,7 +274,7 @@ class FreqProxFields extends Fields {
     }
 
     @Override
-    public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+    public ImpactsEnum impacts(int flags) throws IOException {
       throw new UnsupportedOperationException();
     }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/Impact.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/Impact.java b/lucene/core/src/java/org/apache/lucene/index/Impact.java
new file mode 100644
index 0000000..b8ee20e
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/index/Impact.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.index;
+
+/**
+ * Per-document scoring factors.
+ */
+public final class Impact {
+
+  /**
+   * Term frequency of the term in the document.
+   */
+  public int freq;
+
+  /**
+   * Norm factor of the document.
+   */
+  public long norm;
+
+  /**
+   * Constructor.
+   */
+  public Impact(int freq, long norm) {
+    this.freq = freq;
+    this.norm = norm;
+  }
+
+  @Override
+  public String toString() {
+    return "{freq=" + freq + ",norm=" + norm + "}";
+  }
+
+  @Override
+  public int hashCode() {
+    int h = freq;
+    h = 31 * h + Long.hashCode(norm);
+    return h;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null || getClass() != obj.getClass()) return false;
+    Impact other = (Impact) obj;
+    return freq == other.freq && norm == other.norm;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/Impacts.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/Impacts.java b/lucene/core/src/java/org/apache/lucene/index/Impacts.java
new file mode 100644
index 0000000..ce3ece4
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/index/Impacts.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.index;
+
+import java.util.List;
+
+/**
+ * Information about upcoming impacts, ie. (freq, norm) pairs.
+ */
+public abstract class Impacts {
+
+  /**
+   * Return the number of levels on which we have impacts.
+   * The returned value is always greater than 0 and may not always be the
+   * same, even on a single postings list, depending on the current doc ID.
+   */
+  public abstract int numLevels();
+
+  /**
+   * Return the maximum inclusive doc ID until which the list of impacts
+   * returned by {@link #getImpacts(int)} is valid. This is a non-decreasing
+   * function of {@code level}.
+   */
+  public abstract int getDocIdUpTo(int level);
+
+  /**
+   * Return impacts on the given level. These impacts are sorted by increasing
+   * frequency and increasing unsigned norm, and only valid until the doc ID
+   * returned by {@link #getDocIdUpTo(int)} for the same level, included.
+   * The returned list is never empty.
+   * NOTE: There is no guarantee that these impacts actually appear in postings,
+   * only that they trigger scores that are greater than or equal to the impacts
+   * that actually appear in postings.
+   */
+  public abstract List<Impact> getImpacts(int level);
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/ImpactsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/ImpactsEnum.java b/lucene/core/src/java/org/apache/lucene/index/ImpactsEnum.java
index 8deccff..5a35477 100644
--- a/lucene/core/src/java/org/apache/lucene/index/ImpactsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/index/ImpactsEnum.java
@@ -18,11 +18,9 @@ package org.apache.lucene.index;
 
 import java.io.IOException;
 
-import org.apache.lucene.search.DocIdSetIterator;
-
 /**
- * Extension of {@link PostingsEnum} which also provides information about the
- * produced scores.
+ * Extension of {@link PostingsEnum} which also provides information about
+ * upcoming impacts.
  * @lucene.experimental
  */
 public abstract class ImpactsEnum extends PostingsEnum {
@@ -31,23 +29,28 @@ public abstract class ImpactsEnum extends PostingsEnum {
   protected ImpactsEnum() {}
 
   /**
-   * Advance to the block of documents that contains {@code target} in order to
-   * get scoring information about this block. This method is implicitly called
-   * by {@link DocIdSetIterator#advance(int)} and
-   * {@link DocIdSetIterator#nextDoc()}. Calling this method doesn't modify the
-   * current {@link DocIdSetIterator#docID()}.
-   * It returns a number that is greater than or equal to all documents
-   * contained in the current block, but less than any doc IDS of the next block.
-   * {@code target} must be &gt;= {@link #docID()} as well as all targets that
-   * have been passed to {@link #advanceShallow(int)} so far.
+   * Shallow-advance to {@code target}. This is cheaper than calling
+   * {@link #advance(int)} and allows further calls to {@link #getImpacts()}
+   * to ignore doc IDs that are less than {@code target} in order to get more
+   * precise information about impacts.
+   * This method may not be called on targets that are less than the current
+   * {@link #docID()}.
+   * After this method has been called, {@link #nextDoc()} may not be called
+   * if the current doc ID is less than {@code target - 1} and
+   * {@link #advance(int)} may not be called on targets that are less than
+   * {@code target}.
    */
-  public abstract int advanceShallow(int target) throws IOException;
+  public abstract void advanceShallow(int target) throws IOException;
 
   /**
-   * Return the maximum score that documents between the last {@code target}
-   * that this iterator was {@link #advanceShallow(int) shallow-advanced} to
-   * included and {@code upTo} included.
+   * Get information about upcoming impacts for doc ids that are greater than
+   * or equal to the maximum of {@link #docID()} and the last target that was
+   * passed to {@link #advanceShallow(int)}.
+   * This method may not be called on an unpositioned iterator on which
+   * {@link #advanceShallow(int)} has never been called.
+   * NOTE: advancing this iterator may invalidate the returned impacts, so they
+   * should not be used after the iterator has been advanced.
    */
-  public abstract float getMaxScore(int upTo) throws IOException;
+  public abstract Impacts getImpacts() throws IOException;
 
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/af680af7/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java b/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java
index 4aad5c8..d20c6c1 100644
--- a/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java
@@ -21,7 +21,6 @@ import java.io.IOException;
 import java.util.Arrays;
 import java.util.Comparator;
 
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
@@ -369,9 +368,9 @@ public final class MultiTermsEnum extends TermsEnum {
   }
 
   @Override
-  public ImpactsEnum impacts(SimScorer scorer, int flags) throws IOException {
+  public ImpactsEnum impacts(int flags) throws IOException {
     // implemented to not fail CheckIndex, but you shouldn't be using impacts on a slow reader
-    return new SlowImpactsEnum(postings(null, flags), scorer.score(Float.MAX_VALUE, 1));
+    return new SlowImpactsEnum(postings(null, flags));
   }
 
   final static class TermsEnumWithSlice {