newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
return new SlowCollatedStringComparator(numHits, fieldname, collator);
}
});
diff --git a/lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/TestSpanRegexQuery.java b/lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/TestSpanRegexQuery.java
index 4866cd7829b..63d46971880 100644
--- a/lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/TestSpanRegexQuery.java
+++ b/lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/TestSpanRegexQuery.java
@@ -83,31 +83,4 @@ public class TestSpanRegexQuery extends LuceneTestCase {
reader.close();
directory.close();
}
-
- private void createRAMDirectories() throws CorruptIndexException,
- LockObtainFailedException, IOException {
- // creating a document to store
- Document lDoc = new Document();
- FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
- customType.setOmitNorms(true);
- lDoc.add(newField("field", "a1 b1", customType));
-
- // creating a document to store
- Document lDoc2 = new Document();
- lDoc2.add(newField("field", "a2 b2", customType));
-
- // creating first index writer
- IndexWriter writerA = new IndexWriter(indexStoreA, newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE));
- writerA.addDocument(lDoc);
- writerA.forceMerge(1);
- writerA.close();
-
- // creating second index writer
- IndexWriter writerB = new IndexWriter(indexStoreB, newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE));
- writerB.addDocument(lDoc2);
- writerB.forceMerge(1);
- writerB.close();
- }
}
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionIncrementAttributeImpl.java b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionIncrementAttributeImpl.java
index 7d3239abbae..0fed366e769 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionIncrementAttributeImpl.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionIncrementAttributeImpl.java
@@ -52,9 +52,10 @@ public class PositionIncrementAttributeImpl extends AttributeImpl implements Pos
* @param positionIncrement the distance from the prior term
*/
public void setPositionIncrement(int positionIncrement) {
- if (positionIncrement < 0)
+ if (positionIncrement < 0) {
throw new IllegalArgumentException
- ("Increment must be zero or greater: " + positionIncrement);
+ ("Increment must be zero or greater: got " + positionIncrement);
+ }
this.positionIncrement = positionIncrement;
}
@@ -77,7 +78,8 @@ public class PositionIncrementAttributeImpl extends AttributeImpl implements Pos
}
if (other instanceof PositionIncrementAttributeImpl) {
- return positionIncrement == ((PositionIncrementAttributeImpl) other).positionIncrement;
+ PositionIncrementAttributeImpl _other = (PositionIncrementAttributeImpl) other;
+ return positionIncrement == _other.positionIncrement;
}
return false;
@@ -93,5 +95,4 @@ public class PositionIncrementAttributeImpl extends AttributeImpl implements Pos
PositionIncrementAttribute t = (PositionIncrementAttribute) target;
t.setPositionIncrement(positionIncrement);
}
-
}
diff --git a/solr/contrib/uima/src/java/org/apache/solr/uima/processor/ae/AEProvider.java b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionLengthAttribute.java
similarity index 52%
rename from solr/contrib/uima/src/java/org/apache/solr/uima/processor/ae/AEProvider.java
rename to lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionLengthAttribute.java
index 2f6ac479eed..d5b8466dfe6 100644
--- a/solr/contrib/uima/src/java/org/apache/solr/uima/processor/ae/AEProvider.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionLengthAttribute.java
@@ -1,4 +1,4 @@
-package org.apache.solr.uima.processor.ae;
+package org.apache.lucene.analysis.tokenattributes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,16 +17,25 @@ package org.apache.solr.uima.processor.ae;
* limitations under the License.
*/
-import org.apache.uima.analysis_engine.AnalysisEngine;
-import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.lucene.util.Attribute;
-/**
- * provide an Apache UIMA {@link AnalysisEngine}
- *
+/** The positionLength determines how many positions this
+ * token spans. Very few analyzer components actually
+ * produce this attribute, and indexing ignores it, but
+ * it's useful to express the graph structure naturally
+ * produced by decompounding, word splitting/joining,
+ * synonym filtering, etc.
*
- */
-public interface AEProvider {
+ * The default value is one. */
- public AnalysisEngine getAE() throws ResourceInitializationException;
+public interface PositionLengthAttribute extends Attribute {
+ /** @param positionLength how many positions this token
+ * spans. */
+ public void setPositionLength(int positionLength);
+ /** Returns the position length of this Token.
+ * @see #setPositionLength
+ */
+ public int getPositionLength();
}
+
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionLengthAttributeImpl.java b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionLengthAttributeImpl.java
new file mode 100644
index 00000000000..67918346b42
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/PositionLengthAttributeImpl.java
@@ -0,0 +1,73 @@
+package org.apache.lucene.analysis.tokenattributes;
+
+/**
+ * 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 org.apache.lucene.util.AttributeImpl;
+
+/** See {@link PositionLengthAttribute}. */
+public class PositionLengthAttributeImpl extends AttributeImpl implements PositionLengthAttribute, Cloneable {
+ private int positionLength = 1;
+
+ /** @param positionLength how many positions this token
+ * spans. NOTE: this is optional, and most analyzers
+ * don't change the default value (1). */
+ public void setPositionLength(int positionLength) {
+ if (positionLength < 1) {
+ throw new IllegalArgumentException
+ ("Position length must be 1 or greater: got " + positionLength);
+ }
+ this.positionLength = positionLength;
+ }
+
+ /** Returns the position length of this Token.
+ * @see #setPositionLength
+ */
+ public int getPositionLength() {
+ return positionLength;
+ }
+
+ @Override
+ public void clear() {
+ this.positionLength = 1;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (other instanceof PositionLengthAttributeImpl) {
+ PositionLengthAttributeImpl _other = (PositionLengthAttributeImpl) other;
+ return positionLength == _other.positionLength;
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return positionLength;
+ }
+
+ @Override
+ public void copyTo(AttributeImpl target) {
+ PositionLengthAttribute t = (PositionLengthAttribute) target;
+ t.setPositionLength(positionLength);
+ }
+}
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/BlockTermsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/BlockTermsReader.java
index ee1a56572a9..d2e42c63a18 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/BlockTermsReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/BlockTermsReader.java
@@ -778,9 +778,6 @@ public class BlockTermsReader extends FieldsProducer {
return state.ord;
}
- private void doPendingSeek() {
- }
-
/* Does initial decode of next block of terms; this
doesn't actually decode the docFreq, totalTermFreq,
postings details (frq/prx offset, etc.) metadata;
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java
index 9cbc07f6837..f773e1e72ee 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java
@@ -35,7 +35,6 @@ import org.apache.lucene.index.IndexFileNames;
import org.apache.lucene.index.SegmentInfo;
import org.apache.lucene.index.TermState;
import org.apache.lucene.index.Terms;
-import org.apache.lucene.index.TermsEnum.SeekStatus;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.store.ByteArrayDataInput;
import org.apache.lucene.store.Directory;
@@ -488,7 +487,7 @@ public class BlockTreeTermsReader extends FieldsProducer {
private Frame[] stack;
- @SuppressWarnings("unchecked") private FST.Arc[] arcs = new FST.Arc[5];
+ @SuppressWarnings({"rawtypes","unchecked"}) private FST.Arc[] arcs = new FST.Arc[5];
private final RunAutomaton runAutomaton;
private final CompiledAutomaton compiledAutomaton;
@@ -821,7 +820,8 @@ public class BlockTreeTermsReader extends FieldsProducer {
private FST.Arc getArc(int ord) {
if (ord >= arcs.length) {
- @SuppressWarnings("unchecked") final FST.Arc[] next = new FST.Arc[ArrayUtil.oversize(1+ord, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
+ @SuppressWarnings({"rawtypes","unchecked"}) final FST.Arc[] next =
+ new FST.Arc[ArrayUtil.oversize(1+ord, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
System.arraycopy(arcs, 0, next, 0, arcs.length);
for(int arcOrd=arcs.length;arcOrd();
@@ -1198,7 +1198,8 @@ public class BlockTreeTermsReader extends FieldsProducer {
final BytesRef term = new BytesRef();
private final FST.BytesReader fstReader;
- @SuppressWarnings("unchecked") private FST.Arc[] arcs = new FST.Arc[1];
+ @SuppressWarnings({"rawtypes","unchecked"}) private FST.Arc[] arcs =
+ new FST.Arc[1];
public SegmentTermsEnum() throws IOException {
//if (DEBUG) System.out.println("BTTR.init seg=" + segment);
@@ -1354,7 +1355,8 @@ public class BlockTreeTermsReader extends FieldsProducer {
private FST.Arc getArc(int ord) {
if (ord >= arcs.length) {
- @SuppressWarnings("unchecked") final FST.Arc[] next = new FST.Arc[ArrayUtil.oversize(1+ord, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
+ @SuppressWarnings({"rawtypes","unchecked"}) final FST.Arc[] next =
+ new FST.Arc[ArrayUtil.oversize(1+ord, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
System.arraycopy(arcs, 0, next, 0, arcs.length);
for(int arcOrd=arcs.length;arcOrd();
@@ -1944,6 +1946,7 @@ public class BlockTreeTermsReader extends FieldsProducer {
}
}
+ @SuppressWarnings("unused")
private void printSeekState() throws IOException {
if (currentFrame == staticFrame) {
System.out.println(" no prior seek");
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsWriter.java
index b0f4624b137..232753d9079 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsWriter.java
@@ -640,7 +640,7 @@ public class BlockTreeTermsWriter extends FieldsConsumer {
// for debugging
@SuppressWarnings("unused")
- private String toString(BytesRef b) {
+ private String toString(BytesRef b) {
try {
return b.utf8ToString() + " " + b;
} catch (Throwable t) {
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/FieldsProducer.java b/lucene/core/src/java/org/apache/lucene/codecs/FieldsProducer.java
index d2862ad156d..ecd6f59e436 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/FieldsProducer.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/FieldsProducer.java
@@ -21,13 +21,9 @@ import java.io.Closeable;
import java.io.IOException;
import org.apache.lucene.index.Fields;
-import org.apache.lucene.index.FieldsEnum;
-import org.apache.lucene.index.Terms;
-/** Abstract API that consumes terms, doc, freq, prox and
- * payloads postings. Concrete implementations of this
- * actually do "something" with the postings (write it into
- * the index in a specific format).
+/** Abstract API that produces terms, doc, freq, prox and
+ * payloads postings.
*
* @lucene.experimental
*/
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexReader.java b/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexReader.java
index 6bcd967a3b6..49c8b5dbe34 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexReader.java
@@ -227,8 +227,6 @@ public class FixedGapTermsIndexReader extends TermsIndexReaderBase {
private final class FieldIndexData {
- final private FieldInfo fieldInfo;
-
volatile CoreFieldIndex coreIndex;
private final long indexStart;
@@ -241,7 +239,6 @@ public class FixedGapTermsIndexReader extends TermsIndexReaderBase {
public FieldIndexData(FieldInfo fieldInfo, int numIndexTerms, long indexStart, long termsStart, long packedIndexStart,
long packedOffsetsStart) throws IOException {
- this.fieldInfo = fieldInfo;
this.termsStart = termsStart;
this.indexStart = indexStart;
this.packedIndexStart = packedIndexStart;
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexWriter.java
index ab3453ca43a..83a796d4a35 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/FixedGapTermsIndexWriter.java
@@ -53,7 +53,8 @@ public class FixedGapTermsIndexWriter extends TermsIndexWriterBase {
final private int termIndexInterval;
private final List fields = new ArrayList();
- private final FieldInfos fieldInfos; // unread
+
+ @SuppressWarnings("unused") private final FieldInfos fieldInfos; // unread
public FixedGapTermsIndexWriter(SegmentWriteState state) throws IOException {
final String indexFileName = IndexFileNames.segmentFileName(state.segmentName, state.segmentSuffix, TERMS_INDEX_EXTENSION);
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java
index e22e1740d0a..1f30e9a4ec0 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java
@@ -22,7 +22,6 @@ import java.io.IOException;
import java.util.Comparator;
import org.apache.lucene.index.DocsAndPositionsEnum;
-import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.FieldInfos;
import org.apache.lucene.index.Fields;
@@ -30,6 +29,7 @@ import org.apache.lucene.index.FieldsEnum;
import org.apache.lucene.index.MergeState;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
@@ -236,7 +236,7 @@ public abstract class TermVectorsWriter implements Closeable {
if (docsAndPositionsEnum != null) {
final int docID = docsAndPositionsEnum.nextDoc();
- assert docID != DocsEnum.NO_MORE_DOCS;
+ assert docID != DocIdSetIterator.NO_MORE_DOCS;
assert docsAndPositionsEnum.freq() == freq;
for(int posUpto=0; posUpto fields = new ArrayList();
- private final FieldInfos fieldInfos; // unread
+
+ @SuppressWarnings("unused") private final FieldInfos fieldInfos; // unread
private final IndexTermSelector policy;
/** @lucene.experimental */
@@ -214,7 +215,6 @@ public class VariableGapTermsIndexWriter extends TermsIndexWriterBase {
private final long startTermsFilePointer;
final FieldInfo fieldInfo;
- int numIndexTerms;
FST fst;
final long indexStart;
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/appending/AppendingPostingsFormat.java b/lucene/core/src/java/org/apache/lucene/codecs/appending/AppendingPostingsFormat.java
index 6a160f94bd2..91bd9c85cf8 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/appending/AppendingPostingsFormat.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/appending/AppendingPostingsFormat.java
@@ -32,7 +32,6 @@ import org.apache.lucene.codecs.lucene40.Lucene40PostingsWriter;
import org.apache.lucene.index.SegmentInfo;
import org.apache.lucene.index.SegmentReadState;
import org.apache.lucene.index.SegmentWriteState;
-import org.apache.lucene.store.Directory;
/**
* Appending postings impl
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java
index a4185e9349d..0229199f0c8 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java
@@ -63,6 +63,7 @@ final class VarSortedBytesImpl {
this.comp = comp;
size = 0;
}
+
@Override
public void merge(MergeState mergeState, DocValues[] docValues)
throws IOException {
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
index 18406f5c6a7..1aeabdd6a4c 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
@@ -387,7 +387,7 @@ public class SimpleTextTermVectorsReader extends TermVectorsReader {
}
@Override
- public Comparator getComparator() throws IOException {
+ public Comparator getComparator() {
return BytesRef.getUTF8SortedAsUnicodeComparator();
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java b/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java
index feb53826588..a3840a13c96 100644
--- a/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java
@@ -20,7 +20,6 @@ package org.apache.lucene.index;
import java.io.IOException;
import org.apache.lucene.search.SearcherManager; // javadocs
-import org.apache.lucene.store.*;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.ReaderUtil; // for javadocs
diff --git a/lucene/core/src/java/org/apache/lucene/index/BaseMultiReader.java b/lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java
similarity index 64%
rename from lucene/core/src/java/org/apache/lucene/index/BaseMultiReader.java
rename to lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java
index 3031ceb60be..c9bb2001455 100644
--- a/lucene/core/src/java/org/apache/lucene/index/BaseMultiReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java
@@ -22,25 +22,51 @@ import java.io.IOException;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.ReaderUtil;
-abstract class BaseMultiReader extends CompositeReader {
+/** Base class for implementing {@link CompositeReader}s based on an array
+ * of sub-readers. The implementing class has to add code for
+ * correctly refcounting and closing the sub-readers.
+ *
+ * User code will most likely use {@link MultiReader} to build a
+ * composite reader on a set of sub-readers (like several
+ * {@link DirectoryReader}s).
+ *
+ *
For efficiency, in this API documents are often referred to via
+ * document numbers, non-negative integers which each name a unique
+ * document in the index. These document numbers are ephemeral -- they may change
+ * as documents are added to and deleted from an index. Clients should thus not
+ * rely on a given document having the same number between sessions.
+ *
+ *
NOTE: {@link
+ * IndexReader} instances are completely thread
+ * safe, meaning multiple threads can call any of its methods,
+ * concurrently. If your application requires external
+ * synchronization, you should not synchronize on the
+ * IndexReader
instance; use your own
+ * (non-Lucene) objects instead.
+ * @see MultiReader
+ * @lucene.internal
+ */
+public abstract class BaseCompositeReader extends CompositeReader {
protected final R[] subReaders;
protected final int[] starts; // 1st docno for each reader
private final int maxDoc;
private final int numDocs;
private final boolean hasDeletions;
- protected BaseMultiReader(R[] subReaders) throws IOException {
+ protected BaseCompositeReader(R[] subReaders) throws IOException {
this.subReaders = subReaders;
starts = new int[subReaders.length + 1]; // build starts array
int maxDoc = 0, numDocs = 0;
boolean hasDeletions = false;
for (int i = 0; i < subReaders.length; i++) {
starts[i] = maxDoc;
- maxDoc += subReaders[i].maxDoc(); // compute maxDocs
- numDocs += subReaders[i].numDocs(); // compute numDocs
- if (subReaders[i].hasDeletions()) {
+ final IndexReader r = subReaders[i];
+ maxDoc += r.maxDoc(); // compute maxDocs
+ numDocs += r.numDocs(); // compute numDocs
+ if (r.hasDeletions()) {
hasDeletions = true;
}
+ r.registerParentReader(this);
}
starts[subReaders.length] = maxDoc;
this.maxDoc = maxDoc;
@@ -51,8 +77,8 @@ abstract class BaseMultiReader extends CompositeReader {
@Override
public final Fields getTermVectors(int docID) throws IOException {
ensureOpen();
- final int i = readerIndex(docID); // find segment num
- return subReaders[i].getTermVectors(docID - starts[i]); // dispatch to segment
+ final int i = readerIndex(docID); // find subreader num
+ return subReaders[i].getTermVectors(docID - starts[i]); // dispatch to subreader
}
@Override
@@ -70,8 +96,8 @@ abstract class BaseMultiReader extends CompositeReader {
@Override
public final void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException {
ensureOpen();
- final int i = readerIndex(docID); // find segment num
- subReaders[i].document(docID - starts[i], visitor); // dispatch to segment reader
+ final int i = readerIndex(docID); // find subreader num
+ subReaders[i].document(docID - starts[i], visitor); // dispatch to subreader
}
@Override
@@ -83,7 +109,7 @@ abstract class BaseMultiReader extends CompositeReader {
@Override
public final int docFreq(String field, BytesRef t) throws IOException {
ensureOpen();
- int total = 0; // sum freqs in segments
+ int total = 0; // sum freqs in subreaders
for (int i = 0; i < subReaders.length; i++) {
total += subReaders[i].docFreq(field, t);
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java b/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java
index f4715e4bf2e..ad55e08c053 100644
--- a/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java
+++ b/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java
@@ -401,7 +401,7 @@ class BufferedDeletesStream {
while (true) {
final int docID = docsEnum.nextDoc();
//System.out.println(Thread.currentThread().getName() + " del term=" + term + " doc=" + docID);
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
// NOTE: there is no limit check on the docID
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 de2857e7bb7..2c7cd03f655 100644
--- a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
+++ b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
@@ -576,7 +576,7 @@ public class CheckIndex {
segInfoStat.fieldNormStatus = testFieldNorms(fieldInfos, reader);
// Test the Term Index
- segInfoStat.termIndexStatus = testPostings(reader);
+ segInfoStat.termIndexStatus = testPostings(fieldInfos, reader);
// Test Stored Fields
segInfoStat.storedFieldStatus = testStoredFields(info, reader, nf);
@@ -691,7 +691,7 @@ public class CheckIndex {
/**
* Test the term index.
*/
- private Status.TermIndexStatus testPostings(SegmentReader reader) {
+ private Status.TermIndexStatus testPostings(FieldInfos fieldInfos, SegmentReader reader) {
// TODO: we should go and verify term vectors match, if
// crossCheckTermVectors is on...
@@ -720,15 +720,31 @@ public class CheckIndex {
DocsEnum docsAndFreqs = null;
DocsAndPositionsEnum postings = null;
+ String lastField = null;
final FieldsEnum fieldsEnum = fields.iterator();
while(true) {
final String field = fieldsEnum.next();
if (field == null) {
break;
}
+ // MultiFieldsEnum relies upon this order...
+ if (lastField != null && field.compareTo(lastField) <= 0) {
+ throw new RuntimeException("fields out of order: lastField=" + lastField + " field=" + field);
+ }
+ lastField = field;
+
+ // check that the field is in fieldinfos, and is indexed.
+ // TODO: add a separate test to check this for different reader impls
+ FieldInfo fi = fieldInfos.fieldInfo(field);
+ if (fi == null) {
+ throw new RuntimeException("fieldsEnum inconsistent with fieldInfos, no fieldInfos for: " + field);
+ }
+ if (!fi.isIndexed) {
+ throw new RuntimeException("fieldsEnum inconsistent with fieldInfos, isIndexed == false for: " + field);
+ }
// TODO: really the codec should not return a field
- // from FieldsEnum if it has to Terms... but we do
+ // from FieldsEnum if it has no Terms... but we do
// this today:
// assert fields.terms(field) != null;
computedFieldCount++;
@@ -909,7 +925,7 @@ public class CheckIndex {
final int skipDocID = (int) (((idx+1)*(long) maxDoc)/8);
postings = termsEnum.docsAndPositions(liveDocs, postings, false);
final int docID = postings.advance(skipDocID);
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
} else {
if (docID < skipDocID) {
@@ -932,7 +948,7 @@ public class CheckIndex {
}
final int nextDocID = postings.nextDoc();
- if (nextDocID == DocsEnum.NO_MORE_DOCS) {
+ if (nextDocID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
if (nextDocID <= docID) {
@@ -945,14 +961,14 @@ public class CheckIndex {
final int skipDocID = (int) (((idx+1)*(long) maxDoc)/8);
docs = termsEnum.docs(liveDocs, docs, false);
final int docID = docs.advance(skipDocID);
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
} else {
if (docID < skipDocID) {
throw new RuntimeException("term " + term + ": advance(docID=" + skipDocID + ") returned docID=" + docID);
}
final int nextDocID = docs.nextDoc();
- if (nextDocID == DocsEnum.NO_MORE_DOCS) {
+ if (nextDocID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
if (nextDocID <= docID) {
@@ -1051,7 +1067,7 @@ public class CheckIndex {
throw new RuntimeException("null DocsEnum from to existing term " + seekTerms[i]);
}
- while(docs.nextDoc() != DocsEnum.NO_MORE_DOCS) {
+ while(docs.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
totDocCount++;
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java b/lucene/core/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
index 12d012f0f89..95e4c23c1a8 100644
--- a/lucene/core/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
+++ b/lucene/core/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
@@ -488,19 +488,6 @@ public class ConcurrentMergeScheduler extends MergeScheduler {
}
}
}
-
- @Override
- public String toString() {
- MergePolicy.OneMerge merge = getRunningMerge();
- if (merge == null) {
- merge = startMerge;
- }
- try {
- return "merge thread: " + tWriter.segString(merge.segments);
- } catch (IOException ioe) {
- throw new RuntimeException(ioe);
- }
- }
}
/** Called when an exception is hit in a background merge
diff --git a/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java b/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java
index 6cb1c37632f..48ed5bf45b6 100644
--- a/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java
@@ -48,13 +48,8 @@ import org.apache.lucene.store.Directory;
synchronization, you should not synchronize on the
IndexReader
instance; use your own
(non-Lucene) objects instead.
-
- Please note: This class extends from an internal (invisible)
- superclass that is generic: The type parameter {@code R} is
- {@link AtomicReader}, see {@link #subReaders} and
- {@link #getSequentialSubReaders}.
*/
-public abstract class DirectoryReader extends BaseMultiReader {
+public abstract class DirectoryReader extends BaseCompositeReader {
public static final int DEFAULT_TERMS_INDEX_DIVISOR = 1;
protected final Directory directory;
diff --git a/lucene/core/src/java/org/apache/lucene/index/DocFieldProcessor.java b/lucene/core/src/java/org/apache/lucene/index/DocFieldProcessor.java
index c249e117b96..ae36b8f9a60 100644
--- a/lucene/core/src/java/org/apache/lucene/index/DocFieldProcessor.java
+++ b/lucene/core/src/java/org/apache/lucene/index/DocFieldProcessor.java
@@ -337,6 +337,9 @@ final class DocFieldProcessor extends DocConsumer {
if (perDocConsumer == null) {
PerDocWriteState perDocWriteState = docState.docWriter.newPerDocWriteState("");
perDocConsumer = docState.docWriter.codec.docValuesFormat().docsConsumer(perDocWriteState);
+ if (perDocConsumer == null) {
+ throw new IllegalStateException("codec=" + docState.docWriter.codec + " does not support docValues: from docValuesFormat().docsConsumer(...) returned null; field=" + fieldInfo.name);
+ }
}
DocValuesConsumer docValuesConsumer = perDocConsumer.addValuesField(valueType, fieldInfo);
fieldInfo.setDocValuesType(valueType, false);
diff --git a/lucene/core/src/java/org/apache/lucene/index/DocTermOrds.java b/lucene/core/src/java/org/apache/lucene/index/DocTermOrds.java
index f43a0e33dea..038c62f4de2 100644
--- a/lucene/core/src/java/org/apache/lucene/index/DocTermOrds.java
+++ b/lucene/core/src/java/org/apache/lucene/index/DocTermOrds.java
@@ -642,19 +642,17 @@ public class DocTermOrds {
* ord; in this case we "wrap" our own terms index
* around it. */
private final class OrdWrappedTermsEnum extends TermsEnum {
- private final AtomicReader reader;
private final TermsEnum termsEnum;
private BytesRef term;
private long ord = -indexInterval-1; // force "real" seek
public OrdWrappedTermsEnum(AtomicReader reader) throws IOException {
- this.reader = reader;
assert indexedTermsArray != null;
termsEnum = reader.fields().terms(field).iterator(null);
}
@Override
- public Comparator getComparator() throws IOException {
+ public Comparator getComparator() {
return termsEnum.getComparator();
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/DocValues.java b/lucene/core/src/java/org/apache/lucene/index/DocValues.java
index b3ce0635d3d..23999f49e0c 100644
--- a/lucene/core/src/java/org/apache/lucene/index/DocValues.java
+++ b/lucene/core/src/java/org/apache/lucene/index/DocValues.java
@@ -148,6 +148,7 @@ public abstract class DocValues implements Closeable {
protected Source(Type type) {
this.type = type;
}
+
/**
* Returns a long for the given document id or throws an
* {@link UnsupportedOperationException} if this source doesn't support
@@ -239,9 +240,10 @@ public abstract class DocValues implements Closeable {
public BytesRef getBytes(int docID, BytesRef bytesRef) {
final int ord = ord(docID);
if (ord < 0) {
+ // Negative ord means doc was missing?
bytesRef.length = 0;
} else {
- getByOrd(ord , bytesRef);
+ getByOrd(ord, bytesRef);
}
return bytesRef;
}
@@ -253,7 +255,7 @@ public abstract class DocValues implements Closeable {
public abstract int ord(int docID);
/** Returns value for specified ord. */
- public abstract BytesRef getByOrd(int ord, BytesRef bytesRef);
+ public abstract BytesRef getByOrd(int ord, BytesRef result);
/** Return true if it's safe to call {@link
* #getDocToOrd}. */
@@ -274,7 +276,7 @@ public abstract class DocValues implements Closeable {
}
/**
- * Performs a lookup by value.
+ * Lookup ord by value.
*
* @param value
* the value to look up
@@ -283,11 +285,11 @@ public abstract class DocValues implements Closeable {
* values to the given value. Must not be null
* @return the given values ordinal if found or otherwise
* (-(ord)-1)
, defined as the ordinal of the first
- * element that is greater than the given value. This guarantees
- * that the return value will always be >= 0 if the given value
- * is found.
+ * element that is greater than the given value (the insertion
+ * point). This guarantees that the return value will always be
+ * >= 0 if the given value is found.
*/
- public int getByValue(BytesRef value, BytesRef spare) {
+ public int getOrdByValue(BytesRef value, BytesRef spare) {
return binarySearch(value, spare, 0, getValueCount() - 1);
}
@@ -405,7 +407,7 @@ public abstract class DocValues implements Closeable {
}
@Override
- public int getByValue(BytesRef value, BytesRef spare) {
+ public int getOrdByValue(BytesRef value, BytesRef spare) {
if (value.length == 0) {
return 0;
} else {
@@ -414,7 +416,7 @@ public abstract class DocValues implements Closeable {
}
@Override
- public int getValueCount() {
+ public int getValueCount() {
return 1;
}
};
diff --git a/lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java b/lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java
index 9bf15eed592..7cda4d35947 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java
@@ -17,8 +17,10 @@ package org.apache.lucene.index;
* limitations under the License.
*/
+import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.automaton.CompiledAutomaton;
import java.io.IOException;
import java.util.Comparator;
@@ -26,7 +28,7 @@ import java.util.Comparator;
/** A FilterAtomicReader
contains another AtomicReader, which it
* uses as its basic source of data, possibly transforming the data along the
* way or providing additional functionality. The class
- * FilterIndexReader
itself simply implements all abstract methods
+ * FilterAtomicReader
itself simply implements all abstract methods
* of IndexReader
with versions that pass all requests to the
* contained index reader. Subclasses of FilterAtomicReader
may
* further override some of these methods and may also provide additional
@@ -37,7 +39,7 @@ public class FilterAtomicReader extends AtomicReader {
/** Base class for filtering {@link Fields}
* implementations. */
public static class FilterFields extends Fields {
- protected Fields in;
+ protected final Fields in;
public FilterFields(Fields in) {
this.in = in;
@@ -57,12 +59,17 @@ public class FilterAtomicReader extends AtomicReader {
public int getUniqueFieldCount() throws IOException {
return in.getUniqueFieldCount();
}
+
+ @Override
+ public long getUniqueTermCount() throws IOException {
+ return in.getUniqueTermCount();
+ }
}
/** Base class for filtering {@link Terms}
* implementations. */
public static class FilterTerms extends Terms {
- protected Terms in;
+ protected final Terms in;
public FilterTerms(Terms in) {
this.in = in;
@@ -97,11 +104,16 @@ public class FilterAtomicReader extends AtomicReader {
public int getDocCount() throws IOException {
return in.getDocCount();
}
+
+ @Override
+ public TermsEnum intersect(CompiledAutomaton automaton, BytesRef bytes) throws java.io.IOException {
+ return in.intersect(automaton, bytes);
+ }
}
/** Base class for filtering {@link TermsEnum} implementations. */
public static class FilterFieldsEnum extends FieldsEnum {
- protected FieldsEnum in;
+ protected final FieldsEnum in;
public FilterFieldsEnum(FieldsEnum in) {
this.in = in;
}
@@ -115,11 +127,16 @@ public class FilterAtomicReader extends AtomicReader {
public Terms terms() throws IOException {
return in.terms();
}
+
+ @Override
+ public AttributeSource attributes() {
+ return in.attributes();
+ }
}
/** Base class for filtering {@link TermsEnum} implementations. */
public static class FilterTermsEnum extends TermsEnum {
- protected TermsEnum in;
+ protected final TermsEnum in;
public FilterTermsEnum(TermsEnum in) { this.in = in; }
@@ -174,7 +191,7 @@ public class FilterAtomicReader extends AtomicReader {
}
@Override
- public Comparator getComparator() throws IOException {
+ public Comparator getComparator() {
return in.getComparator();
}
@@ -187,11 +204,16 @@ public class FilterAtomicReader extends AtomicReader {
public TermState termState() throws IOException {
return in.termState();
}
+
+ @Override
+ public AttributeSource attributes() {
+ return in.attributes();
+ }
}
/** Base class for filtering {@link DocsEnum} implementations. */
public static class FilterDocsEnum extends DocsEnum {
- protected DocsEnum in;
+ protected final DocsEnum in;
public FilterDocsEnum(DocsEnum in) {
this.in = in;
@@ -216,11 +238,16 @@ public class FilterAtomicReader extends AtomicReader {
public int advance(int target) throws IOException {
return in.advance(target);
}
+
+ @Override
+ public AttributeSource attributes() {
+ return in.attributes();
+ }
}
/** Base class for filtering {@link DocsAndPositionsEnum} implementations. */
public static class FilterDocsAndPositionsEnum extends DocsAndPositionsEnum {
- protected DocsAndPositionsEnum in;
+ protected final DocsAndPositionsEnum in;
public FilterDocsAndPositionsEnum(DocsAndPositionsEnum in) {
this.in = in;
@@ -270,18 +297,24 @@ public class FilterAtomicReader extends AtomicReader {
public boolean hasPayload() {
return in.hasPayload();
}
+
+ @Override
+ public AttributeSource attributes() {
+ return in.attributes();
+ }
}
- protected AtomicReader in;
+ protected final AtomicReader in;
/**
- * Construct a FilterIndexReader based on the specified base reader.
- *
Note that base reader is closed if this FilterIndexReader is closed.
+ * Construct a FilterAtomicReader based on the specified base reader.
+ *
Note that base reader is closed if this FilterAtomicReader is closed.
* @param in specified base reader.
*/
public FilterAtomicReader(AtomicReader in) {
super();
this.in = in;
+ in.registerParentReader(this);
}
@Override
@@ -363,7 +396,7 @@ public class FilterAtomicReader extends AtomicReader {
@Override
public String toString() {
- final StringBuilder buffer = new StringBuilder("FilterIndexReader(");
+ final StringBuilder buffer = new StringBuilder("FilterAtomicReader(");
buffer.append(in);
buffer.append(')');
return buffer.toString();
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 185e8971857..0995ac16da8 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FilteredTermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FilteredTermsEnum.java
@@ -122,7 +122,7 @@ public abstract class FilteredTermsEnum extends TermsEnum {
}
@Override
- public Comparator getComparator() throws IOException {
+ public Comparator getComparator() {
return tenum.getComparator();
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexFileNameFilter.java b/lucene/core/src/java/org/apache/lucene/index/IndexFileNameFilter.java
index 38c1e41d8fe..5d9cfff7ff2 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexFileNameFilter.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexFileNameFilter.java
@@ -19,7 +19,6 @@ package org.apache.lucene.index;
import java.io.File;
import java.io.FilenameFilter;
-import java.util.HashSet;
import java.util.regex.Pattern;
/**
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexReader.java b/lucene/core/src/java/org/apache/lucene/index/IndexReader.java
index 8f6a3139f22..5bf88caf150 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexReader.java
@@ -21,6 +21,7 @@ import java.io.Closeable;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashSet;
+import java.util.WeakHashMap;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
@@ -72,10 +73,13 @@ import org.apache.lucene.util.ReaderUtil; // for javadocs
*/
public abstract class IndexReader implements Closeable {
+ private boolean closed = false;
+ private boolean closedByChild = false;
+ private final AtomicInteger refCount = new AtomicInteger(1);
+
IndexReader() {
if (!(this instanceof CompositeReader || this instanceof AtomicReader))
- throw new Error("This class should never be directly extended, subclass AtomicReader or CompositeReader instead!");
- refCount.set(1);
+ throw new Error("IndexReader should never be directly extended, subclass AtomicReader or CompositeReader instead.");
}
/**
@@ -91,6 +95,9 @@ public abstract class IndexReader implements Closeable {
private final Set readerClosedListeners =
Collections.synchronizedSet(new LinkedHashSet());
+ private final Set parentReaders =
+ Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap()));
+
/** Expert: adds a {@link ReaderClosedListener}. The
* provided listener will be invoked when this reader is closed.
*
@@ -107,8 +114,19 @@ public abstract class IndexReader implements Closeable {
ensureOpen();
readerClosedListeners.remove(listener);
}
+
+ /** Expert: This method is called by {@code IndexReader}s which wrap other readers
+ * (e.g. {@link CompositeReader} or {@link FilterAtomicReader}) to register the parent
+ * at the child (this reader) on construction of the parent. When this reader is closed,
+ * it will mark all registered parents as closed, too. The references to parent readers
+ * are weak only, so they can be GCed once they are no longer in use.
+ * @lucene.experimental */
+ public final void registerParentReader(IndexReader reader) {
+ ensureOpen();
+ parentReaders.add(reader);
+ }
- private final void notifyReaderClosedListeners() {
+ private void notifyReaderClosedListeners() {
synchronized(readerClosedListeners) {
for(ReaderClosedListener listener : readerClosedListeners) {
listener.onClose(this);
@@ -116,9 +134,17 @@ public abstract class IndexReader implements Closeable {
}
}
- private boolean closed = false;
-
- private final AtomicInteger refCount = new AtomicInteger();
+ private void reportCloseToParentReaders() {
+ synchronized(parentReaders) {
+ for(IndexReader parent : parentReaders) {
+ parent.closedByChild = true;
+ // cross memory barrier by a fake write:
+ parent.refCount.addAndGet(0);
+ // recurse:
+ parent.reportCloseToParentReaders();
+ }
+ }
+ }
/** Expert: returns the current refCount for this reader */
public final int getRefCount() {
@@ -191,7 +217,12 @@ public abstract class IndexReader implements Closeable {
* @see #incRef
*/
public final void decRef() throws IOException {
- ensureOpen();
+ // only check refcount here (don't call ensureOpen()), so we can
+ // still close the reader if it was made invalid by a child:
+ if (refCount.get() <= 0) {
+ throw new AlreadyClosedException("this IndexReader is closed");
+ }
+
final int rc = refCount.decrementAndGet();
if (rc == 0) {
boolean success = false;
@@ -204,6 +235,7 @@ public abstract class IndexReader implements Closeable {
refCount.incrementAndGet();
}
}
+ reportCloseToParentReaders();
notifyReaderClosedListeners();
} else if (rc < 0) {
throw new IllegalStateException("too many decRef calls: refCount is " + rc + " after decrement");
@@ -217,6 +249,33 @@ public abstract class IndexReader implements Closeable {
if (refCount.get() <= 0) {
throw new AlreadyClosedException("this IndexReader is closed");
}
+ // the happens before rule on reading the refCount, which must be after the fake write,
+ // ensures that we see the value:
+ if (closedByChild) {
+ throw new AlreadyClosedException("this IndexReader cannot be used anymore as one of its child readers was closed");
+ }
+ }
+
+ /** {@inheritDoc}
+ * For caching purposes, {@code IndexReader} subclasses are not allowed
+ * to implement equals/hashCode, so methods are declared final.
+ * To lookup instances from caches use {@link #getCoreCacheKey} and
+ * {@link #getCombinedCoreAndDeletesKey}.
+ */
+ @Override
+ public final boolean equals(Object obj) {
+ return (this == obj);
+ }
+
+ /** {@inheritDoc}
+ *
For caching purposes, {@code IndexReader} subclasses are not allowed
+ * to implement equals/hashCode, so methods are declared final.
+ * To lookup instances from caches use {@link #getCoreCacheKey} and
+ * {@link #getCombinedCoreAndDeletesKey}.
+ */
+ @Override
+ public final int hashCode() {
+ return System.identityHashCode(this);
}
/** Returns a IndexReader reading the index in the given
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
index b916b70b54d..4a6ec709bb5 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
@@ -532,7 +532,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
public synchronized boolean delete(int docID) {
assert liveDocs != null;
- assert docID >= 0 && docID < liveDocs.length();
+ assert docID >= 0 && docID < liveDocs.length() : "out of bounds: docid=" + docID + ",liveDocsLength=" + liveDocs.length();
assert !shared;
final boolean didDelete = liveDocs.get(docID);
if (didDelete) {
@@ -577,6 +577,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
public synchronized void initWritableLiveDocs() throws IOException {
assert Thread.holdsLock(IndexWriter.this);
+ assert info.docCount > 0;
//System.out.println("initWritableLivedocs seg=" + info + " liveDocs=" + liveDocs + " shared=" + shared);
if (shared) {
// Copy on write: this means we've cloned a
@@ -3133,7 +3134,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
return false;
}
- final ReadersAndLiveDocs mergedDeletes = commitMergedDeletes(merge);
+ final ReadersAndLiveDocs mergedDeletes = merge.info.docCount == 0 ? null : commitMergedDeletes(merge);
assert mergedDeletes == null || mergedDeletes.pendingDeleteCount != 0;
diff --git a/lucene/core/src/java/org/apache/lucene/index/MultiFields.java b/lucene/core/src/java/org/apache/lucene/index/MultiFields.java
index ea0ded43169..e2df431fb56 100644
--- a/lucene/core/src/java/org/apache/lucene/index/MultiFields.java
+++ b/lucene/core/src/java/org/apache/lucene/index/MultiFields.java
@@ -35,7 +35,7 @@ import org.apache.lucene.util.ReaderUtil;
* Exposes flex API, merged from flex API of sub-segments.
* This is useful when you're interacting with an {@link
* IndexReader} implementation that consists of sequential
- * sub-readers (eg DirectoryReader or {@link
+ * sub-readers (eg {@link DirectoryReader} or {@link
* MultiReader}).
*
*
NOTE: for multi readers, you'll get better
diff --git a/lucene/core/src/java/org/apache/lucene/index/MultiReader.java b/lucene/core/src/java/org/apache/lucene/index/MultiReader.java
index afceaf33944..a936b807e52 100644
--- a/lucene/core/src/java/org/apache/lucene/index/MultiReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/MultiReader.java
@@ -19,15 +19,25 @@ package org.apache.lucene.index;
import java.io.IOException;
-/** An IndexReader which reads multiple indexes, appending
- * their content.
-
-
Please note: This class extends from an internal (invisible)
- superclass that is generic: The type parameter {@code R} is
- {@link IndexReader}, see {@link #subReaders} and
- {@link #getSequentialSubReaders}.
+/** A {@link CompositeReader} which reads multiple indexes, appending
+ * their content. It can be used to create a view on several
+ * sub-readers (like {@link DirectoryReader}) and execute searches on it.
+ *
+ *
For efficiency, in this API documents are often referred to via
+ * document numbers, non-negative integers which each name a unique
+ * document in the index. These document numbers are ephemeral -- they may change
+ * as documents are added to and deleted from an index. Clients should thus not
+ * rely on a given document having the same number between sessions.
+ *
+ *
NOTE: {@link
+ * IndexReader} instances are completely thread
+ * safe, meaning multiple threads can call any of its methods,
+ * concurrently. If your application requires external
+ * synchronization, you should not synchronize on the
+ * IndexReader
instance; use your own
+ * (non-Lucene) objects instead.
*/
-public class MultiReader extends BaseMultiReader {
+public class MultiReader extends BaseCompositeReader {
private final boolean closeSubReaders;
/**
diff --git a/lucene/core/src/java/org/apache/lucene/index/NormsConsumerPerField.java b/lucene/core/src/java/org/apache/lucene/index/NormsConsumerPerField.java
index 2972217a128..5096734dedf 100644
--- a/lucene/core/src/java/org/apache/lucene/index/NormsConsumerPerField.java
+++ b/lucene/core/src/java/org/apache/lucene/index/NormsConsumerPerField.java
@@ -18,11 +18,8 @@ package org.apache.lucene.index;
import java.io.IOException;
import org.apache.lucene.codecs.DocValuesConsumer;
-import org.apache.lucene.document.DocValuesField;
-import org.apache.lucene.document.Field;
import org.apache.lucene.index.DocValues.Type;
import org.apache.lucene.search.similarities.Similarity;
-import org.apache.lucene.util.BytesRef;
public class NormsConsumerPerField extends InvertedDocEndConsumerPerField implements Comparable {
private final FieldInfo fieldInfo;
diff --git a/lucene/core/src/java/org/apache/lucene/index/ParallelAtomicReader.java b/lucene/core/src/java/org/apache/lucene/index/ParallelAtomicReader.java
index 1fefcf98a68..4120026d703 100644
--- a/lucene/core/src/java/org/apache/lucene/index/ParallelAtomicReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/ParallelAtomicReader.java
@@ -19,7 +19,6 @@ package org.apache.lucene.index;
import java.io.IOException;
import java.util.Collections;
-import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
@@ -57,7 +56,8 @@ public final class ParallelAtomicReader extends AtomicReader {
private final boolean closeSubReaders;
private final int maxDoc, numDocs;
private final boolean hasDeletions;
- final SortedMap fieldToReader = new TreeMap();
+ private final SortedMap fieldToReader = new TreeMap();
+ private final SortedMap tvFieldToReader = new TreeMap();
/** Create a ParallelAtomicReader based on the provided
* readers; auto-closes the given readers on {@link #close()}. */
@@ -98,24 +98,43 @@ public final class ParallelAtomicReader extends AtomicReader {
throw new IllegalArgumentException("All readers must have same maxDoc: "+maxDoc+"!="+reader.maxDoc());
}
}
-
+
+ // build FieldInfos and fieldToReader map:
for (final AtomicReader reader : this.parallelReaders) {
final FieldInfos readerFieldInfos = reader.getFieldInfos();
- for(FieldInfo fieldInfo : readerFieldInfos) { // update fieldToReader map
+ for (FieldInfo fieldInfo : readerFieldInfos) {
// NOTE: first reader having a given field "wins":
if (!fieldToReader.containsKey(fieldInfo.name)) {
fieldInfos.add(fieldInfo);
fieldToReader.put(fieldInfo.name, reader);
- this.fields.addField(fieldInfo.name, reader.terms(fieldInfo.name));
+ if (fieldInfo.storeTermVector) {
+ tvFieldToReader.put(fieldInfo.name, reader);
+ }
}
}
- }
+ }
+
+ // build Fields instance
+ for (final AtomicReader reader : this.parallelReaders) {
+ final Fields readerFields = reader.fields();
+ if (readerFields != null) {
+ final FieldsEnum it = readerFields.iterator();
+ String name;
+ while ((name = it.next()) != null) {
+ // only add if the reader responsible for that field name is the current:
+ if (fieldToReader.get(name) == reader) {
+ this.fields.addField(name, it.terms());
+ }
+ }
+ }
+ }
// do this finally so any Exceptions occurred before don't affect refcounts:
- if (!closeSubReaders) {
- for (AtomicReader reader : completeReaderSet) {
+ for (AtomicReader reader : completeReaderSet) {
+ if (!closeSubReaders) {
reader.incRef();
}
+ reader.registerParentReader(this);
}
}
@@ -132,11 +151,11 @@ public final class ParallelAtomicReader extends AtomicReader {
private final class ParallelFieldsEnum extends FieldsEnum {
private String currentField;
private final Iterator keys;
- private final Fields fields;
+ private final ParallelFields fields;
- ParallelFieldsEnum(Fields fields) {
+ ParallelFieldsEnum(ParallelFields fields) {
this.fields = fields;
- keys = fieldToReader.keySet().iterator();
+ keys = fields.fields.keySet().iterator();
}
@Override
@@ -158,7 +177,7 @@ public final class ParallelAtomicReader extends AtomicReader {
// Single instance of this, per ParallelReader instance
private final class ParallelFields extends Fields {
- final HashMap fields = new HashMap();
+ final Map fields = new TreeMap();
ParallelFields() {
}
@@ -197,11 +216,6 @@ public final class ParallelAtomicReader extends AtomicReader {
@Override
public Fields fields() {
ensureOpen();
- // we cache the inner field instances, so we must check
- // that the delegate readers are really still open:
- for (final AtomicReader reader : parallelReaders) {
- reader.ensureOpen();
- }
return fields;
}
@@ -231,15 +245,17 @@ public final class ParallelAtomicReader extends AtomicReader {
}
}
- // get all vectors
@Override
public Fields getTermVectors(int docID) throws IOException {
ensureOpen();
- ParallelFields fields = new ParallelFields();
- for (Map.Entry ent : fieldToReader.entrySet()) {
+ ParallelFields fields = null;
+ for (Map.Entry ent : tvFieldToReader.entrySet()) {
String fieldName = ent.getKey();
Terms vector = ent.getValue().getTermVector(docID, fieldName);
if (vector != null) {
+ if (fields == null) {
+ fields = new ParallelFields();
+ }
fields.addField(fieldName, vector);
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/ParallelCompositeReader.java b/lucene/core/src/java/org/apache/lucene/index/ParallelCompositeReader.java
index f43bfd04617..d85e4e862f5 100644
--- a/lucene/core/src/java/org/apache/lucene/index/ParallelCompositeReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/ParallelCompositeReader.java
@@ -46,7 +46,7 @@ import java.util.Set;
* by number of documents per segment. If you use different {@link MergePolicy}s
* it might happen that the segment structure of your index is no longer predictable.
*/
-public final class ParallelCompositeReader extends BaseMultiReader {
+public final class ParallelCompositeReader extends BaseCompositeReader {
private final boolean closeSubReaders;
private final Set completeReaderSet =
Collections.newSetFromMap(new IdentityHashMap());
diff --git a/lucene/core/src/java/org/apache/lucene/index/PerDocWriteState.java b/lucene/core/src/java/org/apache/lucene/index/PerDocWriteState.java
index 6b615ad1596..268d921d035 100644
--- a/lucene/core/src/java/org/apache/lucene/index/PerDocWriteState.java
+++ b/lucene/core/src/java/org/apache/lucene/index/PerDocWriteState.java
@@ -1,22 +1,4 @@
package org.apache.lucene.index;
-/**
- * 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.PrintStream;
-
import org.apache.lucene.codecs.PerDocConsumer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
diff --git a/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java b/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java
index 11486ccc118..bb6dacce947 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java
@@ -68,6 +68,7 @@ public final class SlowCompositeReaderWrapper extends AtomicReader {
in = reader;
fields = MultiFields.getFields(in);
liveDocs = MultiFields.getLiveDocs(in);
+ in.registerParentReader(this);
}
@Override
@@ -78,7 +79,6 @@ public final class SlowCompositeReaderWrapper extends AtomicReader {
@Override
public Fields fields() throws IOException {
ensureOpen();
- in.ensureOpen(); // as we cached the fields, we better check the original reader
return fields;
}
@@ -127,7 +127,6 @@ public final class SlowCompositeReaderWrapper extends AtomicReader {
@Override
public Bits getLiveDocs() {
ensureOpen();
- in.ensureOpen(); // as we cached the liveDocs, we better check the original reader
return liveDocs;
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/SortedBytesMergeUtils.java b/lucene/core/src/java/org/apache/lucene/index/SortedBytesMergeUtils.java
index dce3011565d..188a6d1d380 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SortedBytesMergeUtils.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SortedBytesMergeUtils.java
@@ -81,7 +81,7 @@ public final class SortedBytesMergeUtils {
}
}
- public static List buildSlices(int[] docBases ,int[][] docMaps,
+ public static List buildSlices(int[] docBases, int[][] docMaps,
DocValues[] docValues, MergeContext ctx) throws IOException {
final List slices = new ArrayList();
for (int i = 0; i < docValues.length; i++) {
@@ -111,7 +111,7 @@ public final class SortedBytesMergeUtils {
* mapping in docIDToRelativeOrd. After the merge SortedSourceSlice#ordMapping
* contains the new global ordinals for the relative index.
*/
- private static void createOrdMapping(int[] docBases ,int[][] docMaps,
+ private static void createOrdMapping(int[] docBases, int[][] docMaps,
SortedSourceSlice currentSlice) {
final int readerIdx = currentSlice.readerIdx;
final int[] currentDocMap = docMaps[readerIdx];
diff --git a/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java b/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java
index d1542008fb2..8b44e98c990 100644
--- a/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java
@@ -23,6 +23,7 @@ import java.util.Comparator;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.BytesRefIterator;
/** Iterator to seek ({@link #seekCeil(BytesRef)}, {@link
* #seekExact(BytesRef,boolean)}) or step through ({@link
@@ -40,7 +41,7 @@ import org.apache.lucene.util.BytesRef;
* of the seek
methods.
*
* @lucene.experimental */
-public abstract class TermsEnum {
+public abstract class TermsEnum implements BytesRefIterator {
private AttributeSource atts = null;
@@ -114,14 +115,6 @@ public abstract class TermsEnum {
}
}
- /** Increments the enumeration to the next term.
- * Returns the resulting term, or null if the end was
- * hit (which means the enum is unpositioned). The
- * returned BytesRef may be re-used across calls to next.
- * After this method returns null, do not call it again:
- * the results are undefined. */
- public abstract BytesRef next() throws IOException;
-
/** Returns current term. Do not call this when the enum
* is unpositioned. */
public abstract BytesRef term() throws IOException;
@@ -186,13 +179,6 @@ public abstract class TermsEnum {
}
};
}
-
- /** Return the {@link BytesRef} Comparator used to sort
- * terms provided by the iterator. This may return
- * null if there are no terms. Callers may invoke this
- * method many times, so it's best to cache a single
- * instance & reuse it. */
- public abstract Comparator getComparator() throws IOException;
/** An empty TermsEnum for quickly returning an empty instance e.g.
* in {@link org.apache.lucene.search.MultiTermQuery}
diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
index d96f174dd4f..5d9c1d0b94d 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
@@ -203,8 +203,6 @@ final class BooleanScorer extends Scorer {
private final int minNrShouldMatch;
private int end;
private Bucket current;
- private int doc = -1;
-
// Any time a prohibited clause matches we set bit 0:
private static final int PROHIBITED_MASK = 1;
diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer2.java b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer2.java
index 7f7d53df709..5bd66d0601c 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer2.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer2.java
@@ -25,7 +25,6 @@ import java.util.List;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery.BooleanWeight;
import org.apache.lucene.search.similarities.Similarity;
-import org.apache.lucene.search.Scorer.ChildScorer;
/* See the description in BooleanScorer.java, comparing
* BooleanScorer & BooleanScorer2 */
diff --git a/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java b/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java
index c10e708cca1..3317cdc18bc 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java
@@ -49,7 +49,7 @@ class ConjunctionTermScorer extends Scorer {
private int doNext(int doc) throws IOException {
do {
- if (lead.doc == DocsEnum.NO_MORE_DOCS) {
+ if (lead.doc == DocIdSetIterator.NO_MORE_DOCS) {
return NO_MORE_DOCS;
}
advanceHead: do {
diff --git a/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java b/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java
index 99715949d94..6fe1ecb000a 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java
@@ -76,7 +76,7 @@ final class ExactPhraseScorer extends Scorer {
// freq of rarest 2 terms is close:
final boolean useAdvance = postings[i].docFreq > 5*postings[0].docFreq;
chunkStates[i] = new ChunkState(postings[i].postings, -postings[i].position, useAdvance);
- if (i > 0 && postings[i].postings.nextDoc() == DocsEnum.NO_MORE_DOCS) {
+ if (i > 0 && postings[i].postings.nextDoc() == DocIdSetIterator.NO_MORE_DOCS) {
noDocs = true;
return;
}
@@ -89,7 +89,7 @@ final class ExactPhraseScorer extends Scorer {
// first (rarest) term
final int doc = chunkStates[0].posEnum.nextDoc();
- if (doc == DocsEnum.NO_MORE_DOCS) {
+ if (doc == DocIdSetIterator.NO_MORE_DOCS) {
docID = doc;
return doc;
}
@@ -140,8 +140,8 @@ final class ExactPhraseScorer extends Scorer {
// first term
int doc = chunkStates[0].posEnum.advance(target);
- if (doc == DocsEnum.NO_MORE_DOCS) {
- docID = DocsEnum.NO_MORE_DOCS;
+ if (doc == DocIdSetIterator.NO_MORE_DOCS) {
+ docID = DocIdSetIterator.NO_MORE_DOCS;
return doc;
}
@@ -171,7 +171,7 @@ final class ExactPhraseScorer extends Scorer {
}
doc = chunkStates[0].posEnum.nextDoc();
- if (doc == DocsEnum.NO_MORE_DOCS) {
+ if (doc == DocIdSetIterator.NO_MORE_DOCS) {
docID = doc;
return doc;
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java b/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java
index a8e34e7718b..0c2513ca157 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java
@@ -367,7 +367,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
retArray[docID] = termval;
@@ -440,7 +440,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
retArray[docID] = termval;
@@ -544,7 +544,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
retArray[docID] = termval;
@@ -612,7 +612,7 @@ class FieldCacheImpl implements FieldCache {
// TODO: use bulk API
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
res.set(docID);
@@ -694,7 +694,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
retArray[docID] = termval;
@@ -782,7 +782,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
retArray[docID] = termval;
@@ -871,7 +871,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
retArray[docID] = termval;
@@ -1052,7 +1052,7 @@ class FieldCacheImpl implements FieldCache {
}
@Override
- public Comparator getComparator() throws IOException {
+ public Comparator getComparator() {
return BytesRef.getUTF8SortedAsUnicodeComparator();
}
@@ -1172,7 +1172,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
docToTermOrd.set(docID, termOrd);
@@ -1293,7 +1293,7 @@ class FieldCacheImpl implements FieldCache {
docs = termsEnum.docs(null, docs, false);
while (true) {
final int docID = docs.nextDoc();
- if (docID == DocsEnum.NO_MORE_DOCS) {
+ if (docID == DocIdSetIterator.NO_MORE_DOCS) {
break;
}
docToOffset.set(docID, pointer);
diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java b/lucene/core/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java
index c84bd19a576..aa3da4e8014 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java
@@ -459,6 +459,7 @@ public abstract class FieldCacheRangeFilter extends Filter {
}
@Override
+ @SuppressWarnings({"unchecked","rawtypes"})
public final boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof FieldCacheRangeFilter)) return false;
diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldComparator.java b/lucene/core/src/java/org/apache/lucene/search/FieldComparator.java
index 4bcdb8a1ee4..a6860018a5b 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FieldComparator.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FieldComparator.java
@@ -150,7 +150,7 @@ public abstract class FieldComparator {
* comparator across segments
* @throws IOException
*/
- public abstract FieldComparator setNextReader(AtomicReaderContext context) throws IOException;
+ public abstract FieldComparator setNextReader(AtomicReaderContext context) throws IOException;
/** Sets the Scorer to use in case a document's score is
* needed.
@@ -201,7 +201,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
if (missingValue != null) {
docsWithField = FieldCache.DEFAULT.getDocsWithField(context.reader(), field);
// optimization to remove unneeded checks on the bit interface:
@@ -258,7 +258,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
// NOTE: must do this before calling super otherwise
// we compute the docsWithField Bits twice!
currentReaderValues = FieldCache.DEFAULT.getBytes(context.reader(), field, parser, missingValue != null);
@@ -335,7 +335,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
// NOTE: must do this before calling super otherwise
// we compute the docsWithField Bits twice!
currentReaderValues = FieldCache.DEFAULT.getDoubles(context.reader(), field, parser, missingValue != null);
@@ -396,7 +396,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
final DocValues docValues = context.reader().docValues(field);
if (docValues != null) {
currentReaderValues = docValues.getSource();
@@ -478,7 +478,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
// NOTE: must do this before calling super otherwise
// we compute the docsWithField Bits twice!
currentReaderValues = FieldCache.DEFAULT.getFloats(context.reader(), field, parser, missingValue != null);
@@ -540,7 +540,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
// NOTE: must do this before calling super otherwise
// we compute the docsWithField Bits twice!
currentReaderValues = FieldCache.DEFAULT.getShorts(context.reader(), field, parser, missingValue != null);
@@ -624,7 +624,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
// NOTE: must do this before calling super otherwise
// we compute the docsWithField Bits twice!
currentReaderValues = FieldCache.DEFAULT.getInts(context.reader(), field, parser, missingValue != null);
@@ -689,7 +689,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
DocValues docValues = context.reader().docValues(field);
if (docValues != null) {
currentReaderValues = docValues.getSource();
@@ -772,7 +772,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
// NOTE: must do this before calling super otherwise
// we compute the docsWithField Bits twice!
currentReaderValues = FieldCache.DEFAULT.getLongs(context.reader(), field, parser, missingValue != null);
@@ -824,7 +824,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) {
+ public FieldComparator setNextReader(AtomicReaderContext context) {
return this;
}
@@ -887,7 +887,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) {
+ public FieldComparator setNextReader(AtomicReaderContext context) {
// TODO: can we "map" our docIDs to the current
// reader? saves having to then subtract on every
// compare call
@@ -1007,7 +1007,7 @@ public abstract class FieldComparator {
abstract class PerSegmentComparator extends FieldComparator {
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
return TermOrdValComparator.this.setNextReader(context);
}
@@ -1055,32 +1055,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = (readerOrds[doc]&0xFF);
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - (readerOrds[doc]&0xFF);
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = readerOrds[doc]&0xFF;
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
-
- if (bottomValue == null) {
- if (order == 0) {
- // unset
- return 0;
- }
- // bottom wins
- return -1;
- } else if (order == 0) {
- // doc wins
- return 1;
- }
- termsIndex.lookup(order, tempBR);
- return bottomValue.compareTo(tempBR);
+ return -1;
}
}
@@ -1116,32 +1101,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = (readerOrds[doc]&0xFFFF);
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - (readerOrds[doc]&0xFFFF);
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = readerOrds[doc]&0xFFFF;
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
-
- if (bottomValue == null) {
- if (order == 0) {
- // unset
- return 0;
- }
- // bottom wins
- return -1;
- } else if (order == 0) {
- // doc wins
- return 1;
- }
- termsIndex.lookup(order, tempBR);
- return bottomValue.compareTo(tempBR);
+ return -1;
}
}
@@ -1177,32 +1147,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = readerOrds[doc];
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - readerOrds[doc];
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = readerOrds[doc];
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
-
- if (bottomValue == null) {
- if (order == 0) {
- // unset
- return 0;
- }
- // bottom wins
- return -1;
- } else if (order == 0) {
- // doc wins
- return 1;
- }
- termsIndex.lookup(order, tempBR);
- return bottomValue.compareTo(tempBR);
+ return -1;
}
}
@@ -1239,32 +1194,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = (int) readerOrds.get(doc);
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - (int) readerOrds.get(doc);
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = (int) readerOrds.get(doc);
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
-
- if (bottomValue == null) {
- if (order == 0) {
- // unset
- return 0;
- }
- // bottom wins
- return -1;
- } else if (order == 0) {
- // doc wins
- return 1;
- }
- termsIndex.lookup(order, tempBR);
- return bottomValue.compareTo(tempBR);
+ return -1;
}
}
@@ -1286,11 +1226,11 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
final int docBase = context.docBase;
termsIndex = FieldCache.DEFAULT.getTermsIndex(context.reader(), field);
final PackedInts.Reader docToOrd = termsIndex.getDocToOrd();
- FieldComparator perSegComp = null;
+ FieldComparator perSegComp = null;
if (docToOrd.hasArray()) {
final Object arr = docToOrd.getArray();
if (arr instanceof byte[]) {
@@ -1457,7 +1397,7 @@ public abstract class FieldComparator {
abstract class PerSegmentComparator extends FieldComparator {
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
return TermOrdValDocValuesComparator.this.setNextReader(context);
}
@@ -1499,21 +1439,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = readerOrds[doc]&0xFF;
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - (readerOrds[doc]&0xFF);
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = readerOrds[doc]&0xFF;
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
-
- termsIndex.getByOrd(order, tempBR);
- return comp.compare(bottomValue, tempBR);
+ return -1;
}
}
@@ -1544,21 +1480,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = readerOrds[doc]&0xFFFF;
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - (readerOrds[doc]&0xFFFF);
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = readerOrds[doc]&0xFFFF;
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
-
- termsIndex.getByOrd(order, tempBR);
- return comp.compare(bottomValue, tempBR);
+ return -1;
}
}
@@ -1589,20 +1521,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = readerOrds[doc];
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - readerOrds[doc];
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = readerOrds[doc];
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
- termsIndex.getByOrd(order, tempBR);
- return comp.compare(bottomValue, tempBR);
+ return -1;
}
}
@@ -1632,20 +1561,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
assert bottomSlot != -1;
+ final int docOrd = (int) readerOrds.get(doc);
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - (int) readerOrds.get(doc);
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = (int) readerOrds.get(doc);
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
- termsIndex.getByOrd(order, tempBR);
- return comp.compare(bottomValue, tempBR);
+ return -1;
}
}
@@ -1672,21 +1598,17 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
- assert bottomSlot != -1;
+ final int docOrd = termsIndex.ord(doc);
if (bottomSameReader) {
// ord is precisely comparable, even in the equal case
- return bottomOrd - termsIndex.ord(doc);
+ return bottomOrd - docOrd;
+ } else if (bottomOrd >= docOrd) {
+ // the equals case always means bottom is > doc
+ // (because we set bottomOrd to the lower bound in
+ // setBottom):
+ return 1;
} else {
- // ord is only approx comparable: if they are not
- // equal, we can use that; if they are equal, we
- // must fallback to compare by value
- final int order = termsIndex.ord(doc);
- final int cmp = bottomOrd - order;
- if (cmp != 0) {
- return cmp;
- }
- termsIndex.getByOrd(order, tempBR);
- return comp.compare(bottomValue, tempBR);
+ return -1;
}
}
@@ -1703,7 +1625,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
final int docBase = context.docBase;
final DocValues dv = context.reader().docValues(field);
@@ -1724,7 +1646,7 @@ public abstract class FieldComparator {
comp = termsIndex.getComparator();
- FieldComparator perSegComp = null;
+ FieldComparator perSegComp = null;
if (termsIndex.hasPackedDocToOrd()) {
final PackedInts.Reader docToOrd = termsIndex.getDocToOrd();
if (docToOrd.hasArray()) {
@@ -1775,7 +1697,7 @@ public abstract class FieldComparator {
bottomSameReader = true;
readerGen[bottomSlot] = currentReaderGen;
} else {
- final int index = termsIndex.getByValue(bottomValue, tempBR);
+ final int index = termsIndex.getOrdByValue(bottomValue, tempBR);
if (index < 0) {
bottomOrd = -index - 2;
bottomSameReader = false;
@@ -1852,7 +1774,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
docTerms = FieldCache.DEFAULT.getTerms(context.reader(), field);
return this;
}
@@ -1921,7 +1843,7 @@ public abstract class FieldComparator {
}
@Override
- public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
final DocValues dv = context.reader().docValues(field);
if (dv != null) {
docTerms = dv.getSource();
diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldComparatorSource.java b/lucene/core/src/java/org/apache/lucene/search/FieldComparatorSource.java
index f7ca0642ac9..6ad27db8e39 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FieldComparatorSource.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FieldComparatorSource.java
@@ -36,6 +36,6 @@ public abstract class FieldComparatorSource {
* @throws IOException
* If an error occurs reading the index.
*/
- public abstract FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed)
+ public abstract FieldComparator> newComparator(String fieldname, int numHits, int sortPos, boolean reversed)
throws IOException;
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldValueHitQueue.java b/lucene/core/src/java/org/apache/lucene/search/FieldValueHitQueue.java
index ab6a30c62f3..1297a46940b 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FieldValueHitQueue.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FieldValueHitQueue.java
@@ -129,6 +129,7 @@ public abstract class FieldValueHitQueue ext
}
// prevent instantiation and extension.
+ @SuppressWarnings({"rawtypes","unchecked"})
private FieldValueHitQueue(SortField[] fields, int size) {
super(size);
// When we get here, fields.length is guaranteed to be > 0, therefore no
@@ -169,7 +170,7 @@ public abstract class FieldValueHitQueue ext
}
}
- public FieldComparator[] getComparators() {
+ public FieldComparator>[] getComparators() {
return comparators;
}
@@ -177,15 +178,15 @@ public abstract class FieldValueHitQueue ext
return reverseMul;
}
- public void setComparator(int pos, FieldComparator comparator) {
+ public void setComparator(int pos, FieldComparator> comparator) {
if (pos==0) firstComparator = comparator;
comparators[pos] = comparator;
}
/** Stores the sort criteria being used. */
protected final SortField[] fields;
- protected final FieldComparator[] comparators; // use setComparator to change this array
- protected FieldComparator firstComparator; // this must always be equal to comparators[0]
+ protected final FieldComparator>[] comparators; // use setComparator to change this array
+ protected FieldComparator> firstComparator; // this must always be equal to comparators[0]
protected final int[] reverseMul;
@Override
diff --git a/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java b/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java
index e994d1a0391..a9f908a4ab9 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java
@@ -84,7 +84,11 @@ public abstract class FilteredDocIdSet extends DocIdSet {
*/
@Override
public DocIdSetIterator iterator() throws IOException {
- return new FilteredDocIdSetIterator(_innerSet.iterator()) {
+ final DocIdSetIterator iterator = _innerSet.iterator();
+ if (iterator == null) {
+ return null;
+ }
+ return new FilteredDocIdSetIterator(iterator) {
@Override
protected boolean match(int docid) {
return FilteredDocIdSet.this.match(docid);
diff --git a/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java b/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java
index 2671efe48f9..3edafab44f8 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java
@@ -287,7 +287,7 @@ public final class FuzzyTermsEnum extends TermsEnum {
}
@Override
- public Comparator getComparator() throws IOException {
+ public Comparator getComparator() {
return actualEnum.getComparator();
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
index 25f80fb1a29..d829bf32595 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
@@ -408,16 +408,12 @@ class UnionDocsAndPositionsEnum extends DocsAndPositionsEnum {
Iterator i = docsEnums.iterator();
while (i.hasNext()) {
DocsAndPositionsEnum postings = i.next();
- if (postings.nextDoc() != DocsAndPositionsEnum.NO_MORE_DOCS) {
+ if (postings.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
add(postings);
}
}
}
- final public DocsEnum peek() {
- return top();
- }
-
@Override
public final boolean lessThan(DocsAndPositionsEnum a, DocsAndPositionsEnum b) {
return a.docID() < b.docID();
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java b/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java
index 549674eeabb..c3c09d508b8 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java
@@ -60,6 +60,7 @@ public class MultiTermQueryWrapperFilter extends Filte
}
@Override
+ @SuppressWarnings({"unchecked","rawtypes"})
public final boolean equals(final Object o) {
if (o==this) return true;
if (o==null) return false;
diff --git a/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java b/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java
index 97e8b889a1e..02a7dc9ba75 100644
--- a/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/NumericRangeQuery.java
@@ -352,6 +352,7 @@ public final class NumericRangeQuery extends MultiTermQuery {
}
@Override
+ @SuppressWarnings({"unchecked","rawtypes"})
public final boolean equals(final Object o) {
if (o==this) return true;
if (!super.equals(o))
diff --git a/lucene/core/src/java/org/apache/lucene/search/SortField.java b/lucene/core/src/java/org/apache/lucene/search/SortField.java
index bbd47147a4c..74d6b925825 100644
--- a/lucene/core/src/java/org/apache/lucene/search/SortField.java
+++ b/lucene/core/src/java/org/apache/lucene/search/SortField.java
@@ -376,7 +376,7 @@ public class SortField {
* optimize themselves when they are the primary sort.
* @return {@link FieldComparator} to use when sorting
*/
- public FieldComparator getComparator(final int numHits, final int sortPos) throws IOException {
+ public FieldComparator> getComparator(final int numHits, final int sortPos) throws IOException {
switch (type) {
case SCORE:
diff --git a/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java b/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java
index 3f1370d4201..0a56b865689 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java
@@ -17,12 +17,12 @@ package org.apache.lucene.search;
* limitations under the License.
*/
-import java.io.IOException;
-
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.util.Counter;
import org.apache.lucene.util.ThreadInterruptedException;
+import java.io.IOException;
+
/**
* The {@link TimeLimitingCollector} is used to timeout search requests that
* take longer than the maximum allowed search time limit. After this time is
@@ -60,7 +60,7 @@ public class TimeLimitingCollector extends Collector {
private long t0 = Long.MIN_VALUE;
private long timeout = Long.MIN_VALUE;
- private final Collector collector;
+ private Collector collector;
private final Counter clock;
private final long ticksAllowed;
private boolean greedy = false;
@@ -172,6 +172,17 @@ public class TimeLimitingCollector extends Collector {
public boolean acceptsDocsOutOfOrder() {
return collector.acceptsDocsOutOfOrder();
}
+
+ /**
+ * This is so the same timer can be used with a multi-phase search process such as grouping.
+ * We don't want to create a new TimeLimitingCollector for each phase because that would
+ * reset the timer for each phase. Once time is up subsequent phases need to timeout quickly.
+ *
+ * @param collector The actual collector performing search functionality
+ */
+ public void setCollector(Collector collector) {
+ this.collector = collector;
+ }
/**
diff --git a/lucene/core/src/java/org/apache/lucene/search/TopDocs.java b/lucene/core/src/java/org/apache/lucene/search/TopDocs.java
index b464aae163d..0e5bc0fb96e 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopDocs.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopDocs.java
@@ -116,10 +116,11 @@ public class TopDocs {
}
}
+ @SuppressWarnings({"rawtypes","unchecked"})
private static class MergeSortQueue extends PriorityQueue {
// These are really FieldDoc instances:
final ScoreDoc[][] shardHits;
- final FieldComparator[] comparators;
+ final FieldComparator>[] comparators;
final int[] reverseMul;
public MergeSortQueue(Sort sort, TopDocs[] shardHits) throws IOException {
@@ -155,7 +156,7 @@ public class TopDocs {
}
// Returns true if first is < second
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked","rawtypes"})
public boolean lessThan(ShardRef first, ShardRef second) {
assert first != second;
final FieldDoc firstFD = (FieldDoc) shardHits[first.shardIndex][first.hitIndex];
diff --git a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
index 0d4e05a887a..cc01ce8ea05 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
@@ -46,7 +46,7 @@ public abstract class TopFieldCollector extends TopDocsCollector {
private static class OneComparatorNonScoringCollector extends
TopFieldCollector {
- FieldComparator comparator;
+ FieldComparator> comparator;
final int reverseMul;
final FieldValueHitQueue queue;
@@ -70,7 +70,7 @@ public abstract class TopFieldCollector extends TopDocsCollector {
if (queueFull) {
if ((reverseMul * comparator.compareBottom(doc)) <= 0) {
// since docs are visited in doc Id order, if compare is 0, it means
- // this document is largest than anything else in the queue, and
+ // this document is larger than anything else in the queue, and
// therefore not competitive.
return;
}
@@ -382,7 +382,7 @@ public abstract class TopFieldCollector extends TopDocsCollector {
*/
private static class MultiComparatorNonScoringCollector extends TopFieldCollector {
- final FieldComparator[] comparators;
+ final FieldComparator>[] comparators;
final int[] reverseMul;
final FieldValueHitQueue queue;
public MultiComparatorNonScoringCollector(FieldValueHitQueue queue,
diff --git a/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java b/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java
index 964d9a0fb6a..28e2c084b2c 100644
--- a/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java
+++ b/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java
@@ -135,7 +135,8 @@ public class PayloadSpanUtil {
}
}
- @SuppressWarnings("unchecked") final List[] disjunctLists = new List[maxPosition + 1];
+ @SuppressWarnings({"rawtypes","unchecked"}) final List[] disjunctLists =
+ new List[maxPosition + 1];
int distinctPositions = 0;
for (int i = 0; i < termArrays.size(); ++i) {
diff --git a/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
index fdaf74adf7f..2f9a86add91 100644
--- a/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
@@ -25,7 +25,6 @@ import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.ComplexExplanation;
-import org.apache.lucene.search.payloads.PayloadNearQuery.PayloadNearSpanScorer;
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.similarities.Similarity.SloppySimScorer;
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
index 144987027d7..44bcf3ec0a9 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
@@ -60,6 +60,7 @@ public class SpanMultiTermQueryWrapper extends SpanQue
* Be sure to not change the rewrite method on the wrapped query afterwards! Doing so will
* throw {@link UnsupportedOperationException} on rewriting this query!
*/
+ @SuppressWarnings({"rawtypes","unchecked"})
public SpanMultiTermQueryWrapper(Q query) {
this.query = query;
@@ -123,6 +124,7 @@ public class SpanMultiTermQueryWrapper extends SpanQue
}
@Override
+ @SuppressWarnings({"rawtypes","unchecked"})
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java b/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java
index 2ce409eeca9..d0f965ad203 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java
@@ -56,7 +56,7 @@ public class TermSpans extends Spans {
return false;
}
doc = postings.nextDoc();
- if (doc == DocsAndPositionsEnum.NO_MORE_DOCS) {
+ if (doc == DocIdSetIterator.NO_MORE_DOCS) {
return false;
}
freq = postings.freq();
@@ -70,7 +70,7 @@ public class TermSpans extends Spans {
@Override
public boolean skipTo(int target) throws IOException {
doc = postings.advance(target);
- if (doc == DocsAndPositionsEnum.NO_MORE_DOCS) {
+ if (doc == DocIdSetIterator.NO_MORE_DOCS) {
return false;
}
diff --git a/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java b/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java
index 1d8ebd2baba..37bd1e2ba14 100644
--- a/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java
+++ b/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java
@@ -280,6 +280,37 @@ public final class ByteBlockPool {
} while(true);
}
+ /**
+ *
+ */
+ public final BytesRef copyFrom(final BytesRef bytes) {
+ final int length = bytes.length;
+ final int offset = bytes.offset;
+ bytes.offset = 0;
+ bytes.grow(length);
+ int bufferIndex = offset >> BYTE_BLOCK_SHIFT;
+ byte[] buffer = buffers[bufferIndex];
+ int pos = offset & BYTE_BLOCK_MASK;
+ int overflow = (pos + length) - BYTE_BLOCK_SIZE;
+ do {
+ if (overflow <= 0) {
+ System.arraycopy(buffer, pos, bytes.bytes, bytes.offset, bytes.length);
+ bytes.length = length;
+ bytes.offset = 0;
+ break;
+ } else {
+ final int bytesToCopy = length - overflow;
+ System.arraycopy(buffer, pos, bytes.bytes, bytes.offset, bytesToCopy);
+ pos = 0;
+ bytes.length -= bytesToCopy;
+ bytes.offset += bytesToCopy;
+ buffer = buffers[++bufferIndex];
+ overflow = overflow - BYTE_BLOCK_SIZE;
+ }
+ } while (true);
+ return bytes;
+ }
+
/**
* Writes the pools content to the given {@link DataOutput}
*/
diff --git a/lucene/core/src/java/org/apache/lucene/util/BytesRef.java b/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
index be14c25d90c..900a96f5746 100644
--- a/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
@@ -233,13 +233,7 @@ public final class BytesRef implements Comparable,Cloneable {
final byte[] bBytes = b.bytes;
int bUpto = b.offset;
- final int aStop;
- if (a.length < b.length) {
- aStop = aUpto + a.length;
- } else {
- aStop = aUpto + b.length;
- }
-
+ final int aStop = aUpto + Math.min(a.length, b.length);
while(aUpto < aStop) {
int aByte = aBytes[aUpto++] & 0xff;
int bByte = bBytes[bUpto++] & 0xff;
diff --git a/lucene/core/src/java/org/apache/lucene/util/BytesRefIterator.java b/lucene/core/src/java/org/apache/lucene/util/BytesRefIterator.java
new file mode 100644
index 00000000000..b22ec1ab758
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/util/BytesRefIterator.java
@@ -0,0 +1,65 @@
+package org.apache.lucene.util;
+
+/**
+ * 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 java.util.Comparator;
+
+/**
+ * A simple iterator interface for {@link BytesRef} iteration
+ *
+ */
+public interface BytesRefIterator {
+
+ public static final BytesRefIterator EMPTY_ITERATOR = new EmptyBytesRefIterator();
+
+ /**
+ * Increments the iteration to the next {@link BytesRef} in the iterator.
+ * Returns the resulting {@link BytesRef} or null
if the end of
+ * the iterator is reached. The returned BytesRef may be re-used across calls
+ * to next. After this method returns null, do not call it again: the results
+ * are undefined.
+ *
+ * @return the next {@link BytesRef} in the iterator or null
if
+ * the end of the iterator is reached.
+ * @throws IOException
+ */
+ public BytesRef next() throws IOException;
+
+ /**
+ * Return the {@link BytesRef} Comparator used to sort terms provided by the
+ * iterator. This may return null if there are no items or the iterator is not
+ * sorted. Callers may invoke this method many times, so it's best to cache a
+ * single instance & reuse it.
+ */
+ public Comparator getComparator();
+
+ public final static class EmptyBytesRefIterator implements BytesRefIterator {
+
+ @Override
+ public BytesRef next() throws IOException {
+ return null;
+ }
+
+ public Comparator getComparator() {
+ return null;
+ }
+
+ }
+
+}
diff --git a/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java b/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java
index 1313f8ad66b..a2317901fdf 100644
--- a/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java
+++ b/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java
@@ -23,7 +23,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.CompositeReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.FieldCache;
diff --git a/lucene/core/src/java/org/apache/lucene/util/IndexableBinaryStringTools.java b/lucene/core/src/java/org/apache/lucene/util/IndexableBinaryStringTools.java
index 1a2fc7f02ef..fdb1e71d9c7 100644
--- a/lucene/core/src/java/org/apache/lucene/util/IndexableBinaryStringTools.java
+++ b/lucene/core/src/java/org/apache/lucene/util/IndexableBinaryStringTools.java
@@ -17,8 +17,6 @@ package org.apache.lucene.util;
* limitations under the License.
*/
-import java.nio.CharBuffer;
-import java.nio.ByteBuffer;
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute; // javadoc
/**
diff --git a/lucene/core/src/java/org/apache/lucene/util/ReaderUtil.java b/lucene/core/src/java/org/apache/lucene/util/ReaderUtil.java
index 62dd44a45bb..476b35e1b11 100644
--- a/lucene/core/src/java/org/apache/lucene/util/ReaderUtil.java
+++ b/lucene/core/src/java/org/apache/lucene/util/ReaderUtil.java
@@ -17,13 +17,10 @@ package org.apache.lucene.util;
* limitations under the License.
*/
-import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import org.apache.lucene.index.AtomicReaderContext;
-import org.apache.lucene.index.FieldInfo;
-import org.apache.lucene.index.FieldInfos;
import org.apache.lucene.index.CompositeReader;
import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.IndexReader;
diff --git a/lucene/core/src/java/org/apache/lucene/util/RollingCharBuffer.java b/lucene/core/src/java/org/apache/lucene/util/RollingCharBuffer.java
new file mode 100644
index 00000000000..bd840f462d5
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/util/RollingCharBuffer.java
@@ -0,0 +1,148 @@
+package org.apache.lucene.util;
+
+/**
+ * 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 java.io.Reader;
+
+/** Acts like a forever growing char[] as you read
+ * characters into it from the provided reader, but
+ * internally it uses a circular buffer to only hold the
+ * characters that haven't been freed yet. This is like a
+ * PushbackReader, except you don't have to specify
+ * up-front the max size of the buffer, but you do have to
+ * periodically call {@link #freeBefore}. */
+
+public final class RollingCharBuffer {
+
+ private Reader reader;
+
+ private char[] buffer = new char[32];
+
+ // Next array index to write to in buffer:
+ private int nextWrite;
+
+ // Next absolute position to read from reader:
+ private int nextPos;
+
+ // How many valid chars (wrapped) are in the buffer:
+ private int count;
+
+ // True if we hit EOF
+ private boolean end;
+
+ /** Clear array and switch to new reader. */
+ public void reset(Reader reader) {
+ this.reader = reader;
+ nextPos = 0;
+ nextWrite = 0;
+ count = 0;
+ end = false;
+ }
+
+ /* Absolute position read. NOTE: pos must not jump
+ * ahead by more than 1! Ie, it's OK to read arbitarily
+ * far back (just not prior to the last {@link
+ * #freeBefore}), but NOT ok to read arbitrarily far
+ * ahead. Returns -1 if you hit EOF. */
+ public int get(int pos) throws IOException {
+ //System.out.println(" get pos=" + pos + " nextPos=" + nextPos + " count=" + count);
+ if (pos == nextPos) {
+ if (end) {
+ return -1;
+ }
+ final int ch = reader.read();
+ if (ch == -1) {
+ end = true;
+ return -1;
+ }
+ if (count == buffer.length) {
+ // Grow
+ final char[] newBuffer = new char[ArrayUtil.oversize(1+count, RamUsageEstimator.NUM_BYTES_CHAR)];
+ //System.out.println(Thread.currentThread().getName() + ": cb grow " + newBuffer.length);
+ System.arraycopy(buffer, nextWrite, newBuffer, 0, buffer.length - nextWrite);
+ System.arraycopy(buffer, 0, newBuffer, buffer.length - nextWrite, nextWrite);
+ nextWrite = buffer.length;
+ buffer = newBuffer;
+ }
+ if (nextWrite == buffer.length) {
+ nextWrite = 0;
+ }
+ buffer[nextWrite++] = (char) ch;
+ count++;
+ nextPos++;
+ return ch;
+ } else {
+ // Cannot read from future (except by 1):
+ assert pos < nextPos;
+
+ // Cannot read from already freed past:
+ assert nextPos - pos <= count;
+
+ final int index = getIndex(pos);
+ return buffer[index];
+ }
+ }
+
+ // For assert:
+ private boolean inBounds(int pos) {
+ return pos >= 0 && pos < nextPos && pos >= nextPos - count;
+ }
+
+ private int getIndex(int pos) {
+ int index = nextWrite - (nextPos - pos);
+ if (index < 0) {
+ // Wrap:
+ index += buffer.length;
+ assert index >= 0;
+ }
+ return index;
+ }
+
+ public char[] get(int posStart, int length) {
+ assert length > 0;
+ assert inBounds(posStart): "posStart=" + posStart + " length=" + length;
+ //System.out.println(" buffer.get posStart=" + posStart + " len=" + length);
+
+ final int startIndex = getIndex(posStart);
+ final int endIndex = getIndex(posStart + length);
+ //System.out.println(" startIndex=" + startIndex + " endIndex=" + endIndex);
+
+ final char[] result = new char[length];
+ if (endIndex >= startIndex && length < buffer.length) {
+ System.arraycopy(buffer, startIndex, result, 0, endIndex-startIndex);
+ } else {
+ // Wrapped:
+ final int part1 = buffer.length-startIndex;
+ System.arraycopy(buffer, startIndex, result, 0, part1);
+ System.arraycopy(buffer, 0, result, buffer.length-startIndex, length-part1);
+ }
+ return result;
+ }
+
+ /** Call this to notify us that no chars before this
+ * absolute position are needed anymore. */
+ public void freeBefore(int pos) {
+ assert pos >= 0;
+ assert pos <= nextPos;
+ final int newCount = nextPos - pos;
+ assert newCount <= count: "newCount=" + newCount + " count=" + count;
+ assert newCount <= buffer.length: "newCount=" + newCount + " buf.length=" + buffer.length;
+ count = newCount;
+ }
+}
diff --git a/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java b/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java
index 4311ece1032..f9434891738 100644
--- a/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java
+++ b/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java
@@ -430,7 +430,7 @@ public class Automaton implements Cloneable {
}
}
// map>
- @SuppressWarnings("unchecked") Set map[] = new Set[states.length];
+ @SuppressWarnings({"rawtypes","unchecked"}) Set map[] = new Set[states.length];
for (int i = 0; i < map.length; i++)
map[i] = new HashSet();
for (State s : states) {
diff --git a/lucene/core/src/java/org/apache/lucene/util/automaton/MinimizationOperations.java b/lucene/core/src/java/org/apache/lucene/util/automaton/MinimizationOperations.java
index 7c3e4cf4ed6..b5fd0cad33b 100644
--- a/lucene/core/src/java/org/apache/lucene/util/automaton/MinimizationOperations.java
+++ b/lucene/core/src/java/org/apache/lucene/util/automaton/MinimizationOperations.java
@@ -74,11 +74,11 @@ final public class MinimizationOperations {
final int[] sigma = a.getStartPoints();
final State[] states = a.getNumberedStates();
final int sigmaLen = sigma.length, statesLen = states.length;
- @SuppressWarnings("unchecked") final ArrayList[][] reverse =
+ @SuppressWarnings({"rawtypes","unchecked"}) final ArrayList[][] reverse =
(ArrayList[][]) new ArrayList[statesLen][sigmaLen];
- @SuppressWarnings("unchecked") final HashSet[] partition =
+ @SuppressWarnings({"rawtypes","unchecked"}) final HashSet[] partition =
(HashSet[]) new HashSet[statesLen];
- @SuppressWarnings("unchecked") final ArrayList[] splitblock =
+ @SuppressWarnings({"rawtypes","unchecked"}) final ArrayList[] splitblock =
(ArrayList[]) new ArrayList[statesLen];
final int[] block = new int[statesLen];
final StateList[][] active = new StateList[statesLen][sigmaLen];
diff --git a/lucene/core/src/java/org/apache/lucene/util/fst/Builder.java b/lucene/core/src/java/org/apache/lucene/util/fst/Builder.java
index fbda31bb99f..01e692781a1 100644
--- a/lucene/core/src/java/org/apache/lucene/util/fst/Builder.java
+++ b/lucene/core/src/java/org/apache/lucene/util/fst/Builder.java
@@ -144,7 +144,8 @@ public class Builder {
}
NO_OUTPUT = outputs.getNoOutput();
- @SuppressWarnings("unchecked") final UnCompiledNode[] f = (UnCompiledNode[]) new UnCompiledNode[10];
+ @SuppressWarnings({"rawtypes","unchecked"}) final UnCompiledNode[] f =
+ (UnCompiledNode[]) new UnCompiledNode[10];
frontier = f;
for(int idx=0;idx(this, idx);
@@ -239,7 +240,8 @@ public class Builder {
if (node.inputCount < minSuffixCount2 || (minSuffixCount2 == 1 && node.inputCount == 1 && idx > 1)) {
// drop all arcs
for(int arcIdx=0;arcIdx target = (UnCompiledNode) node.arcs[arcIdx].target;
+ @SuppressWarnings({"rawtypes","unchecked"}) final UnCompiledNode target =
+ (UnCompiledNode) node.arcs[arcIdx].target;
target.clear();
}
node.numArcs = 0;
@@ -356,7 +358,7 @@ public class Builder {
final int prefixLenPlus1 = pos1+1;
if (frontier.length < input.length+1) {
- @SuppressWarnings("unchecked") final UnCompiledNode[] next =
+ @SuppressWarnings({"rawtypes","unchecked"}) final UnCompiledNode[] next =
new UnCompiledNode[ArrayUtil.oversize(input.length+1, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
System.arraycopy(frontier, 0, next, 0, frontier.length);
for(int idx=frontier.length;idx {
final Arc arc = node.arcs[arcIdx];
if (!arc.target.isCompiled()) {
// not yet compiled
- @SuppressWarnings("unchecked") final UnCompiledNode n = (UnCompiledNode) arc.target;
+ @SuppressWarnings({"rawtypes","unchecked"}) final UnCompiledNode n = (UnCompiledNode) arc.target;
if (n.numArcs == 0) {
//System.out.println("seg=" + segment + " FORCE final arc=" + (char) arc.label);
arc.isFinal = n.isFinal = true;
@@ -512,7 +514,7 @@ public class Builder {
* LUCENE-2934 (node expansion based on conditions other than the
* fanout size).
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"rawtypes","unchecked"})
public UnCompiledNode(Builder owner, int depth) {
this.owner = owner;
arcs = (Arc[]) new Arc[1];
@@ -545,7 +547,7 @@ public class Builder {
assert label >= 0;
assert numArcs == 0 || label > arcs[numArcs-1].label: "arc[-1].label=" + arcs[numArcs-1].label + " new label=" + label + " numArcs=" + numArcs;
if (numArcs == arcs.length) {
- @SuppressWarnings("unchecked") final Arc[] newArcs =
+ @SuppressWarnings({"rawtypes","unchecked"}) final Arc[] newArcs =
new Arc[ArrayUtil.oversize(numArcs+1, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
System.arraycopy(arcs, 0, newArcs, 0, arcs.length);
for(int arcIdx=numArcs;arcIdx {
}
// Caches first 128 labels
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"rawtypes","unchecked"})
private void cacheRootArcs() throws IOException {
cachedRootArcs = (Arc[]) new Arc[0x80];
final Arc arc = new Arc();
@@ -840,6 +840,7 @@ public final class FST {
}
public Arc readFirstRealTargetArc(int node, Arc arc, final BytesReader in) throws IOException {
+ assert in.bytes == bytes;
final int address = getNodeAddress(node);
in.pos = address;
//System.out.println(" readFirstRealTargtArc address="
@@ -936,6 +937,7 @@ public final class FST {
/** Never returns null, but you should never call this if
* arc.isLast() is true. */
public Arc readNextRealArc(Arc arc, final BytesReader in) throws IOException {
+ assert in.bytes == bytes;
// TODO: can't assert this because we call from readFirstArc
// assert !flag(arc.flags, BIT_LAST_ARC);
@@ -1019,6 +1021,7 @@ public final class FST {
* This returns null if the arc was not found, else the incoming arc. */
public Arc findTargetArc(int labelToMatch, Arc follow, Arc arc, BytesReader in) throws IOException {
assert cachedRootArcs != null;
+ assert in.bytes == bytes;
if (labelToMatch == END_LABEL) {
if (follow.isFinal()) {
@@ -1225,17 +1228,20 @@ public final class FST {
/** Expert */
public static abstract class BytesReader extends DataInput {
- int pos;
+ protected int pos;
+ protected final byte[] bytes;
+ protected BytesReader(byte[] bytes, int pos) {
+ this.bytes = bytes;
+ this.pos = pos;
+ }
abstract void skip(int byteCount);
abstract void skip(int base, int byteCount);
}
final static class ReverseBytesReader extends BytesReader {
- final byte[] bytes;
public ReverseBytesReader(byte[] bytes, int pos) {
- this.bytes = bytes;
- this.pos = pos;
+ super(bytes, pos);
}
@Override
@@ -1262,11 +1268,9 @@ public final class FST {
// TODO: can we use just ByteArrayDataInput...? need to
// add a .skipBytes to DataInput.. hmm and .setPosition
final static class ForwardBytesReader extends BytesReader {
- final byte[] bytes;
public ForwardBytesReader(byte[] bytes, int pos) {
- this.bytes = bytes;
- this.pos = pos;
+ super(bytes, pos);
}
@Override
diff --git a/lucene/core/src/java/org/apache/lucene/util/fst/FSTEnum.java b/lucene/core/src/java/org/apache/lucene/util/fst/FSTEnum.java
index 6abe25b7978..b65f1808341 100644
--- a/lucene/core/src/java/org/apache/lucene/util/fst/FSTEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/util/fst/FSTEnum.java
@@ -30,9 +30,9 @@ import java.io.IOException;
abstract class FSTEnum {
protected final FST fst;
- @SuppressWarnings("unchecked") protected FST.Arc[] arcs = new FST.Arc[10];
+ @SuppressWarnings({"rawtypes","unchecked"}) protected FST.Arc[] arcs = new FST.Arc[10];
// outputs are cumulative
- @SuppressWarnings("unchecked") protected T[] output = (T[]) new Object[10];
+ @SuppressWarnings({"rawtypes","unchecked"}) protected T[] output = (T[]) new Object[10];
protected final T NO_OUTPUT;
protected final FST.Arc scratchArc = new FST.Arc();
@@ -462,13 +462,13 @@ abstract class FSTEnum {
upto++;
grow();
if (arcs.length <= upto) {
- @SuppressWarnings("unchecked") final FST.Arc[] newArcs =
+ @SuppressWarnings({"rawtypes","unchecked"}) final FST.Arc[] newArcs =
new FST.Arc[ArrayUtil.oversize(1+upto, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
System.arraycopy(arcs, 0, newArcs, 0, arcs.length);
arcs = newArcs;
}
if (output.length <= upto) {
- @SuppressWarnings("unchecked") final T[] newOutput =
+ @SuppressWarnings({"rawtypes","unchecked"}) final T[] newOutput =
(T[]) new Object[ArrayUtil.oversize(1+upto, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
System.arraycopy(output, 0, newOutput, 0, output.length);
output = newOutput;
diff --git a/lucene/core/src/java/org/apache/lucene/util/fst/Util.java b/lucene/core/src/java/org/apache/lucene/util/fst/Util.java
index d8be1dcdbc3..4f37e447c7d 100644
--- a/lucene/core/src/java/org/apache/lucene/util/fst/Util.java
+++ b/lucene/core/src/java/org/apache/lucene/util/fst/Util.java
@@ -83,11 +83,6 @@ public final class Util {
}
}
- // TODO: parameterize the FST type and allow passing in a
- // comparator; eg maybe your output is a PairOutput and
- // one of the outputs in the pair is monotonic so you
- // compare by that
-
/** Reverse lookup (lookup by output instead of by input),
* in the special case when your FSTs outputs are
* strictly ascending. This locates the input/output
@@ -133,7 +128,7 @@ public final class Util {
}
}
- if (fst.targetHasArcs(arc)) {
+ if (FST.targetHasArcs(arc)) {
//System.out.println(" targetHasArcs");
if (result.ints.length == upto) {
result.grow(1+upto);
@@ -155,7 +150,7 @@ public final class Util {
final byte flags = in.readByte();
fst.readLabel(in);
final long minArcOutput;
- if ((flags & fst.BIT_ARC_HAS_OUTPUT) != 0) {
+ if ((flags & FST.BIT_ARC_HAS_OUTPUT) != 0) {
final long arcOutput = fst.outputs.read(in);
minArcOutput = output + arcOutput;
} else {
@@ -235,14 +230,16 @@ public final class Util {
}
}
- private static class FSTPath implements Comparable {
- public FST.Arc arc;
- public long cost;
+ private static class FSTPath implements Comparable> {
+ public FST.Arc arc;
+ public T cost;
public final IntsRef input = new IntsRef();
+ final Comparator comparator;
- public FSTPath(long cost, FST.Arc arc) {
- this.arc = new FST.Arc().copyFrom(arc);
+ public FSTPath(T cost, FST.Arc arc, Comparator comparator) {
+ this.arc = new FST.Arc().copyFrom(arc);
this.cost = cost;
+ this.comparator = comparator;
}
@Override
@@ -251,48 +248,50 @@ public final class Util {
}
@Override
- public int compareTo(FSTPath other) {
- if (cost < other.cost) {
- return -1;
- } else if (cost > other.cost) {
- return 1;
- } else {
+ public int compareTo(FSTPath other) {
+ int cmp = comparator.compare(cost, other.cost);
+ if (cmp == 0) {
return input.compareTo(other.input);
+ } else {
+ return cmp;
}
}
}
- private static class TopNSearcher {
+ private static class TopNSearcher {
- private final FST fst;
- private final FST.Arc fromNode;
+ private final FST fst;
+ private final FST.Arc fromNode;
private final int topN;
+
+ final Comparator comparator;
// Set once the queue has filled:
- FSTPath bottom = null;
+ FSTPath bottom = null;
- TreeSet queue = null;
+ TreeSet> queue = null;
- public TopNSearcher(FST fst, FST.Arc fromNode, int topN) {
+ public TopNSearcher(FST fst, FST.Arc fromNode, int topN, Comparator comparator) {
this.fst = fst;
this.topN = topN;
this.fromNode = fromNode;
+ this.comparator = comparator;
}
// If back plus this arc is competitive then add to queue:
- private void addIfCompetitive(FSTPath path) {
+ private void addIfCompetitive(FSTPath path) {
assert queue != null;
- long cost = path.cost + path.arc.output;
+ T cost = fst.outputs.add(path.cost, path.arc.output);
//System.out.println(" addIfCompetitive bottom=" + bottom + " queue.size()=" + queue.size());
if (bottom != null) {
-
- if (cost > bottom.cost) {
+ int comp = comparator.compare(cost, bottom.cost);
+ if (comp > 0) {
// Doesn't compete
return;
- } else if (cost == bottom.cost) {
+ } else if (comp == 0) {
// Tie break by alpha sort on the input:
path.input.grow(path.input.length+1);
path.input.ints[path.input.length++] = path.arc.label;
@@ -309,7 +308,7 @@ public final class Util {
// Queue isn't full yet, so any path we hit competes:
}
- final FSTPath newPath = new FSTPath(cost, path.arc);
+ final FSTPath newPath = new FSTPath(cost, path.arc, comparator);
newPath.input.grow(path.input.length+1);
System.arraycopy(path.input.ints, 0, newPath.input.ints, 0, path.input.length);
@@ -319,7 +318,7 @@ public final class Util {
//System.out.println(" add path=" + newPath);
queue.add(newPath);
if (bottom != null) {
- final FSTPath removed = queue.pollLast();
+ final FSTPath removed = queue.pollLast();
assert removed == bottom;
bottom = queue.last();
//System.out.println(" now re-set bottom: " + bottom + " queue=" + queue);
@@ -330,13 +329,13 @@ public final class Util {
}
}
- public MinResult[] search() throws IOException {
+ public MinResult[] search() throws IOException {
//System.out.println(" search topN=" + topN);
- final FST.Arc scratchArc = new FST.Arc();
+ final FST.Arc scratchArc = new FST.Arc();
- final List results = new ArrayList();
+ final List> results = new ArrayList>();
- final Long NO_OUTPUT = fst.outputs.getNoOutput();
+ final T NO_OUTPUT = fst.outputs.getNoOutput();
// TODO: we could enable FST to sorting arcs by weight
// as it freezes... can easily do this on first pass
@@ -349,7 +348,7 @@ public final class Util {
while (results.size() < topN) {
//System.out.println("\nfind next path");
- FSTPath path;
+ FSTPath path;
if (queue == null) {
@@ -360,20 +359,20 @@ public final class Util {
// First pass (top path): start from original fromNode
if (topN > 1) {
- queue = new TreeSet();
+ queue = new TreeSet>();
}
- long minArcCost = Long.MAX_VALUE;
- FST.Arc minArc = null;
+ T minArcCost = null;
+ FST.Arc minArc = null;
- path = new FSTPath(0, fromNode);
+ path = new FSTPath(NO_OUTPUT, fromNode, comparator);
fst.readFirstTargetArc(fromNode, path.arc);
// Bootstrap: find the min starting arc
while (true) {
- long arcScore = path.arc.output;
+ T arcScore = path.arc.output;
//System.out.println(" arc=" + (char) path.arc.label + " cost=" + arcScore);
- if (arcScore < minArcCost) {
+ if (minArcCost == null || comparator.compare(arcScore, minArcCost) < 0) {
minArcCost = arcScore;
minArc = scratchArc.copyFrom(path.arc);
//System.out.println(" **");
@@ -419,7 +418,7 @@ public final class Util {
//System.out.println(" empty string! cost=" + path.cost);
// Empty string!
path.input.length--;
- results.add(new MinResult(path.input, path.cost));
+ results.add(new MinResult(path.input, path.cost, comparator));
continue;
}
@@ -439,15 +438,16 @@ public final class Util {
// For each input letter:
while (true) {
- //System.out.println("\n cycle path: " + path);
-
+ //System.out.println("\n cycle path: " + path);
fst.readFirstTargetArc(path.arc, path.arc);
// For each arc leaving this node:
boolean foundZero = false;
while(true) {
//System.out.println(" arc=" + (char) path.arc.label + " cost=" + path.arc.output);
- if (path.arc.output == NO_OUTPUT) {
+ // tricky: instead of comparing output == 0, we must
+ // express it via the comparator compare(output, 0) == 0
+ if (comparator.compare(NO_OUTPUT, path.arc.output) == 0) {
if (queue == null) {
foundZero = true;
break;
@@ -479,55 +479,53 @@ public final class Util {
if (path.arc.label == FST.END_LABEL) {
// Add final output:
//System.out.println(" done!: " + path);
- results.add(new MinResult(path.input, path.cost + path.arc.output));
+ results.add(new MinResult