You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2018/02/04 08:53:14 UTC
[2/2] lucene-solr:branch_7x: LUCENE-7966: Build Multi-Release JARs to
enable usage of optimized intrinsic methods from Java 9 for index bounds
checking and array comparison/mismatch
LUCENE-7966: Build Multi-Release JARs to enable usage of optimized intrinsic methods from Java 9 for index bounds checking and array comparison/mismatch
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/05a105a9
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/05a105a9
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/05a105a9
Branch: refs/heads/branch_7x
Commit: 05a105a9f76b73b597931894dff392ad44243aa0
Parents: 7fbdf5d
Author: Uwe Schindler <us...@apache.org>
Authored: Sat Feb 3 09:17:59 2018 +0100
Committer: Uwe Schindler <us...@apache.org>
Committed: Sun Feb 4 09:51:40 2018 +0100
----------------------------------------------------------------------
build.xml | 1 +
lucene/CHANGES.txt | 6 +
lucene/build.xml | 2 +-
.../blockterms/FixedGapTermsIndexWriter.java | 8 +-
.../SimpleTextStoredFieldsReader.java | 5 +-
lucene/common-build.xml | 48 ++-
lucene/core/build.xml | 9 +
.../tokenattributes/CharTermAttributeImpl.java | 19 +-
.../CompressingTermVectorsWriter.java | 8 +-
.../apache/lucene/codecs/compressing/LZ4.java | 8 +-
.../lucene70/Lucene70DocValuesConsumer.java | 8 +-
.../org/apache/lucene/document/BinaryPoint.java | 4 +-
.../org/apache/lucene/document/DoubleRange.java | 11 +-
.../org/apache/lucene/document/FloatRange.java | 11 +-
.../org/apache/lucene/document/IntRange.java | 11 +-
.../org/apache/lucene/document/LongRange.java | 11 +-
.../java/org/apache/lucene/index/BitsSlice.java | 6 +-
.../org/apache/lucene/index/CodecReader.java | 5 +-
.../apache/lucene/index/MergeReaderWrapper.java | 5 +-
.../apache/lucene/index/PrefixCodedTerms.java | 28 +-
.../org/apache/lucene/search/BooleanScorer.java | 5 +-
.../java/org/apache/lucene/util/ArrayUtil.java | 52 ----
.../java/org/apache/lucene/util/BytesRef.java | 39 +--
.../org/apache/lucene/util/BytesRefArray.java | 36 +--
.../java/org/apache/lucene/util/CharsRef.java | 102 ++-----
.../org/apache/lucene/util/FutureArrays.java | 268 ++++++++++++++++
.../org/apache/lucene/util/FutureObjects.java | 70 +++++
.../java/org/apache/lucene/util/IntsRef.java | 38 +--
.../java/org/apache/lucene/util/LongsRef.java | 38 +--
.../org/apache/lucene/util/StringHelper.java | 87 ++----
.../apache/lucene/util/automaton/Automaton.java | 25 +-
.../TestCharTermAttributeImpl.java | 3 +-
.../org/apache/lucene/util/TestArrayUtil.java | 16 -
.../apache/lucene/util/TestFutureArrays.java | 305 +++++++++++++++++++
.../apache/lucene/util/TestFutureObjects.java | 102 +++++++
.../apache/lucene/util/TestStringHelper.java | 13 +
.../org/apache/lucene/util/TestUnicodeUtil.java | 3 +-
.../lucene/facet/taxonomy/TaxonomyWriter.java | 2 +-
.../directory/DirectoryTaxonomyWriter.java | 5 +-
.../facet/taxonomy/TestTaxonomyCombined.java | 6 +-
lucene/module-build.xml | 9 +
.../tools/src/groovy/patch-mrjar-classes.groovy | 73 +++++
solr/common-build.xml | 3 +
43 files changed, 1074 insertions(+), 440 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index a100e12..2d300b5 100755
--- a/build.xml
+++ b/build.xml
@@ -874,4 +874,5 @@ Test args: [${args}]</echo>
<!-- useless targets (override common-build.xml): -->
<target name="generate-test-reports"/>
+ <target name="patch-mrjar-classes"/>
</project>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 7a27718..f59768d 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -54,6 +54,12 @@ Improvements
* LUCENE-8129: A Unicode set filter can now be specified when using ICUFoldingFilter.
(Ere Maijala)
+* LUCENE-7966: Build Multi-Release JARs to enable usage of optimized intrinsic methods
+ from Java 9 for index bounds checking and array comparison/mismatch. This change
+ introduces Java 8 replacements for those Java 9 methods and patches the compiled
+ classes to use the optimized variants through the MR-JAR mechanism.
+ (Uwe Schindler, Robert Muir, Adrien Grand, Mike McCandless)
+
Bug Fixes
* LUCENE-8077: Fixed bug in how CheckIndex verifies doc-value iterators.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/build.xml
----------------------------------------------------------------------
diff --git a/lucene/build.xml b/lucene/build.xml
index 3aa4e42..f2ce68d 100644
--- a/lucene/build.xml
+++ b/lucene/build.xml
@@ -557,7 +557,7 @@
</target>
<!-- Override common-build.xml definition to check for the jar already being up-to-date -->
- <target name="jar-core" depends="check-lucene-core-uptodate,compile-lucene-core" unless="lucene-core.uptodate">
+ <target name="jar-core" depends="resolve-groovy,check-lucene-core-uptodate,compile-lucene-core" unless="lucene-core.uptodate">
<ant dir="${common.dir}/core" target="jar-core" inheritAll="false">
<propertyset refid="uptodate.and.compiled.properties"/>
</ant>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java
index cdfd962..abb4cb0 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java
@@ -150,7 +150,13 @@ public class FixedGapTermsIndexWriter extends TermsIndexWriterBase {
@Override
public void add(BytesRef text, TermStats stats, long termsFilePointer) throws IOException {
- final int indexedTermLength = indexedTermPrefixLength(lastTerm.get(), text);
+ final int indexedTermLength;
+ if (numIndexTerms == 0) {
+ // no previous term: no bytes to write
+ indexedTermLength = 0;
+ } else {
+ indexedTermLength = indexedTermPrefixLength(lastTerm.get(), text);
+ }
//System.out.println("FGW: add text=" + text.utf8ToString() + " " + text + " fp=" + termsFilePointer);
// write only the min prefix that shows the diff
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java
index ead8ecc..b457ca5 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java
@@ -36,6 +36,7 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.CharsRef;
import org.apache.lucene.util.CharsRefBuilder;
+import org.apache.lucene.util.FutureArrays;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.lucene.util.StringHelper;
@@ -202,8 +203,8 @@ public class SimpleTextStoredFieldsReader extends StoredFieldsReader {
}
private boolean equalsAt(BytesRef a, BytesRef b, int bOffset) {
- return a.length == b.length - bOffset &&
- ArrayUtil.equals(a.bytes, a.offset, b.bytes, b.offset + bOffset, b.length - bOffset);
+ return a.length == b.length - bOffset &&
+ FutureArrays.equals(a.bytes, a.offset, a.offset + a.length, b.bytes, b.offset + bOffset, b.offset + b.length);
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/common-build.xml
----------------------------------------------------------------------
diff --git a/lucene/common-build.xml b/lucene/common-build.xml
index f6f4da3..7ce8d6f 100644
--- a/lucene/common-build.xml
+++ b/lucene/common-build.xml
@@ -160,6 +160,10 @@
<!-- Display at most this many failures as a summary at the end of junit4 run. -->
<property name="tests.showNumFailures" value="10" />
+
+ <!-- If we detect Java 9+, should we test the patched classes of the
+ multi-release JAR or still run with our own classes? -->
+ <property name="tests.withJava9Patches" value="true" />
<property name="javac.deprecation" value="off"/>
<property name="javac.debug" value="on"/>
@@ -546,10 +550,48 @@
<!-- convenience target to compile core -->
</target>
- <target name="jar-core" depends="compile-core">
+ <!-- Special targets to patch all class files by replacing some method calls with new Java 9 methods: -->
+ <target name="-mrjar-classes-uptodate">
+ <uptodate property="mrjar-classes-uptodate" targetfile="${build.dir}/patch-mrjar.stamp">
+ <srcfiles dir= "${build.dir}/classes/java" includes="**/*.class"/>
+ </uptodate>
+ </target>
+
+ <target xmlns:ivy="antlib:org.apache.ivy.ant" name="patch-mrjar-classes" depends="-mrjar-classes-uptodate,ivy-availability-check,ivy-configure,resolve-groovy,compile-core"
+ unless="mrjar-classes-uptodate" description="Patches compiled class files for usage with Java 9 in MR-JAR">
+ <loadproperties prefix="ivyversions" srcFile="${common.dir}/ivy-versions.properties"/>
+ <ivy:cachepath organisation="org.ow2.asm" module="asm-commons" revision="${ivyversions./org.ow2.asm/asm-commons}"
+ inline="true" conf="default" transitive="true" log="download-only" pathid="asm.classpath"/>
+ <groovy classpathref="asm.classpath" src="${common.dir}/tools/src/groovy/patch-mrjar-classes.groovy"/>
+ <touch file="${build.dir}/patch-mrjar.stamp"/>
+ </target>
+
+ <target name="-mrjar-check" depends="patch-mrjar-classes">
+ <zipfileset id="mrjar-patched-files" prefix="META-INF/versions/9" dir="${build.dir}/classes/java9"/>
+ <condition property="has-mrjar-patched-files">
+ <resourcecount refid="mrjar-patched-files" when="greater" count="0" />
+ </condition>
+ </target>
+
+ <target name="-mrjar-core" depends="-mrjar-check" if="has-mrjar-patched-files">
+ <jarify>
+ <filesets>
+ <zipfileset refid="mrjar-patched-files"/>
+ </filesets>
+ <jarify-additional-manifest-attributes>
+ <attribute name="Multi-Release" value="true"/>
+ </jarify-additional-manifest-attributes>
+ </jarify>
+ </target>
+
+ <target name="-jar-core" depends="-mrjar-check" unless="has-mrjar-patched-files">
<jarify/>
</target>
+
+ <target name="jar-core" depends="-mrjar-core,-jar-core"/>
+ <!-- Packaging targets: -->
+
<property name="lucene.tgz.file" location="${common.dir}/dist/lucene-${version}.tgz"/>
<available file="${lucene.tgz.file}" property="lucene.tgz.exists"/>
<property name="lucene.tgz.unpack.dir" location="${common.build.dir}/lucene.tgz.unpacked"/>
@@ -1453,8 +1495,8 @@ ${tests-output}/junit4-*.suites - per-JVM executed suites
</taskdef>
</target>
- <target name="test" depends="clover,compile-test,install-junit4-taskdef,validate,-init-totals,-test,-check-totals" description="Runs unit tests"/>
- <target name="beast" depends="clover,compile-test,install-junit4-taskdef,validate,-init-totals,-beast,-check-totals" description="Runs unit tests in a loop (-Dbeast.iters=n)"/>
+ <target name="test" depends="clover,compile-test,patch-mrjar-classes,install-junit4-taskdef,validate,-init-totals,-test,-check-totals" description="Runs unit tests"/>
+ <target name="beast" depends="clover,compile-test,patch-mrjar-classes,install-junit4-taskdef,validate,-init-totals,-beast,-check-totals" description="Runs unit tests in a loop (-Dbeast.iters=n)"/>
<target name="test-nocompile" depends="-clover.disable,install-junit4-taskdef,-init-totals,-test,-check-totals"
description="Only runs unit tests. Jars are not downloaded; compilation is not updated; and Clover is not enabled."/>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/build.xml
----------------------------------------------------------------------
diff --git a/lucene/core/build.xml b/lucene/core/build.xml
index d968798..46183b0 100644
--- a/lucene/core/build.xml
+++ b/lucene/core/build.xml
@@ -31,10 +31,19 @@
<path id="classpath"/>
+ <!-- if we run with Java 9+, we refer to the java9 classes directory and insert this before the main classpath (to "emulate" a MR-JAR): -->
+ <condition property="-test.classpath.java9.addon" value="${build.dir}/classes/java9" else="${build.dir}/classes/java">
+ <and>
+ <not><equals arg1="${build.java.runtime}" arg2="1.8"/></not>
+ <istrue value="${tests.withJava9Patches}"/>
+ </and>
+ </condition>
+
<path id="test.classpath">
<pathelement location="${common.dir}/build/codecs/classes/java"/>
<pathelement location="${common.dir}/build/test-framework/classes/java"/>
<path refid="junit-path"/>
+ <pathelement location="${-test.classpath.java9.addon}"/><!-- if it's a duplicate it gets removed by Ant! -->
<pathelement location="${build.dir}/classes/java"/>
<pathelement location="${build.dir}/classes/test"/>
</path>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
index 355f417..f28cc78 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
@@ -23,6 +23,7 @@ import org.apache.lucene.util.AttributeImpl;
import org.apache.lucene.util.AttributeReflector;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
+import org.apache.lucene.util.FutureObjects;
/** Default implementation of {@link CharTermAttribute}. */
public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttribute, TermToBytesRefAttribute, Cloneable {
@@ -71,11 +72,7 @@ public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttr
@Override
public final CharTermAttribute setLength(int length) {
- if (length < 0) {
- throw new IllegalArgumentException("length " + length + " must not be negative");
- }
- if (length > termBuffer.length)
- throw new IllegalArgumentException("length " + length + " exceeds the size of the termBuffer (" + termBuffer.length + ")");
+ FutureObjects.checkFromIndexSize(0, length, termBuffer.length);
termLength = length;
return this;
}
@@ -102,15 +99,13 @@ public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttr
@Override
public final char charAt(int index) {
- if (index >= termLength)
- throw new IndexOutOfBoundsException();
+ FutureObjects.checkIndex(index, termLength);
return termBuffer[index];
}
@Override
public final CharSequence subSequence(final int start, final int end) {
- if (start > termLength || end > termLength)
- throw new IndexOutOfBoundsException();
+ FutureObjects.checkFromToIndex(start, end, termLength);
return new String(termBuffer, start, end - start);
}
@@ -127,9 +122,9 @@ public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttr
public final CharTermAttribute append(CharSequence csq, int start, int end) {
if (csq == null) // needed for Appendable compliance
csq = "null";
- final int len = end - start, csqlen = csq.length();
- if (len < 0 || start > csqlen || end > csqlen)
- throw new IndexOutOfBoundsException();
+ // TODO: the optimized cases (jdk methods) will already do such checks, maybe re-organize this?
+ FutureObjects.checkFromToIndex(start, end, csq.length());
+ final int len = end - start;
if (len == 0)
return this;
resizeBuffer(termLength + len);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsWriter.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsWriter.java
index 26fe890..ee948c3 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsWriter.java
@@ -293,7 +293,13 @@ public final class CompressingTermVectorsWriter extends TermVectorsWriter {
@Override
public void startTerm(BytesRef term, int freq) throws IOException {
assert freq >= 1;
- final int prefix = StringHelper.bytesDifference(lastTerm, term);
+ final int prefix;
+ if (lastTerm.length == 0) {
+ // no previous term: no bytes to write
+ prefix = 0;
+ } else {
+ prefix = StringHelper.bytesDifference(lastTerm, term);
+ }
curField.addTerm(freq, prefix, term.length - prefix);
termSuffixes.writeBytes(term.bytes, term.offset + prefix, term.length - prefix);
// copy last term
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java b/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java
index 44bc82c..cba625f 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.DataOutput;
+import org.apache.lucene.util.FutureArrays;
import org.apache.lucene.util.packed.PackedInts;
/**
@@ -61,11 +62,8 @@ final class LZ4 {
private static int commonBytes(byte[] b, int o1, int o2, int limit) {
assert o1 < o2;
- int count = 0;
- while (o2 < limit && b[o1++] == b[o2++]) {
- ++count;
- }
- return count;
+ // never -1 because lengths always differ
+ return FutureArrays.mismatch(b, o1, limit, b, o2, limit);
}
private static int commonBytesBackward(byte[] b, int o1, int o2, int l1, int l2) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesConsumer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesConsumer.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesConsumer.java
index 2dd68e9..e25e8e7 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesConsumer.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene70/Lucene70DocValuesConsumer.java
@@ -504,7 +504,13 @@ final class Lucene70DocValuesConsumer extends DocValuesConsumer implements Close
for (BytesRef term = iterator.next(); term != null; term = iterator.next()) {
if ((ord & Lucene70DocValuesFormat.TERMS_DICT_REVERSE_INDEX_MASK) == 0) {
writer.add(offset);
- int sortKeyLength = StringHelper.sortKeyLength(previous.get(), term);
+ final int sortKeyLength;
+ if (ord == 0) {
+ // no previous term: no bytes to write
+ sortKeyLength = 0;
+ } else {
+ sortKeyLength = StringHelper.sortKeyLength(previous.get(), term);
+ }
offset += sortKeyLength;
data.writeBytes(term.bytes, term.offset, sortKeyLength);
} else if ((ord & Lucene70DocValuesFormat.TERMS_DICT_REVERSE_INDEX_MASK) == Lucene70DocValuesFormat.TERMS_DICT_REVERSE_INDEX_MASK) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
index 81ef092..693a00f 100644
--- a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
@@ -26,7 +26,7 @@ import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.StringHelper;
+import org.apache.lucene.util.FutureArrays;
/**
* An indexed binary field for fast range filters. If you also
@@ -222,7 +222,7 @@ public final class BinaryPoint extends Field {
new Comparator<byte[]>() {
@Override
public int compare(byte[] a, byte[] b) {
- return StringHelper.compare(a.length, a, 0, b, 0);
+ return FutureArrays.compareUnsigned(a, 0, a.length, b, 0, b.length);
}
});
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java b/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java
index 90a8eb9..c1d2dc5 100644
--- a/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java
@@ -19,6 +19,7 @@ package org.apache.lucene.document;
import org.apache.lucene.document.RangeFieldQuery.QueryType;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.FutureObjects;
import org.apache.lucene.util.NumericUtils;
/**
@@ -147,10 +148,7 @@ public class DoubleRange extends Field {
* @return the decoded min value
*/
public double getMin(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMin(((BytesRef)fieldsData).bytes, dimension);
}
@@ -160,10 +158,7 @@ public class DoubleRange extends Field {
* @return the decoded max value
*/
public double getMax(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMax(((BytesRef)fieldsData).bytes, dimension);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/document/FloatRange.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/FloatRange.java b/lucene/core/src/java/org/apache/lucene/document/FloatRange.java
index 8b40538..facf23b 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FloatRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FloatRange.java
@@ -19,6 +19,7 @@ package org.apache.lucene.document;
import org.apache.lucene.document.RangeFieldQuery.QueryType;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.FutureObjects;
import org.apache.lucene.util.NumericUtils;
/**
@@ -147,10 +148,7 @@ public class FloatRange extends Field {
* @return the decoded min value
*/
public float getMin(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMin(((BytesRef)fieldsData).bytes, dimension);
}
@@ -160,10 +158,7 @@ public class FloatRange extends Field {
* @return the decoded max value
*/
public float getMax(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMax(((BytesRef)fieldsData).bytes, dimension);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/document/IntRange.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/IntRange.java b/lucene/core/src/java/org/apache/lucene/document/IntRange.java
index 6d2b71c..b426613 100644
--- a/lucene/core/src/java/org/apache/lucene/document/IntRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/IntRange.java
@@ -19,6 +19,7 @@ package org.apache.lucene.document;
import org.apache.lucene.document.RangeFieldQuery.QueryType;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.FutureObjects;
import org.apache.lucene.util.NumericUtils;
/**
@@ -147,10 +148,7 @@ public class IntRange extends Field {
* @return the decoded min value
*/
public int getMin(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMin(((BytesRef)fieldsData).bytes, dimension);
}
@@ -160,10 +158,7 @@ public class IntRange extends Field {
* @return the decoded max value
*/
public int getMax(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMax(((BytesRef)fieldsData).bytes, dimension);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/document/LongRange.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongRange.java b/lucene/core/src/java/org/apache/lucene/document/LongRange.java
index 009f4a1..5c1c763 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LongRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LongRange.java
@@ -19,6 +19,7 @@ package org.apache.lucene.document;
import org.apache.lucene.document.RangeFieldQuery.QueryType;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.FutureObjects;
import org.apache.lucene.util.NumericUtils;
/**
@@ -145,10 +146,7 @@ public class LongRange extends Field {
* @return the decoded min value
*/
public long getMin(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMin(((BytesRef)fieldsData).bytes, dimension);
}
@@ -158,10 +156,7 @@ public class LongRange extends Field {
* @return the decoded max value
*/
public long getMax(int dimension) {
- if (dimension < 0 || dimension >= type.pointDimensionCount()/2) {
- throw new IllegalArgumentException("dimension request (" + dimension +
- ") out of bounds for field (name=" + name + " dimensions=" + type.pointDimensionCount()/2 + "). ");
- }
+ FutureObjects.checkIndex(dimension, type.pointDimensionCount()/2);
return decodeMax(((BytesRef)fieldsData).bytes, dimension);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java b/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java
index 216d8f9..19bf9c1 100644
--- a/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java
+++ b/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java
@@ -17,6 +17,7 @@
package org.apache.lucene.index;
import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.FutureObjects;
/**
@@ -39,10 +40,7 @@ final class BitsSlice implements Bits {
@Override
public boolean get(int doc) {
- if (doc >= length) {
- throw new RuntimeException("doc " + doc + " is out of bounds 0 .. " + (length-1));
- }
- assert doc < length: "doc=" + doc + " length=" + length;
+ FutureObjects.checkIndex(doc, length);
return parent.get(doc+start);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/index/CodecReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/CodecReader.java b/lucene/core/src/java/org/apache/lucene/index/CodecReader.java
index 9efcf25..50aaa42 100644
--- a/lucene/core/src/java/org/apache/lucene/index/CodecReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/CodecReader.java
@@ -31,6 +31,7 @@ import org.apache.lucene.codecs.StoredFieldsReader;
import org.apache.lucene.codecs.TermVectorsReader;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.Accountables;
+import org.apache.lucene.util.FutureObjects;
/**
* LeafReader implemented by codec APIs.
@@ -94,9 +95,7 @@ public abstract class CodecReader extends LeafReader implements Accountable {
}
private void checkBounds(int docID) {
- if (docID < 0 || docID >= maxDoc()) {
- throw new IndexOutOfBoundsException("docID must be >= 0 and < maxDoc=" + maxDoc() + " (got docID=" + docID + ")");
- }
+ FutureObjects.checkIndex(docID, maxDoc());
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java b/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java
index 565bdd4..1f35e45 100644
--- a/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java
+++ b/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java
@@ -25,6 +25,7 @@ import org.apache.lucene.codecs.NormsProducer;
import org.apache.lucene.codecs.StoredFieldsReader;
import org.apache.lucene.codecs.TermVectorsReader;
import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.FutureObjects;
/** This is a hack to make index sorting fast, with a {@link LeafReader} that always returns merge instances when you ask for the codec readers. */
class MergeReaderWrapper extends LeafReader {
@@ -226,9 +227,7 @@ class MergeReaderWrapper extends LeafReader {
}
private void checkBounds(int docID) {
- if (docID < 0 || docID >= maxDoc()) {
- throw new IndexOutOfBoundsException("docID must be >= 0 and < maxDoc=" + maxDoc() + " (got docID=" + docID + ")");
- }
+ FutureObjects.checkIndex(docID, maxDoc());
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java b/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java
index ba56c2a..7a65d71 100644
--- a/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java
+++ b/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java
@@ -26,6 +26,7 @@ import org.apache.lucene.store.RAMOutputStream;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
+import org.apache.lucene.util.StringHelper;
/**
* Prefix codes term instances (prefixes are shared). This is expected to be
@@ -74,14 +75,19 @@ public class PrefixCodedTerms implements Accountable {
assert lastTerm.equals(new Term("")) || new Term(field, bytes).compareTo(lastTerm) > 0;
try {
- int prefix = sharedPrefix(lastTerm.bytes, bytes);
- int suffix = bytes.length - prefix;
- if (field.equals(lastTerm.field)) {
+ final int prefix;
+ if (size > 0 && field.equals(lastTerm.field)) {
+ // same field as the last term
+ prefix = StringHelper.bytesDifference(lastTerm.bytes, bytes);
output.writeVInt(prefix << 1);
} else {
- output.writeVInt(prefix << 1 | 1);
+ // field change
+ prefix = 0;
+ output.writeVInt(1);
output.writeString(field);
}
+
+ int suffix = bytes.length - prefix;
output.writeVInt(suffix);
output.writeBytes(bytes.bytes, bytes.offset + prefix, suffix);
lastTermBytes.copyBytes(bytes);
@@ -102,20 +108,6 @@ public class PrefixCodedTerms implements Accountable {
throw new RuntimeException(e);
}
}
-
- private int sharedPrefix(BytesRef term1, BytesRef term2) {
- int pos1 = 0;
- int pos1End = pos1 + Math.min(term1.length, term2.length);
- int pos2 = 0;
- while(pos1 < pos1End) {
- if (term1.bytes[term1.offset + pos1] != term2.bytes[term2.offset + pos2]) {
- return pos1;
- }
- pos1++;
- pos2++;
- }
- return pos1;
- }
}
/** An iterator over the list of terms stored in a {@link PrefixCodedTerms}. */
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
----------------------------------------------------------------------
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 59b6be5..0e075b4 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Collection;
import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.FutureObjects;
import org.apache.lucene.util.PriorityQueue;
/**
@@ -105,9 +106,7 @@ final class BooleanScorer extends BulkScorer {
}
public BulkScorerAndDoc get(int i) {
- if (i < 0 || i >= size()) {
- throw new IndexOutOfBoundsException();
- }
+ FutureObjects.checkIndex(i, size());
return (BulkScorerAndDoc) getHeapArray()[1 + i];
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java b/lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java
index 3bc65ef..3c5897f 100644
--- a/lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java
+++ b/lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java
@@ -313,58 +313,6 @@ public final class ArrayUtil {
code = code * 31 + array[i];
return code;
}
-
- // Since Arrays.equals doesn't implement offsets for equals
- /**
- * See if two array slices are the same.
- *
- * @param left The left array to compare
- * @param offsetLeft The offset into the array. Must be positive
- * @param right The right array to compare
- * @param offsetRight the offset into the right array. Must be positive
- * @param length The length of the section of the array to compare
- * @return true if the two arrays, starting at their respective offsets, are equal
- *
- * @see java.util.Arrays#equals(byte[], byte[])
- */
- public static boolean equals(byte[] left, int offsetLeft, byte[] right, int offsetRight, int length) {
- if ((offsetLeft + length <= left.length) && (offsetRight + length <= right.length)) {
- for (int i = 0; i < length; i++) {
- if (left[offsetLeft + i] != right[offsetRight + i]) {
- return false;
- }
-
- }
- return true;
- }
- return false;
- }
-
- // Since Arrays.equals doesn't implement offsets for equals
- /**
- * See if two array slices are the same.
- *
- * @param left The left array to compare
- * @param offsetLeft The offset into the array. Must be positive
- * @param right The right array to compare
- * @param offsetRight the offset into the right array. Must be positive
- * @param length The length of the section of the array to compare
- * @return true if the two arrays, starting at their respective offsets, are equal
- *
- * @see java.util.Arrays#equals(char[], char[])
- */
- public static boolean equals(int[] left, int offsetLeft, int[] right, int offsetRight, int length) {
- if ((offsetLeft + length <= left.length) && (offsetRight + length <= right.length)) {
- for (int i = 0; i < length; i++) {
- if (left[offsetLeft + i] != right[offsetRight + i]) {
- return false;
- }
-
- }
- return true;
- }
- return false;
- }
/** Swap values stored in slots <code>i</code> and <code>j</code> */
public static <T> void swap(T[] arr, int i, int j) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
----------------------------------------------------------------------
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 2fcf28a..42c4e87 100644
--- a/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
@@ -96,20 +96,8 @@ public final class BytesRef implements Comparable<BytesRef>,Cloneable {
* @lucene.internal
*/
public boolean bytesEquals(BytesRef other) {
- assert other != null;
- if (length == other.length) {
- int otherUpto = other.offset;
- final byte[] otherBytes = other.bytes;
- final int end = offset + length;
- for(int upto=offset;upto<end;upto++,otherUpto++) {
- if (bytes[upto] != otherBytes[otherUpto]) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
+ return FutureArrays.equals(this.bytes, this.offset, this.offset + this.length,
+ other.bytes, other.offset, other.offset + other.length);
}
/**
@@ -172,27 +160,8 @@ public final class BytesRef implements Comparable<BytesRef>,Cloneable {
/** Unsigned byte order comparison */
@Override
public int compareTo(BytesRef other) {
- // TODO: Once we are on Java 9 replace this by java.util.Arrays#compareUnsigned()
- // which is implemented by a Hotspot intrinsic! Also consider building a
- // Multi-Release-JAR!
- final byte[] aBytes = this.bytes;
- int aUpto = this.offset;
- final byte[] bBytes = other.bytes;
- int bUpto = other.offset;
-
- final int aStop = aUpto + Math.min(this.length, other.length);
- while(aUpto < aStop) {
- int aByte = aBytes[aUpto++] & 0xff;
- int bByte = bBytes[bUpto++] & 0xff;
-
- int diff = aByte - bByte;
- if (diff != 0) {
- return diff;
- }
- }
-
- // One is a prefix of the other, or, they are equal:
- return this.length - other.length;
+ return FutureArrays.compareUnsigned(this.bytes, this.offset, this.offset + this.length,
+ other.bytes, other.offset, other.offset + other.length);
}
/**
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java b/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
index bab3d04..00222f4 100644
--- a/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
+++ b/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
@@ -93,34 +93,28 @@ public final class BytesRefArray implements SortableBytesRefArray {
* @return the <i>n'th</i> element of this {@link BytesRefArray}
*/
public BytesRef get(BytesRefBuilder spare, int index) {
- if (lastElement > index) {
- int offset = offsets[index];
- int length = index == lastElement - 1 ? currentOffset - offset
- : offsets[index + 1] - offset;
- spare.grow(length);
- spare.setLength(length);
- pool.readBytes(offset, spare.bytes(), 0, spare.length());
- return spare.get();
- }
- throw new IndexOutOfBoundsException("index " + index
- + " must be less than the size: " + lastElement);
+ FutureObjects.checkIndex(index, lastElement);
+ int offset = offsets[index];
+ int length = index == lastElement - 1 ? currentOffset - offset
+ : offsets[index + 1] - offset;
+ spare.grow(length);
+ spare.setLength(length);
+ pool.readBytes(offset, spare.bytes(), 0, spare.length());
+ return spare.get();
}
/** Used only by sort below, to set a {@link BytesRef} with the specified slice, avoiding copying bytes in the common case when the slice
* is contained in a single block in the byte block pool. */
private void setBytesRef(BytesRefBuilder spare, BytesRef result, int index) {
- if (index < lastElement) {
- int offset = offsets[index];
- int length;
- if (index == lastElement - 1) {
- length = currentOffset - offset;
- } else {
- length = offsets[index + 1] - offset;
- }
- pool.setBytesRef(spare, result, offset, length);
+ FutureObjects.checkIndex(index, lastElement);
+ int offset = offsets[index];
+ int length;
+ if (index == lastElement - 1) {
+ length = currentOffset - offset;
} else {
- throw new IndexOutOfBoundsException("index " + index + " must be less than the size: " + lastElement);
+ length = offsets[index + 1] - offset;
}
+ pool.setBytesRef(spare, result, offset, length);
}
private int[] sort(final Comparator<BytesRef> comp) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/CharsRef.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/CharsRef.java b/lucene/core/src/java/org/apache/lucene/util/CharsRef.java
index aacdfcc..eb839a8 100644
--- a/lucene/core/src/java/org/apache/lucene/util/CharsRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/CharsRef.java
@@ -107,46 +107,15 @@ public final class CharsRef implements Comparable<CharsRef>, CharSequence, Clone
}
public boolean charsEquals(CharsRef other) {
- if (length == other.length) {
- int otherUpto = other.offset;
- final char[] otherChars = other.chars;
- final int end = offset + length;
- for (int upto = offset; upto < end; upto++, otherUpto++) {
- if (chars[upto] != otherChars[otherUpto]) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
+ return FutureArrays.equals(this.chars, this.offset, this.offset + this.length,
+ other.chars, other.offset, other.offset + other.length);
}
/** Signed int order comparison */
@Override
public int compareTo(CharsRef other) {
- if (this == other)
- return 0;
-
- final char[] aChars = this.chars;
- int aUpto = this.offset;
- final char[] bChars = other.chars;
- int bUpto = other.offset;
-
- final int aStop = aUpto + Math.min(this.length, other.length);
-
- while (aUpto < aStop) {
- int aInt = aChars[aUpto++];
- int bInt = bChars[bUpto++];
- if (aInt > bInt) {
- return 1;
- } else if (aInt < bInt) {
- return -1;
- }
- }
-
- // One is a prefix of the other, or, they are equal:
- return this.length - other.length;
+ return FutureArrays.compare(this.chars, this.offset, this.offset + this.length,
+ other.chars, other.offset, other.offset + other.length);
}
@Override
@@ -162,18 +131,14 @@ public final class CharsRef implements Comparable<CharsRef>, CharSequence, Clone
@Override
public char charAt(int index) {
// NOTE: must do a real check here to meet the specs of CharSequence
- if (index < 0 || index >= length) {
- throw new IndexOutOfBoundsException();
- }
+ FutureObjects.checkIndex(index, length);
return chars[offset + index];
}
@Override
public CharSequence subSequence(int start, int end) {
// NOTE: must do a real check here to meet the specs of CharSequence
- if (start < 0 || end > length || start > end) {
- throw new IndexOutOfBoundsException();
- }
+ FutureObjects.checkFromToIndex(start, end, length);
return new CharsRef(chars, offset + start, end - start);
}
@@ -195,40 +160,33 @@ public final class CharsRef implements Comparable<CharsRef>, CharSequence, Clone
@Override
public int compare(CharsRef a, CharsRef b) {
- if (a == b)
- return 0;
-
- final char[] aChars = a.chars;
- int aUpto = a.offset;
- final char[] bChars = b.chars;
- int bUpto = b.offset;
-
- final int aStop = aUpto + Math.min(a.length, b.length);
-
- while (aUpto < aStop) {
- char aChar = aChars[aUpto++];
- char bChar = bChars[bUpto++];
- if (aChar != bChar) {
- // http://icu-project.org/docs/papers/utf16_code_point_order.html
-
- /* aChar != bChar, fix up each one if they're both in or above the surrogate range, then compare them */
- if (aChar >= 0xd800 && bChar >= 0xd800) {
- if (aChar >= 0xe000) {
- aChar -= 0x800;
- } else {
- aChar += 0x2000;
- }
-
- if (bChar >= 0xe000) {
- bChar -= 0x800;
- } else {
- bChar += 0x2000;
- }
+ int aEnd = a.offset + a.length;
+ int bEnd = b.offset + b.length;
+ int i = FutureArrays.mismatch(a.chars, a.offset, aEnd,
+ b.chars, b.offset, bEnd);
+
+ if (i >= 0 && i < Math.min(a.length, b.length)) {
+ // http://icu-project.org/docs/papers/utf16_code_point_order.html
+
+ char aChar = a.chars[a.offset + i];
+ char bChar = b.chars[b.offset + i];
+ /* aChar != bChar, fix up each one if they're both in or above the surrogate range, then compare them */
+ if (aChar >= 0xd800 && bChar >= 0xd800) {
+ if (aChar >= 0xe000) {
+ aChar -= 0x800;
+ } else {
+ aChar += 0x2000;
}
- /* now aChar and bChar are in code point order */
- return (int)aChar - (int)bChar; /* int must be 32 bits wide */
+ if (bChar >= 0xe000) {
+ bChar -= 0x800;
+ } else {
+ bChar += 0x2000;
+ }
}
+
+ /* now aChar and bChar are in code point order */
+ return (int)aChar - (int)bChar; /* int must be 32 bits wide */
}
// One is a prefix of the other, or, they are equal:
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/FutureArrays.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/FutureArrays.java b/lucene/core/src/java/org/apache/lucene/util/FutureArrays.java
new file mode 100644
index 0000000..0154053
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/util/FutureArrays.java
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.util;
+
+/**
+ * Additional methods from Java 9's <a href="https://docs.oracle.com/javase/9/docs/api/java/util/Arrays.html">
+ * {@code java.util.Arrays}</a>.
+ * <p>
+ * This class will be removed when Java 9 is minimum requirement.
+ * Currently any bytecode is patched to use the Java 9 native
+ * classes through MR-JAR (Multi-Release JAR) mechanism.
+ * In Java 8 it will use THIS implementation.
+ * Because of patching, inside the Java source files we always
+ * refer to the Lucene implementations, but the final Lucene
+ * JAR files will use the native Java 9 class names when executed
+ * with Java 9.
+ * @lucene.internal
+ */
+public final class FutureArrays {
+
+ private FutureArrays() {} // no instance
+
+ // methods in Arrays are defined stupid: they cannot use Objects.checkFromToIndex
+ // they throw IAE (vs IOOBE) in the case of fromIndex > toIndex.
+ // so this method works just like checkFromToIndex, but with that stupidity added.
+ private static void checkFromToIndex(int fromIndex, int toIndex, int length) {
+ if (fromIndex > toIndex) {
+ throw new IllegalArgumentException("fromIndex " + fromIndex + " > toIndex " + toIndex);
+ }
+ if (fromIndex < 0 || toIndex > length) {
+ throw new IndexOutOfBoundsException("Range [" + fromIndex + ", " + toIndex + ") out-of-bounds for length " + length);
+ }
+ }
+
+ // byte[]
+
+ /**
+ * Behaves like Java 9's Arrays.mismatch
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#mismatch-byte:A-int-int-byte:A-int-int-">Arrays.mismatch</a>
+ */
+ public static int mismatch(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ int len = Math.min(aLen, bLen);
+ for (int i = 0; i < len; i++)
+ if (a[i+aFromIndex] != b[i+bFromIndex])
+ return i;
+ return aLen == bLen ? -1 : len;
+ }
+
+ /**
+ * Behaves like Java 9's Arrays.compareUnsigned
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compareUnsigned-byte:A-int-int-byte:A-int-int-">Arrays.compareUnsigned</a>
+ */
+ public static int compareUnsigned(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ int len = Math.min(aLen, bLen);
+ for (int i = 0; i < len; i++) {
+ int aByte = a[i+aFromIndex] & 0xFF;
+ int bByte = b[i+bFromIndex] & 0xFF;
+ int diff = aByte - bByte;
+ if (diff != 0) {
+ return diff;
+ }
+ }
+
+ // One is a prefix of the other, or, they are equal:
+ return aLen - bLen;
+ }
+
+ /**
+ * Behaves like Java 9's Arrays.equals
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-byte:A-int-int-byte:A-int-int-">Arrays.equals</a>
+ */
+ public static boolean equals(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ // lengths differ: cannot be equal
+ if (aLen != bLen) {
+ return false;
+ }
+ for (int i = 0; i < aLen; i++) {
+ if (a[i+aFromIndex] != b[i+bFromIndex]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // char[]
+
+ /**
+ * Behaves like Java 9's Arrays.mismatch
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#mismatch-char:A-int-int-char:A-int-int-">Arrays.mismatch</a>
+ */
+ public static int mismatch(char[] a, int aFromIndex, int aToIndex, char[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ int len = Math.min(aLen, bLen);
+ for (int i = 0; i < len; i++)
+ if (a[i+aFromIndex] != b[i+bFromIndex])
+ return i;
+ return aLen == bLen ? -1 : len;
+ }
+
+ /**
+ * Behaves like Java 9's Arrays.compare
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compare-char:A-int-int-char:A-int-int-">Arrays.compare</a>
+ */
+ public static int compare(char[] a, int aFromIndex, int aToIndex, char[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ int len = Math.min(aLen, bLen);
+ for (int i = 0; i < len; i++) {
+ int aInt = a[i+aFromIndex];
+ int bInt = b[i+bFromIndex];
+ if (aInt > bInt) {
+ return 1;
+ } else if (aInt < bInt) {
+ return -1;
+ }
+ }
+
+ // One is a prefix of the other, or, they are equal:
+ return aLen - bLen;
+ }
+
+ /**
+ * Behaves like Java 9's Arrays.equals
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-char:A-int-int-char:A-int-int-">Arrays.equals</a>
+ */
+ public static boolean equals(char[] a, int aFromIndex, int aToIndex, char[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ // lengths differ: cannot be equal
+ if (aLen != bLen) {
+ return false;
+ }
+ for (int i = 0; i < aLen; i++) {
+ if (a[i+aFromIndex] != b[i+bFromIndex]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // int[]
+
+ /**
+ * Behaves like Java 9's Arrays.compare
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compare-int:A-int-int-int:A-int-int-">Arrays.compare</a>
+ */
+ public static int compare(int[] a, int aFromIndex, int aToIndex, int[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ int len = Math.min(aLen, bLen);
+ for (int i = 0; i < len; i++) {
+ int aInt = a[i+aFromIndex];
+ int bInt = b[i+bFromIndex];
+ if (aInt > bInt) {
+ return 1;
+ } else if (aInt < bInt) {
+ return -1;
+ }
+ }
+
+ // One is a prefix of the other, or, they are equal:
+ return aLen - bLen;
+ }
+
+ /**
+ * Behaves like Java 9's Arrays.equals
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-int:A-int-int-int:A-int-int-">Arrays.equals</a>
+ */
+ public static boolean equals(int[] a, int aFromIndex, int aToIndex, int[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ // lengths differ: cannot be equal
+ if (aLen != bLen) {
+ return false;
+ }
+ for (int i = 0; i < aLen; i++) {
+ if (a[i+aFromIndex] != b[i+bFromIndex]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // long[]
+
+ /**
+ * Behaves like Java 9's Arrays.compare
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compare-long:A-int-int-long:A-int-int-">Arrays.compare</a>
+ */
+ public static int compare(long[] a, int aFromIndex, int aToIndex, long[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ int len = Math.min(aLen, bLen);
+ for (int i = 0; i < len; i++) {
+ long aInt = a[i+aFromIndex];
+ long bInt = b[i+bFromIndex];
+ if (aInt > bInt) {
+ return 1;
+ } else if (aInt < bInt) {
+ return -1;
+ }
+ }
+
+ // One is a prefix of the other, or, they are equal:
+ return aLen - bLen;
+ }
+
+ /**
+ * Behaves like Java 9's Arrays.equals
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-long:A-int-int-long:A-int-int-">Arrays.equals</a>
+ */
+ public static boolean equals(long[] a, int aFromIndex, int aToIndex, long[] b, int bFromIndex, int bToIndex) {
+ checkFromToIndex(aFromIndex, aToIndex, a.length);
+ checkFromToIndex(bFromIndex, bToIndex, b.length);
+ int aLen = aToIndex - aFromIndex;
+ int bLen = bToIndex - bFromIndex;
+ // lengths differ: cannot be equal
+ if (aLen != bLen) {
+ return false;
+ }
+ for (int i = 0; i < aLen; i++) {
+ if (a[i+aFromIndex] != b[i+bFromIndex]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/FutureObjects.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/FutureObjects.java b/lucene/core/src/java/org/apache/lucene/util/FutureObjects.java
new file mode 100644
index 0000000..b8ad4d3
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/util/FutureObjects.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.util;
+
+/**
+ * Additional methods from Java 9's <a href="https://docs.oracle.com/javase/9/docs/api/java/util/Objects.html">
+ * {@code java.util.Objects}</a>.
+ * <p>
+ * This class will be removed when Java 9 is minimum requirement.
+ * Currently any bytecode is patched to use the Java 9 native
+ * classes through MR-JAR (Multi-Release JAR) mechanism.
+ * In Java 8 it will use THIS implementation.
+ * Because of patching, inside the Java source files we always
+ * refer to the Lucene implementations, but the final Lucene
+ * JAR files will use the native Java 9 class names when executed
+ * with Java 9.
+ * @lucene.internal
+ */
+public final class FutureObjects {
+
+ private FutureObjects() {} // no instance
+
+ /**
+ * Behaves like Java 9's Objects.checkIndex
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Objects.html#checkIndex-int-int-">Objects.checkIndex</a>
+ */
+ public static int checkIndex(int index, int length) {
+ if (index < 0 || index >= length) {
+ throw new IndexOutOfBoundsException("Index " + index + " out-of-bounds for length " + length);
+ }
+ return index;
+ }
+
+ /**
+ * Behaves like Java 9's Objects.checkFromToIndex
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Objects.html#checkFromToIndex-int-int-int-">Objects.checkFromToIndex</a>
+ */
+ public static int checkFromToIndex(int fromIndex, int toIndex, int length) {
+ if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) {
+ throw new IndexOutOfBoundsException("Range [" + fromIndex + ", " + toIndex + ") out-of-bounds for length " + length);
+ }
+ return fromIndex;
+ }
+
+ /**
+ * Behaves like Java 9's Objects.checkFromIndexSize
+ * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Objects.html#checkFromIndexSize-int-int-int-">Objects.checkFromIndexSize</a>
+ */
+ public static int checkFromIndexSize(int fromIndex, int size, int length) {
+ int end = fromIndex + size;
+ if (fromIndex < 0 || fromIndex > end || end > length) {
+ throw new IndexOutOfBoundsException("Range [" + fromIndex + ", " + fromIndex + " + " + size + ") out-of-bounds for length " + length);
+ }
+ return fromIndex;
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/IntsRef.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/IntsRef.java b/lucene/core/src/java/org/apache/lucene/util/IntsRef.java
index 981210d..aa7bbce 100644
--- a/lucene/core/src/java/org/apache/lucene/util/IntsRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/IntsRef.java
@@ -93,45 +93,15 @@ public final class IntsRef implements Comparable<IntsRef>, Cloneable {
}
public boolean intsEquals(IntsRef other) {
- if (length == other.length) {
- int otherUpto = other.offset;
- final int[] otherInts = other.ints;
- final int end = offset + length;
- for(int upto=offset;upto<end;upto++,otherUpto++) {
- if (ints[upto] != otherInts[otherUpto]) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
+ return FutureArrays.equals(this.ints, this.offset, this.offset + this.length,
+ other.ints, other.offset, other.offset + other.length);
}
/** Signed int order comparison */
@Override
public int compareTo(IntsRef other) {
- if (this == other) return 0;
-
- final int[] aInts = this.ints;
- int aUpto = this.offset;
- final int[] bInts = other.ints;
- int bUpto = other.offset;
-
- final int aStop = aUpto + Math.min(this.length, other.length);
-
- while(aUpto < aStop) {
- int aInt = aInts[aUpto++];
- int bInt = bInts[bUpto++];
- if (aInt > bInt) {
- return 1;
- } else if (aInt < bInt) {
- return -1;
- }
- }
-
- // One is a prefix of the other, or, they are equal:
- return this.length - other.length;
+ return FutureArrays.compare(this.ints, this.offset, this.offset + this.length,
+ other.ints, other.offset, other.offset + other.length);
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/LongsRef.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/LongsRef.java b/lucene/core/src/java/org/apache/lucene/util/LongsRef.java
index 61b85cf..952d189 100644
--- a/lucene/core/src/java/org/apache/lucene/util/LongsRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/LongsRef.java
@@ -92,45 +92,15 @@ public final class LongsRef implements Comparable<LongsRef>, Cloneable {
}
public boolean longsEquals(LongsRef other) {
- if (length == other.length) {
- int otherUpto = other.offset;
- final long[] otherInts = other.longs;
- final long end = offset + length;
- for(int upto=offset; upto<end; upto++,otherUpto++) {
- if (longs[upto] != otherInts[otherUpto]) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
+ return FutureArrays.equals(this.longs, this.offset, this.offset + this.length,
+ other.longs, other.offset, other.offset + other.length);
}
/** Signed int order comparison */
@Override
public int compareTo(LongsRef other) {
- if (this == other) return 0;
-
- final long[] aInts = this.longs;
- int aUpto = this.offset;
- final long[] bInts = other.longs;
- int bUpto = other.offset;
-
- final long aStop = aUpto + Math.min(this.length, other.length);
-
- while(aUpto < aStop) {
- long aInt = aInts[aUpto++];
- long bInt = bInts[bUpto++];
- if (aInt > bInt) {
- return 1;
- } else if (aInt < bInt) {
- return -1;
- }
- }
-
- // One is a prefix of the other, or, they are equal:
- return this.length - other.length;
+ return FutureArrays.compare(this.longs, this.offset, this.offset + this.length,
+ other.longs, other.offset, other.offset + other.length);
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/StringHelper.java b/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
index 6d958ba..4c6d4fa 100644
--- a/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
+++ b/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
@@ -34,21 +34,19 @@ public abstract class StringHelper {
/**
* Compares two {@link BytesRef}, element by element, and returns the
* number of elements common to both arrays (from the start of each).
+ * This method assumes currentTerm comes after priorTerm.
*
- * @param left The first {@link BytesRef} to compare
- * @param right The second {@link BytesRef} to compare
+ * @param priorTerm The first {@link BytesRef} to compare
+ * @param currentTerm The second {@link BytesRef} to compare
* @return The number of common elements (from the start of each).
*/
- public static int bytesDifference(BytesRef left, BytesRef right) {
- int len = left.length < right.length ? left.length : right.length;
- final byte[] bytesLeft = left.bytes;
- final int offLeft = left.offset;
- byte[] bytesRight = right.bytes;
- final int offRight = right.offset;
- for (int i = 0; i < len; i++)
- if (bytesLeft[i+offLeft] != bytesRight[i+offRight])
- return i;
- return len;
+ public static int bytesDifference(BytesRef priorTerm, BytesRef currentTerm) {
+ int mismatch = FutureArrays.mismatch(priorTerm.bytes, priorTerm.offset, priorTerm.offset + priorTerm.length,
+ currentTerm.bytes, currentTerm.offset, currentTerm.offset + currentTerm.length);
+ if (mismatch < 0) {
+ throw new IllegalArgumentException("terms out of order: priorTerm=" + priorTerm + ",currentTerm=" + currentTerm);
+ }
+ return mismatch;
}
/**
@@ -57,15 +55,7 @@ public abstract class StringHelper {
* This method assumes currentTerm comes after priorTerm.
*/
public static int sortKeyLength(final BytesRef priorTerm, final BytesRef currentTerm) {
- final int currentTermOffset = currentTerm.offset;
- final int priorTermOffset = priorTerm.offset;
- final int limit = Math.min(priorTerm.length, currentTerm.length);
- for (int i = 0; i < limit; i++) {
- if (priorTerm.bytes[priorTermOffset+i] != currentTerm.bytes[currentTermOffset+i]) {
- return i+1;
- }
- }
- return Math.min(1+priorTerm.length, currentTerm.length);
+ return bytesDifference(priorTerm, currentTerm) + 1;
}
private StringHelper() {
@@ -83,17 +73,12 @@ public abstract class StringHelper {
* Otherwise <code>false</code>.
*/
public static boolean startsWith(byte[] ref, BytesRef prefix) {
+ // not long enough to start with the prefix
if (ref.length < prefix.length) {
return false;
}
-
- for(int i=0;i<prefix.length;i++) {
- if (ref[i] != prefix.bytes[prefix.offset+i]) {
- return false;
- }
- }
-
- return true;
+ return FutureArrays.equals(ref, 0, prefix.length,
+ prefix.bytes, prefix.offset, prefix.offset + prefix.length);
}
/**
@@ -108,7 +93,12 @@ public abstract class StringHelper {
* Otherwise <code>false</code>.
*/
public static boolean startsWith(BytesRef ref, BytesRef prefix) {
- return sliceEquals(ref, prefix, 0);
+ // not long enough to start with the prefix
+ if (ref.length < prefix.length) {
+ return false;
+ }
+ return FutureArrays.equals(ref.bytes, ref.offset, ref.offset + prefix.length,
+ prefix.bytes, prefix.offset, prefix.offset + prefix.length);
}
/**
@@ -123,24 +113,13 @@ public abstract class StringHelper {
* Otherwise <code>false</code>.
*/
public static boolean endsWith(BytesRef ref, BytesRef suffix) {
- return sliceEquals(ref, suffix, ref.length - suffix.length);
- }
-
- private static boolean sliceEquals(BytesRef sliceToTest, BytesRef other, int pos) {
- if (pos < 0 || sliceToTest.length - pos < other.length) {
+ int startAt = ref.length - suffix.length;
+ // not long enough to start with the suffix
+ if (startAt < 0) {
return false;
}
- int i = sliceToTest.offset + pos;
- int j = other.offset;
- final int k = other.offset + other.length;
-
- while (j < k) {
- if (sliceToTest.bytes[i++] != other.bytes[j++]) {
- return false;
- }
- }
-
- return true;
+ return FutureArrays.equals(ref.bytes, ref.offset + startAt, ref.offset + startAt + suffix.length,
+ suffix.bytes, suffix.offset, suffix.offset + suffix.length);
}
/** Pass this as the seed to {@link #murmurhash3_x86_32}. */
@@ -375,16 +354,12 @@ public abstract class StringHelper {
/** Compares a fixed length slice of two byte arrays interpreted as
* big-endian unsigned values. Returns positive int if a > b,
- * negative int if a < b and 0 if a == b */
+ * negative int if a < b and 0 if a == b
+ *
+ * @deprecated Use FutureArrays.compareUnsigned instead.
+ */
+ @Deprecated
public static int compare(int count, byte[] a, int aOffset, byte[] b, int bOffset) {
- // TODO: dedup this w/ BytesRef.compareTo?
- for(int i=0;i<count;i++) {
- int cmp = (a[aOffset+i]&0xff) - (b[bOffset+i]&0xff);
- if (cmp != 0) {
- return cmp;
- }
- }
-
- return 0;
+ return FutureArrays.compareUnsigned(a, aOffset, aOffset + count, b, bOffset, bOffset + count);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java
----------------------------------------------------------------------
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 e4a5bd9..9ef31e8 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
@@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.FutureObjects;
import org.apache.lucene.util.InPlaceMergeSorter;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.lucene.util.Sorter;
@@ -114,14 +115,8 @@ public class Automaton implements Accountable {
/** Set or clear this state as an accept state. */
public void setAccept(int state, boolean accept) {
- if (state >= getNumStates()) {
- throw new IllegalArgumentException("state=" + state + " is out of bounds (numStates=" + getNumStates() + ")");
- }
- if (accept) {
- isAccept.set(state);
- } else {
- isAccept.clear(state);
- }
+ FutureObjects.checkIndex(state, getNumStates());
+ isAccept.set(state, accept);
}
/** Sugar to get all transitions for all states. This is
@@ -161,12 +156,9 @@ public class Automaton implements Accountable {
public void addTransition(int source, int dest, int min, int max) {
assert nextTransition%3 == 0;
- if (source >= nextState/2) {
- throw new IllegalArgumentException("source=" + source + " is out of bounds (maxState is " + (nextState/2-1) + ")");
- }
- if (dest >= nextState/2) {
- throw new IllegalArgumentException("dest=" + dest + " is out of bounds (max state is " + (nextState/2-1) + ")");
- }
+ int bounds = nextState/2;
+ FutureObjects.checkIndex(source, bounds);
+ FutureObjects.checkIndex(dest, bounds);
growTransitions();
if (curState != source) {
@@ -842,10 +834,7 @@ public class Automaton implements Accountable {
/** Set or clear this state as an accept state. */
public void setAccept(int state, boolean accept) {
- if (state >= getNumStates()) {
- throw new IllegalArgumentException("state=" + state + " is out of bounds (numStates=" + getNumStates() + ")");
- }
-
+ FutureObjects.checkIndex(state, getNumStates());
this.isAccept.set(state, accept);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java b/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java
index 3082129..9bf3621 100644
--- a/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java
+++ b/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java
@@ -46,10 +46,9 @@ public class TestCharTermAttributeImpl extends LuceneTestCase {
CharTermAttributeImpl t = new CharTermAttributeImpl();
char[] content = "hello".toCharArray();
t.copyBuffer(content, 0, content.length);
- IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
+ expectThrows(IndexOutOfBoundsException.class, () -> {
t.setLength(-1);
});
- assertTrue(expected.getMessage().contains("must not be negative"));
}
public void testGrow() {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/05a105a9/lucene/core/src/test/org/apache/lucene/util/TestArrayUtil.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/util/TestArrayUtil.java b/lucene/core/src/test/org/apache/lucene/util/TestArrayUtil.java
index 79f4cbd..0cda337 100644
--- a/lucene/core/src/test/org/apache/lucene/util/TestArrayUtil.java
+++ b/lucene/core/src/test/org/apache/lucene/util/TestArrayUtil.java
@@ -16,8 +16,6 @@
*/
package org.apache.lucene.util;
-
-import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
@@ -107,20 +105,6 @@ public class TestArrayUtil extends LuceneTestCase {
test = ArrayUtil.parseInt("foo 1923 bar".toCharArray(), 4, 4);
assertTrue(test + " does not equal: " + 1923, test == 1923);
}
-
- public void testSliceEquals() {
- String left = "this is equal";
- String right = left;
- byte[] leftChars = left.getBytes(StandardCharsets.UTF_8);
- byte[] rightChars = right.getBytes(StandardCharsets.UTF_8);
- assertTrue(left + " does not equal: " + right, ArrayUtil.equals(leftChars, 0, rightChars, 0, left.length()));
-
- assertFalse(left + " does not equal: " + right, ArrayUtil.equals(leftChars, 1, rightChars, 0, left.length()));
- assertFalse(left + " does not equal: " + right, ArrayUtil.equals(leftChars, 1, rightChars, 2, left.length()));
-
- assertFalse(left + " does not equal: " + right, ArrayUtil.equals(leftChars, 25, rightChars, 0, left.length()));
- assertFalse(left + " does not equal: " + right, ArrayUtil.equals(leftChars, 12, rightChars, 0, left.length()));
- }
private Integer[] createRandomArray(int maxSize) {
final Random rnd = random();