forked from apache/pinot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix [Type]ArrayList elements() method usage (apache#13354)
- Loading branch information
Showing
7 changed files
with
309 additions
and
26 deletions.
There are no files selected for viewing
139 changes: 139 additions & 0 deletions
139
pinot-common/src/main/java/org/apache/pinot/common/utils/ArrayListUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/** | ||
* 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.pinot.common.utils; | ||
|
||
import it.unimi.dsi.fastutil.doubles.DoubleArrayList; | ||
import it.unimi.dsi.fastutil.floats.FloatArrayList; | ||
import it.unimi.dsi.fastutil.ints.IntArrayList; | ||
import it.unimi.dsi.fastutil.longs.LongArrayList; | ||
import it.unimi.dsi.fastutil.objects.ObjectArrayList; | ||
|
||
|
||
/** | ||
* Utility class for {@link IntArrayList}, {@link LongArrayList}, {@link FloatArrayList}, {@link DoubleArrayList}, | ||
* {@link ObjectArrayList}. | ||
*/ | ||
public class ArrayListUtils { | ||
private ArrayListUtils() { | ||
} | ||
|
||
/** | ||
* Best effort extract the given {@link IntArrayList} to an int array without copying the elements. | ||
* The {@link IntArrayList#elements()} returned int array may be longer than the actual size of the | ||
* {@link IntArrayList}, and the actual size of the {@link IntArrayList} can be retrieved using | ||
* {@link IntArrayList#size()}. | ||
* This method checks the length of the returned int array and returns the same if it is equal to the size of the | ||
* {@link IntArrayList}, otherwise, it copies the elements to a new int array and returns it. | ||
* | ||
* <p>Use this method only if you are sure that the returned int array will not be modified. | ||
* <p>Otherwise, use {@link IntArrayList#toIntArray()}. | ||
* | ||
* @param intArrayList Input {@link IntArrayList} | ||
* @return Best effort extracted int array without copying the elements | ||
*/ | ||
public static int[] toIntArray(IntArrayList intArrayList) { | ||
int[] intArrayListElements = intArrayList.elements(); | ||
return intArrayListElements.length == intArrayList.size() ? intArrayListElements : intArrayList.toIntArray(); | ||
} | ||
|
||
/** | ||
* Best effort extract the given {@link LongArrayList} to a long array without copying the elements. | ||
* The {@link LongArrayList#elements()} returned long array may be longer than the actual size of the | ||
* {@link LongArrayList}, and the actual size of the {@link LongArrayList} can be retrieved using | ||
* {@link LongArrayList#size()}. | ||
* This method checks the length of the returned long array and returns the same if it is equal to the size of the | ||
* {@link LongArrayList}, otherwise, it copies the elements to a new long array and returns it. | ||
* | ||
* <p>Use this method only if you are sure that the returned long array will not be modified. | ||
* <p>Otherwise, use {@link LongArrayList#toLongArray()}. | ||
* | ||
* @param longArrayList Input {@link LongArrayList} | ||
* @return Best effort extracted long array without copying the elements | ||
*/ | ||
public static long[] toLongArray(LongArrayList longArrayList) { | ||
long[] longArrayListElements = longArrayList.elements(); | ||
return longArrayListElements.length == longArrayList.size() ? longArrayListElements : longArrayList.toLongArray(); | ||
} | ||
|
||
/** | ||
* Best effort extract the given {@link FloatArrayList} to a float array without copying the elements. | ||
* The {@link FloatArrayList#elements()} returned float array may be longer than the actual size of the | ||
* {@link FloatArrayList}, and the actual size of the {@link FloatArrayList} can be retrieved using | ||
* {@link FloatArrayList#size()}. | ||
* This method checks the length of the returned float array and returns the same if it is equal to the size of the | ||
* {@link FloatArrayList}, otherwise, it copies the elements to a new float array and returns it. | ||
* | ||
* <p>Use this method only if you are sure that the returned float array will not be modified. | ||
* <p>Otherwise, use {@link FloatArrayList#toFloatArray()}. | ||
* | ||
* @param floatArrayList Input {@link FloatArrayList} | ||
* @return Best effort extracted float array without copying the elements | ||
*/ | ||
public static float[] toFloatArray(FloatArrayList floatArrayList) { | ||
float[] floatArrayListElements = floatArrayList.elements(); | ||
return floatArrayListElements.length == floatArrayList.size() ? floatArrayListElements | ||
: floatArrayList.toFloatArray(); | ||
} | ||
|
||
/** | ||
* Best effort extract the given {@link DoubleArrayList} to a double array without copying the elements. | ||
* The {@link DoubleArrayList#elements()} returned double array may be longer than the actual size of the | ||
* {@link DoubleArrayList}, and the actual size of the {@link DoubleArrayList} can be retrieved using | ||
* {@link DoubleArrayList#size()}. | ||
* This method checks the length of the returned double array and returns the same if it is equal to the size of the | ||
* {@link DoubleArrayList}, otherwise, it copies the elements to a new double array and returns it. | ||
* | ||
* <p>Use this method only if you are sure that the returned double array will not be modified. | ||
* <p>Otherwise, use {@link DoubleArrayList#toDoubleArray()}. | ||
* | ||
* @param doubleArrayList Input {@link DoubleArrayList} | ||
* @return Best effort extracted double array without copying the elements | ||
*/ | ||
public static double[] toDoubleArray(DoubleArrayList doubleArrayList) { | ||
double[] doubleArrayListElements = doubleArrayList.elements(); | ||
return doubleArrayListElements.length == doubleArrayList.size() ? doubleArrayListElements | ||
: doubleArrayList.toDoubleArray(); | ||
} | ||
|
||
/** | ||
* Convert the given {@link ObjectArrayList} to a string array. | ||
* The method {@link ObjectArrayList#elements()} could return either Object[] or String[]. The casting to String[] | ||
* is not guaranteed to work, and it may throw {@link ClassCastException} if the internal object is not a String | ||
* array. | ||
* <p> | ||
* This method first get `elements` as Object, then check if it's instance of String[]. | ||
* Only return the reference when the internal object is a String array and the length equals to ObjectArrayList | ||
* size. | ||
* For all the other scenarios, just copy the elements to a new string array and returns it. | ||
* <p> | ||
* | ||
* @param stringArrayList Input {@link ObjectArrayList} | ||
* @return Copied string array | ||
*/ | ||
public static String[] toStringArray(ObjectArrayList<String> stringArrayList) { | ||
Object elements = stringArrayList.elements(); | ||
if (elements instanceof String[]) { | ||
String[] stringArrayListElements = (String[]) elements; | ||
if (stringArrayListElements.length == stringArrayList.size()) { | ||
return stringArrayListElements; | ||
} | ||
} | ||
return stringArrayList.toArray(new String[0]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
pinot-common/src/test/java/org/apache/pinot/common/utils/ArrayListUtilsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/** | ||
* 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.pinot.common.utils; | ||
|
||
import it.unimi.dsi.fastutil.doubles.DoubleArrayList; | ||
import it.unimi.dsi.fastutil.floats.FloatArrayList; | ||
import it.unimi.dsi.fastutil.ints.IntArrayList; | ||
import it.unimi.dsi.fastutil.longs.LongArrayList; | ||
import it.unimi.dsi.fastutil.objects.ObjectArrayList; | ||
import org.testng.annotations.Test; | ||
|
||
import static org.testng.Assert.assertEquals; | ||
|
||
|
||
public class ArrayListUtilsTest { | ||
@Test | ||
public void testToIntArray() { | ||
// Test empty list | ||
IntArrayList intArrayList = new IntArrayList(); | ||
int[] intArray = ArrayListUtils.toIntArray(intArrayList); | ||
assertEquals(intArray.length, 0); | ||
|
||
// Test list with one element | ||
intArrayList.add(1); | ||
intArray = ArrayListUtils.toIntArray(intArrayList); | ||
assertEquals(intArray.length, 1); | ||
assertEquals(intArray[0], 1); | ||
|
||
// Test list with multiple elements | ||
intArrayList.add(2); | ||
intArrayList.add(3); | ||
intArray = ArrayListUtils.toIntArray(intArrayList); | ||
assertEquals(intArray.length, 3); | ||
assertEquals(intArray[0], 1); | ||
assertEquals(intArray[1], 2); | ||
assertEquals(intArray[2], 3); | ||
} | ||
|
||
@Test | ||
public void testToLongArray() { | ||
// Test empty list | ||
LongArrayList longArrayList = new LongArrayList(); | ||
long[] longArray = ArrayListUtils.toLongArray(longArrayList); | ||
assertEquals(longArray.length, 0); | ||
|
||
// Test list with one element | ||
longArrayList.add(1L); | ||
longArray = ArrayListUtils.toLongArray(longArrayList); | ||
assertEquals(longArray.length, 1); | ||
assertEquals(longArray[0], 1L); | ||
|
||
// Test list with multiple elements | ||
longArrayList.add(2L); | ||
longArrayList.add(3L); | ||
longArray = ArrayListUtils.toLongArray(longArrayList); | ||
assertEquals(longArray.length, 3); | ||
assertEquals(longArray[0], 1L); | ||
assertEquals(longArray[1], 2L); | ||
assertEquals(longArray[2], 3L); | ||
} | ||
|
||
@Test | ||
public void testToFloatArray() { | ||
// Test empty list | ||
FloatArrayList floatArrayList = new FloatArrayList(); | ||
float[] floatArray = ArrayListUtils.toFloatArray(floatArrayList); | ||
assertEquals(floatArray.length, 0); | ||
|
||
// Test list with one element | ||
floatArrayList.add(1.0f); | ||
floatArray = ArrayListUtils.toFloatArray(floatArrayList); | ||
assertEquals(floatArray.length, 1); | ||
assertEquals(floatArray[0], 1.0f); | ||
|
||
// Test list with multiple elements | ||
floatArrayList.add(2.0f); | ||
floatArrayList.add(3.0f); | ||
floatArray = ArrayListUtils.toFloatArray(floatArrayList); | ||
assertEquals(floatArray.length, 3); | ||
assertEquals(floatArray[0], 1.0f); | ||
assertEquals(floatArray[1], 2.0f); | ||
assertEquals(floatArray[2], 3.0f); | ||
} | ||
|
||
@Test | ||
public void testToDoubleArray() { | ||
// Test empty list | ||
DoubleArrayList doubleArrayList = new DoubleArrayList(); | ||
double[] doubleArray = ArrayListUtils.toDoubleArray(doubleArrayList); | ||
assertEquals(doubleArray.length, 0); | ||
|
||
// Test list with one element | ||
doubleArrayList.add(1.0); | ||
doubleArray = ArrayListUtils.toDoubleArray(doubleArrayList); | ||
assertEquals(doubleArray.length, 1); | ||
assertEquals(doubleArray[0], 1.0); | ||
|
||
// Test list with multiple elements | ||
doubleArrayList.add(2.0); | ||
doubleArrayList.add(3.0); | ||
doubleArray = ArrayListUtils.toDoubleArray(doubleArrayList); | ||
assertEquals(doubleArray.length, 3); | ||
assertEquals(doubleArray[0], 1.0); | ||
assertEquals(doubleArray[1], 2.0); | ||
assertEquals(doubleArray[2], 3.0); | ||
} | ||
|
||
@Test | ||
public void testToStringArray() { | ||
// Test empty list | ||
ObjectArrayList<String> stringArrayList = new ObjectArrayList<String>(); | ||
String[] stringArray = ArrayListUtils.toStringArray(stringArrayList); | ||
assertEquals(stringArray.length, 0); | ||
|
||
// Test list with one element | ||
stringArrayList.add("1"); | ||
stringArray = ArrayListUtils.toStringArray(stringArrayList); | ||
assertEquals(stringArray.length, 1); | ||
assertEquals(stringArray[0], "1"); | ||
|
||
// Test list with multiple elements | ||
stringArrayList.add("2"); | ||
stringArrayList.add("3"); | ||
stringArray = ArrayListUtils.toStringArray(stringArrayList); | ||
assertEquals(stringArray.length, 3); | ||
assertEquals(stringArray[0], "1"); | ||
assertEquals(stringArray[1], "2"); | ||
assertEquals(stringArray[2], "3"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.