/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch 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.elasticsearch.common.util; import org.elasticsearch.test.ESTestCase; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import static org.hamcrest.Matchers.is; public class ArrayUtilsTests extends ESTestCase { public void testBinarySearch() throws Exception { for (int j = 0; j < 100; j++) { int index = Math.min(randomInt(0, 10), 9); double tolerance = Math.random() * 0.01; double lookForValue = randomFreq(0.9) ? -1 : Double.NaN; // sometimes we'll look for NaN double[] array = new double[10]; for (int i = 0; i < array.length; i++) { double value; if (randomFreq(0.9)) { value = Math.random() * 10; array[i] = value + ((randomFreq(0.5) ? 1 : -1) * Math.random() * tolerance); } else { // sometimes we'll have NaN in the array value = Double.NaN; array[i] = value; } if (i == index && lookForValue < 0) { lookForValue = value; } } Arrays.sort(array); // pick up all the indices that fall within the range of [lookForValue - tolerance, lookForValue + tolerance] // we need to do this, since we choose the values randomly and we might end up having multiple values in the // array that will match the looked for value with the random tolerance. In such cases, the binary search will // return the first one that will match. BitSet bitSet = new BitSet(10); for (int i = 0; i < array.length; i++) { if (Double.isNaN(lookForValue) && Double.isNaN(array[i])) { bitSet.set(i); } else if ((array[i] >= lookForValue - tolerance) && (array[i] <= lookForValue + tolerance)) { bitSet.set(i); } } int foundIndex = ArrayUtils.binarySearch(array, lookForValue, tolerance); if (bitSet.cardinality() == 0) { assertThat(foundIndex, is(-1)); } else { assertThat(bitSet.get(foundIndex), is(true)); } } } private boolean randomFreq(double freq) { return Math.random() < freq; } private int randomInt(int min, int max) { int delta = (int) (Math.random() * (max - min)); return min + delta; } public void testConcat() { assertArrayEquals(new String[]{"a", "b", "c", "d"}, ArrayUtils.concat(new String[]{"a", "b"}, new String[]{"c", "d"})); int firstSize = randomIntBetween(0, 10); String[] first = new String[firstSize]; ArrayList<String> sourceOfTruth = new ArrayList<>(); for (int i = 0; i < firstSize; i++) { first[i] = randomRealisticUnicodeOfCodepointLengthBetween(0,10); sourceOfTruth.add(first[i]); } int secondSize = randomIntBetween(0, 10); String[] second = new String[secondSize]; for (int i = 0; i < secondSize; i++) { second[i] = randomRealisticUnicodeOfCodepointLengthBetween(0, 10); sourceOfTruth.add(second[i]); } assertArrayEquals(sourceOfTruth.toArray(new String[0]), ArrayUtils.concat(first, second)); } }