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 70feff19cd3..f379a02e0dc 100644 --- a/lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java +++ b/lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java @@ -17,7 +17,6 @@ package org.apache.lucene.util; import java.util.Arrays; -import java.util.Collection; import java.util.Comparator; /** @@ -40,19 +39,6 @@ public final class ArrayUtil { */ - /** - * Parses the string argument as if it was an int value and returns the - * result. Throws NumberFormatException if the string does not represent an - * int quantity. - * - * @param chars a string representation of an int quantity. - * @return int the value represented by the argument - * @throws NumberFormatException if the argument could not be parsed as an int quantity. - */ - public static int parseInt(char[] chars) throws NumberFormatException { - return parseInt(chars, 0, chars.length, 10); - } - /** * Parses a char array into an int. * @param chars the character array @@ -225,17 +211,6 @@ public final class ArrayUtil { } } - public static int getShrinkSize(int currentSize, int targetSize, int bytesPerElement) { - final int newSize = oversize(targetSize, bytesPerElement); - // Only reallocate if we are "substantially" smaller. - // This saves us from "running hot" (constantly making a - // bit bigger then a bit smaller, over and over): - if (newSize < currentSize / 2) - return newSize; - else - return currentSize; - } - public static T[] grow(T[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { @@ -247,9 +222,7 @@ public final class ArrayUtil { public static short[] grow(short[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { - short[] newArray = new short[oversize(minSize, Short.BYTES)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; + return Arrays.copyOf(array, oversize(minSize, Short.BYTES)); } else return array; } @@ -261,9 +234,7 @@ public final class ArrayUtil { public static float[] grow(float[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { - float[] newArray = new float[oversize(minSize, Float.BYTES)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; + return Arrays.copyOf(array, oversize(minSize, Float.BYTES)); } else return array; } @@ -275,9 +246,7 @@ public final class ArrayUtil { public static double[] grow(double[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { - double[] newArray = new double[oversize(minSize, Double.BYTES)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; + return Arrays.copyOf(array, oversize(minSize, Double.BYTES)); } else return array; } @@ -286,23 +255,10 @@ public final class ArrayUtil { return grow(array, 1 + array.length); } - public static short[] shrink(short[] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, Short.BYTES); - if (newSize != array.length) { - short[] newArray = new short[newSize]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else - return array; - } - public static int[] grow(int[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { - int[] newArray = new int[oversize(minSize, Integer.BYTES)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; + return Arrays.copyOf(array, oversize(minSize, Integer.BYTES)); } else return array; } @@ -311,23 +267,10 @@ public final class ArrayUtil { return grow(array, 1 + array.length); } - public static int[] shrink(int[] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, Integer.BYTES); - if (newSize != array.length) { - int[] newArray = new int[newSize]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else - return array; - } - public static long[] grow(long[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { - long[] newArray = new long[oversize(minSize, Long.BYTES)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; + return Arrays.copyOf(array, oversize(minSize, Long.BYTES)); } else return array; } @@ -336,23 +279,10 @@ public final class ArrayUtil { return grow(array, 1 + array.length); } - public static long[] shrink(long[] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, Long.BYTES); - if (newSize != array.length) { - long[] newArray = new long[newSize]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else - return array; - } - public static byte[] grow(byte[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { - byte[] newArray = new byte[oversize(minSize, 1)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; + return Arrays.copyOf(array, oversize(minSize, Byte.BYTES)); } else return array; } @@ -361,48 +291,10 @@ public final class ArrayUtil { return grow(array, 1 + array.length); } - public static byte[] shrink(byte[] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, 1); - if (newSize != array.length) { - byte[] newArray = new byte[newSize]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else - return array; - } - - public static boolean[] grow(boolean[] array, int minSize) { - assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; - if (array.length < minSize) { - boolean[] newArray = new boolean[oversize(minSize, 1)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; - } else - return array; - } - - public static boolean[] grow(boolean[] array) { - return grow(array, 1 + array.length); - } - - public static boolean[] shrink(boolean[] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, 1); - if (newSize != array.length) { - boolean[] newArray = new boolean[newSize]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else - return array; - } - public static char[] grow(char[] array, int minSize) { assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; if (array.length < minSize) { - char[] newArray = new char[oversize(minSize, Character.BYTES)]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; + return Arrays.copyOf(array, oversize(minSize, Character.BYTES)); } else return array; } @@ -411,71 +303,6 @@ public final class ArrayUtil { return grow(array, 1 + array.length); } - public static char[] shrink(char[] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, Character.BYTES); - if (newSize != array.length) { - char[] newArray = new char[newSize]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else - return array; - } - - public static int[][] grow(int[][] array, int minSize) { - assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; - if (array.length < minSize) { - int[][] newArray = new int[oversize(minSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF)][]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; - } else { - return array; - } - } - - public static int[][] grow(int[][] array) { - return grow(array, 1 + array.length); - } - - public static int[][] shrink(int[][] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF); - if (newSize != array.length) { - int[][] newArray = new int[newSize][]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else { - return array; - } - } - - public static float[][] grow(float[][] array, int minSize) { - assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; - if (array.length < minSize) { - float[][] newArray = new float[oversize(minSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF)][]; - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; - } else { - return array; - } - } - - public static float[][] grow(float[][] array) { - return grow(array, 1 + array.length); - } - - public static float[][] shrink(float[][] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF); - if (newSize != array.length) { - float[][] newArray = new float[newSize][]; - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else { - return array; - } - } - /** * Returns hash of chars in range start (inclusive) to * end (inclusive) @@ -486,44 +313,6 @@ public final class ArrayUtil { code = code * 31 + array[i]; return code; } - - /** - * Returns hash of bytes in range start (inclusive) to - * end (inclusive) - */ - public static int hashCode(byte[] array, int start, int end) { - int code = 0; - for (int i = end - 1; i >= start; i--) - 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(char[], char[]) - */ - public static boolean equals(char[] left, int offsetLeft, char[] 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 /** @@ -551,35 +340,6 @@ public final class ArrayUtil { return false; } - /* DISABLE THIS FOR NOW: This has performance problems until Java creates intrinsics for Class#getComponentType() and Array.newInstance() - public static T[] grow(T[] array, int minSize) { - assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?"; - if (array.length < minSize) { - @SuppressWarnings("unchecked") final T[] newArray = - (T[]) Array.newInstance(array.getClass().getComponentType(), oversize(minSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF)); - System.arraycopy(array, 0, newArray, 0, array.length); - return newArray; - } else - return array; - } - - public static T[] grow(T[] array) { - return grow(array, 1 + array.length); - } - - public static T[] shrink(T[] array, int targetSize) { - assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?"; - final int newSize = getShrinkSize(array.length, targetSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF); - if (newSize != array.length) { - @SuppressWarnings("unchecked") final T[] newArray = - (T[]) Array.newInstance(array.getClass().getComponentType(), newSize); - System.arraycopy(array, 0, newArray, 0, newSize); - return newArray; - } else - return array; - } - */ - // Since Arrays.equals doesn't implement offsets for equals /** * See if two array slices are the same. @@ -606,20 +366,6 @@ public final class ArrayUtil { return false; } - public static int[] toIntArray(Collection ints) { - - final int[] result = new int[ints.size()]; - int upto = 0; - for(int v : ints) { - result[upto++] = v; - } - - // paranoia: - assert upto == result.length; - - return result; - } - /** Swap values stored in slots i and j */ public static void swap(T[] arr, int i, int j) { final T tmp = arr[i]; diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/HeapPointWriter.java b/lucene/core/src/java/org/apache/lucene/util/bkd/HeapPointWriter.java index 470f585f3cb..24d248b930d 100644 --- a/lucene/core/src/java/org/apache/lucene/util/bkd/HeapPointWriter.java +++ b/lucene/core/src/java/org/apache/lucene/util/bkd/HeapPointWriter.java @@ -18,6 +18,7 @@ package org.apache.lucene.util.bkd; import java.io.Closeable; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.lucene.util.ArrayUtil; @@ -105,20 +106,6 @@ final class HeapPointWriter implements PointWriter { System.arraycopy(bytes, 0, blocks.get(block), blockIndex * packedBytesLength, packedBytesLength); } - private int[] growExact(int[] arr, int size) { - assert size > arr.length; - int[] newArr = new int[size]; - System.arraycopy(arr, 0, newArr, 0, arr.length); - return newArr; - } - - private long[] growExact(long[] arr, int size) { - assert size > arr.length; - long[] newArr = new long[size]; - System.arraycopy(arr, 0, newArr, 0, arr.length); - return newArr; - } - @Override public void append(byte[] packedValue, long ord, int docID) { assert closed == false; @@ -126,12 +113,12 @@ final class HeapPointWriter implements PointWriter { if (docIDs.length == nextWrite) { int nextSize = Math.min(maxSize, ArrayUtil.oversize(nextWrite+1, Integer.BYTES)); assert nextSize > nextWrite: "nextSize=" + nextSize + " vs nextWrite=" + nextWrite; - docIDs = growExact(docIDs, nextSize); + docIDs = Arrays.copyOf(docIDs, nextSize); if (singleValuePerDoc == false) { if (ordsLong != null) { - ordsLong = growExact(ordsLong, nextSize); + ordsLong = Arrays.copyOf(ordsLong, nextSize); } else { - ords = growExact(ords, nextSize); + ords = Arrays.copyOf(ords, nextSize); } } } 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 dfa6eb1465d..c5ab849f3f8 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 @@ -22,7 +22,6 @@ import java.io.IOException; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.IntsRef; import org.apache.lucene.util.IntsRefBuilder; -import org.apache.lucene.util.RamUsageEstimator; import org.apache.lucene.util.fst.FST.INPUT_TYPE; // javadoc import org.apache.lucene.util.packed.PackedInts; @@ -403,9 +402,7 @@ public class Builder { final int prefixLenPlus1 = pos1+1; if (frontier.length < input.length+1) { - @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); + final UnCompiledNode[] next = ArrayUtil.grow(frontier, input.length+1); for(int idx=frontier.length;idx(this, idx); } @@ -606,9 +603,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({"rawtypes","unchecked"}) final Arc[] newArcs = - new Arc[ArrayUtil.oversize(numArcs+1, RamUsageEstimator.NUM_BYTES_OBJECT_REF)]; - System.arraycopy(arcs, 0, newArcs, 0, arcs.length); + final Arc[] newArcs = ArrayUtil.grow(arcs, numArcs+1); for(int arcIdx=numArcs;arcIdx(); } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestPerSegmentDeletes.java b/lucene/core/src/test/org/apache/lucene/index/TestPerSegmentDeletes.java index 99a02024c8e..68d697b4d72 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestPerSegmentDeletes.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestPerSegmentDeletes.java @@ -19,6 +19,7 @@ package org.apache.lucene.index; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Random; @@ -233,12 +234,14 @@ public class TestPerSegmentDeletes extends LuceneTestCase { } public static int[] toArray(PostingsEnum postingsEnum) throws IOException { - List docs = new ArrayList<>(); + int[] docs = new int[0]; + int numDocs = 0; while (postingsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) { int docID = postingsEnum.docID(); - docs.add(docID); + docs = ArrayUtil.grow(docs, numDocs + 1); + docs[numDocs + 1] = docID; } - return ArrayUtil.toIntArray(docs); + return Arrays.copyOf(docs, numDocs); } public class RangeMergePolicy extends MergePolicy { 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 77471f943b4..eb80ddda259 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestArrayUtil.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestArrayUtil.java @@ -17,6 +17,7 @@ package org.apache.lucene.util; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.Random; @@ -70,30 +71,37 @@ public class TestArrayUtil extends LuceneTestCase { } } + private static int parseInt(String s) { + int start = random().nextInt(5); + char[] chars = new char[s.length() + start + random().nextInt(4)]; + s.getChars(0, s.length(), chars, start); + return ArrayUtil.parseInt(chars, start, s.length()); + } + public void testParseInt() throws Exception { expectThrows(NumberFormatException.class, () -> { - ArrayUtil.parseInt("".toCharArray()); + parseInt(""); }); expectThrows(NumberFormatException.class, () -> { - ArrayUtil.parseInt("foo".toCharArray()); + parseInt("foo"); }); expectThrows(NumberFormatException.class, () -> { - ArrayUtil.parseInt(String.valueOf(Long.MAX_VALUE).toCharArray()); + parseInt(String.valueOf(Long.MAX_VALUE)); }); expectThrows(NumberFormatException.class, () -> { - ArrayUtil.parseInt("0.34".toCharArray()); + parseInt("0.34"); }); - int test = ArrayUtil.parseInt("1".toCharArray()); + int test = parseInt("1"); assertTrue(test + " does not equal: " + 1, test == 1); - test = ArrayUtil.parseInt("-10000".toCharArray()); + test = parseInt("-10000"); assertTrue(test + " does not equal: " + -10000, test == -10000); - test = ArrayUtil.parseInt("1923".toCharArray()); + test = parseInt("1923"); assertTrue(test + " does not equal: " + 1923, test == 1923); - test = ArrayUtil.parseInt("-1".toCharArray()); + test = parseInt("-1"); assertTrue(test + " does not equal: " + -1, test == -1); test = ArrayUtil.parseInt("foo 1923 bar".toCharArray(), 4, 4); assertTrue(test + " does not equal: " + 1923, test == 1923); @@ -102,8 +110,8 @@ public class TestArrayUtil extends LuceneTestCase { public void testSliceEquals() { String left = "this is equal"; String right = left; - char[] leftChars = left.toCharArray(); - char[] rightChars = right.toCharArray(); + 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())); diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinCollector.java b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinCollector.java index 94b3e71696b..70e15498d81 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinCollector.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinCollector.java @@ -280,13 +280,13 @@ public class ToParentBlockJoinCollector implements Collector { // While rare, this could happen if join query had // null scorer on first segment(s) but then became // non-null on later segments - og.docs = ArrayUtil.grow(og.docs); + og.docs = ArrayUtil.grow(og.docs, numSubScorers); } if (og.counts.length < numSubScorers) { og.counts = ArrayUtil.grow(og.counts); } if (trackScores && og.scores.length < numSubScorers) { - og.scores = ArrayUtil.grow(og.scores); + og.scores = ArrayUtil.grow(og.scores, numSubScorers); } //System.out.println("\ncopyGroups parentDoc=" + og.doc); diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/automaton/AutomatonTestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/util/automaton/AutomatonTestUtil.java index 52a63a49693..8ef4febea9c 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/util/automaton/AutomatonTestUtil.java +++ b/lucene/test-framework/src/java/org/apache/lucene/util/automaton/AutomatonTestUtil.java @@ -17,6 +17,7 @@ package org.apache.lucene.util.automaton; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -205,8 +206,8 @@ public class AutomatonTestUtil { } public int[] getRandomAcceptedString(Random r) { - - final List soFar = new ArrayList<>(); + int[] codePoints = new int[0]; + int codepointCount = 0; int s = 0; @@ -248,11 +249,12 @@ public class AutomatonTestUtil { } else { t = transitions[s][r.nextInt(transitions[s].length)]; } - soFar.add(getRandomCodePoint(r, t.min, t.max)); + codePoints = ArrayUtil.grow(codePoints, codepointCount + 1); + codePoints[codepointCount++] = getRandomCodePoint(r, t.min, t.max); s = t.dest; } - return ArrayUtil.toIntArray(soFar); + return Arrays.copyOf(codePoints, codepointCount); } }