Index: lucene/core/src/java/org/apache/lucene/codecs/intblock/FixedIntBlockIndexInput.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/intblock/FixedIntBlockIndexInput.java (revision 1352570)
+++ lucene/core/src/java/org/apache/lucene/codecs/intblock/FixedIntBlockIndexInput.java (working copy)
@@ -75,7 +75,8 @@
public void readBlock() throws IOException;
}
- private static class Reader extends IntIndexInput.Reader {
+ // nocommit public
+ public static class Reader extends IntIndexInput.Reader {
private final IndexInput in;
protected final int[] pending;
@@ -103,21 +104,38 @@
pendingFP = fp;
pendingUpto = upto;
seekPending = true;
+ //System.out.println("seek fp=" + fp + " upto=" + upto);
}
- private void maybeSeek() throws IOException {
+ // nocommit
+ public void maybeSeek() throws IOException {
+ //System.out.println("maybeSeek: " + seekPending);
if (seekPending) {
if (pendingFP != lastBlockFP) {
// need new block
+ //System.out.println(" seek fp=" + pendingFP);
in.seek(pendingFP);
lastBlockFP = pendingFP;
blockReader.readBlock();
}
upto = pendingUpto;
seekPending = false;
+ //System.out.println(" upto=" + upto + " this=" + this);
}
}
+ public int getUpto() {
+ return upto;
+ }
+
+ public int[] getBlock() {
+ return pending;
+ }
+
+ public BlockReader getBlockReader() {
+ return blockReader;
+ }
+
@Override
public int next() throws IOException {
this.maybeSeek();
Index: lucene/core/src/java/org/apache/lucene/codecs/sep/SepPostingsReader.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/sep/SepPostingsReader.java (revision 1352570)
+++ lucene/core/src/java/org/apache/lucene/codecs/sep/SepPostingsReader.java (working copy)
@@ -303,7 +303,8 @@
return postingsEnum.init(fieldInfo, termState, liveDocs);
}
- class SepDocsEnum extends DocsEnum {
+ // nocommit public
+ public class SepDocsEnum extends DocsEnum {
int docFreq;
int doc = -1;
int accum;
@@ -348,6 +349,14 @@
}
}
+ public IntIndexInput.Reader getDocReader() {
+ return docReader;
+ }
+
+ public IntIndexInput.Reader getFreqReader() {
+ return freqReader;
+ }
+
SepDocsEnum init(FieldInfo fieldInfo, SepTermState termState, Bits liveDocs) throws IOException {
this.liveDocs = liveDocs;
this.indexOptions = fieldInfo.getIndexOptions();
Index: lucene/core/src/java/org/apache/lucene/search/BlockTermScorer.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/search/BlockTermScorer.java (revision 0)
+++ lucene/core/src/java/org/apache/lucene/search/BlockTermScorer.java (working copy)
@@ -0,0 +1,146 @@
+package org.apache.lucene.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.lucene.codecs.intblock.FixedIntBlockIndexInput;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.util.Bits;
+
+/** Expert: A Scorer for documents matching a Term.
+ */
+final class BlockTermScorer extends Scorer {
+ private final FixedIntBlockIndexInput.BlockReader docBlockReader;
+ private final FixedIntBlockIndexInput.BlockReader freqBlockReader;
+ private final Similarity.ExactSimScorer docScorer;
+ private final int[] docBuffer;
+ private final int[] freqBuffer;
+ private final Bits acceptDocs;
+ private final int bufferLen;
+ private final int docFreq;
+
+ private int upto;
+ private int bufferUpto;
+ private int docID;
+ private int freq;
+
+ /**
+ * Construct a TermScorer.
+ *
+ * @param weight
+ * The weight of the Term in the query.
+ * @param td
+ * An iterator over the documents matching the Term.
+ * @param docScorer
+ * The Similarity.ExactSimScorer implementation
+ * to be used for score computations.
+ */
+ BlockTermScorer(Weight weight,
+ FixedIntBlockIndexInput.Reader docBlockReader,
+ FixedIntBlockIndexInput.Reader freqBlockReader,
+ Bits acceptDocs,
+ int docFreq,
+ Similarity.ExactSimScorer docScorer) throws IOException {
+ super(weight);
+ this.docScorer = docScorer;
+ this.docBlockReader = docBlockReader.getBlockReader();
+ this.freqBlockReader = freqBlockReader.getBlockReader();
+ this.acceptDocs = acceptDocs;
+ this.docFreq = docFreq;
+ docBlockReader.maybeSeek();
+ freqBlockReader.maybeSeek();
+ bufferUpto = docBlockReader.getUpto();
+ docBuffer = docBlockReader.getBlock();
+ freqBuffer = freqBlockReader.getBlock();
+ bufferLen = docBuffer.length;
+ assert docBuffer.length == freqBuffer.length;
+ assert bufferUpto == freqBlockReader.getUpto(): upto + " vs " + freqBlockReader.getUpto() + " dF=" + docFreq;
+ //System.out.println("dF=" + docFreq);
+ }
+
+ @Override
+ public int docID() {
+ return docID;
+ }
+
+ @Override
+ public float freq() throws IOException {
+ return freq;
+ }
+
+ /**
+ * Advances to the next document matching the query.
+ *
+ * @return the document matching the query or NO_MORE_DOCS if there are no more documents.
+ */
+ @Override
+ public int nextDoc() throws IOException {
+ while (true) {
+ if (upto == docFreq) {
+ return docID = NO_MORE_DOCS;
+ }
+
+ upto++;
+
+ if (bufferUpto == bufferLen) {
+ //System.out.println("readBlock");
+ docBlockReader.readBlock();
+ freqBlockReader.readBlock();
+ bufferUpto = 0;
+ }
+ docID += docBuffer[bufferUpto];
+ if (acceptDocs != null && !acceptDocs.get(docID)) {
+ bufferUpto++;
+ continue;
+ }
+
+ freq = freqBuffer[bufferUpto];
+ bufferUpto++;
+ //System.out.println(" doc=" + docID + " bufferUpto=" + bufferUpto + " freq=" + freq);
+
+ return docID;
+ }
+ }
+
+ @Override
+ public float score() throws IOException {
+ assert docID() != NO_MORE_DOCS;
+ return docScorer.score(docID, freq);
+ }
+
+ /**
+ * Advances to the first match beyond the current whose document number is
+ * greater than or equal to a given target.
+ * The implementation uses {@link DocsEnum#advance(int)}.
+ *
+ * @param target
+ * The target document number.
+ * @return the matching document or NO_MORE_DOCS if none exist.
+ */
+ @Override
+ public int advance(int target) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /** Returns a string representation of this TermScorer. */
+ @Override
+ public String toString() { return "scorer(" + weight + ")"; }
+
+}
Index: lucene/core/src/java/org/apache/lucene/search/TermQuery.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/search/TermQuery.java (revision 1352570)
+++ lucene/core/src/java/org/apache/lucene/search/TermQuery.java (working copy)
@@ -20,9 +20,12 @@
import java.io.IOException;
import java.util.Set;
+import org.apache.lucene.codecs.intblock.FixedIntBlockIndexInput;
+import org.apache.lucene.codecs.sep.IntIndexInput;
+import org.apache.lucene.codecs.sep.SepPostingsReader.SepDocsEnum;
+import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.DocsEnum;
-import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermState;
@@ -43,6 +46,13 @@
private final int docFreq;
private final TermContext perReaderTermState;
+ private boolean noSkip;
+
+ // nocommit
+ public void setNoSkip() {
+ noSkip = true;
+ }
+
final class TermWeight extends Weight {
private final Similarity similarity;
private final Similarity.SimWeight stats;
@@ -85,7 +95,24 @@
}
DocsEnum docs = termsEnum.docs(acceptDocs, null, true);
if (docs != null) {
- return new TermScorer(this, docs, createDocScorer(context));
+ if ((topScorer || noSkip) && docs instanceof SepDocsEnum) {
+ SepDocsEnum sepDocs = (SepDocsEnum) docs;
+ IntIndexInput.Reader docReader = sepDocs.getDocReader();
+ IntIndexInput.Reader freqReader = sepDocs.getFreqReader();
+ if (docReader instanceof FixedIntBlockIndexInput.Reader) {
+ assert freqReader instanceof FixedIntBlockIndexInput.Reader;
+ return new BlockTermScorer(this,
+ (FixedIntBlockIndexInput.Reader) docReader,
+ (FixedIntBlockIndexInput.Reader) freqReader,
+ acceptDocs,
+ termsEnum.docFreq(),
+ createDocScorer(context));
+ } else {
+ return new TermScorer(this, docs, createDocScorer(context));
+ }
+ } else {
+ return new TermScorer(this, docs, createDocScorer(context));
+ }
} else {
// Index does not store freq info
docs = termsEnum.docs(acceptDocs, null, false);