1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @summary Lambda unit test for Arrays.
  27  * @library /sqeutil
  28  * @(#) ArraysTest.java
  29  * @author Tristan Yan
  30  * @run testng ArraysLambdaTest
  31  */
  32 
  33 import java.util.Arrays;
  34 import java.util.Random;
  35 import static org.testng.Assert.*;
  36 import org.testng.annotations.Test;
  37 
  38 public class ArraysLambdaTest {
  39     private final static int ARRAY_SIZE = 1 << 8;
  40 
  41     private final static int MIN_LEN = 1 << 2;
  42 
  43     private final static int MAX_LEN = 1 << 6;
  44 
  45     private final static Random rand = new Random(System.currentTimeMillis());
  46 
  47     private long[] generateLongData(int size) {
  48         long[] array = new long[size];
  49         for(int i = 0; i < size; i++) {
  50             array[i] = rand.nextLong();
  51         }
  52         return array;
  53     }
  54 
  55     private int[] generateIntData(int size) {
  56         int[] array = new int[size];
  57         for(int i = 0; i < size; i++) {
  58             array[i] = rand.nextInt();
  59         }
  60         return array;
  61     }
  62 
  63     private double[] generateDoubleData(int size) {
  64         double[] array = new double[size];
  65         //Precision could be changed when do parallel calculation, we only use
  66         //integer to test it to prevent precision lost issue
  67         for(int i = 0; i < size; i++) {
  68             array[i] = rand.nextInt(1024);
  69         }
  70         return array;
  71     }
  72 
  73     private String[] generateStringData(int size) {
  74         String[] array = new String[size];
  75         for(int i = 0; i < size; i++) {
  76             array[i] = StringUtilities.randomString(MAX_LEN, MIN_LEN);
  77         }
  78         return array;
  79     }
  80 
  81     private StringBuilder[] generateSBData(int size) {
  82         StringBuilder[] array = new StringBuilder[size];
  83         for(int i = 0; i < size; i++) {
  84             array[i] = new StringBuilder(StringUtilities.randomString(MAX_LEN, MIN_LEN));
  85         }
  86         return array;
  87     }
  88 
  89     @Test
  90     public void testParallelPrefixForInt() {
  91         int startIndex = rand.nextInt(ARRAY_SIZE);
  92         int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
  93 
  94         int[] intArr1 = generateIntData(ARRAY_SIZE);
  95         int[] intArr2 = Arrays.copyOf(intArr1, ARRAY_SIZE);
  96         int[] intBackArr = Arrays.copyOf(intArr1, ARRAY_SIZE);
  97         Arrays.parallelPrefix(intArr1, LambdaUtilities.addIntBinaryOperator());
  98         assertEquals(intArr1.length, intBackArr.length);
  99         int totalInt = 0;
 100         for(int i = 0; i < ARRAY_SIZE; i++) {
 101             totalInt += intBackArr[i];
 102             assertEquals(totalInt, intArr1[i]);
 103         }
 104         Arrays.parallelPrefix(intArr2, startIndex, endIndex, LambdaUtilities.addIntBinaryOperator());
 105         totalInt = 0;
 106         for(int i = startIndex; i < endIndex; i++) {
 107             totalInt += intBackArr[i];
 108             assertEquals(totalInt, intArr2[i]);
 109         }
 110     }
 111 
 112     @Test
 113     public void testParallelPrefixForLong() {
 114         int startIndex = rand.nextInt(ARRAY_SIZE);
 115         int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
 116         long[] longArr1 = generateLongData(ARRAY_SIZE);
 117         long[] longArr2 = Arrays.copyOf(longArr1, ARRAY_SIZE);
 118         long[] longBackArr = Arrays.copyOf(longArr1, ARRAY_SIZE);
 119         Arrays.parallelPrefix(longArr1, LambdaUtilities.addLongBinaryOperator());
 120         assertEquals(longArr1.length, longBackArr.length);
 121         long totalLong = 0;
 122         for(int i = 0; i < ARRAY_SIZE; i++) {
 123             totalLong += longBackArr[i];
 124             assertEquals(totalLong, longArr1[i]);
 125         }
 126         Arrays.parallelPrefix(longArr2, startIndex, endIndex, LambdaUtilities.addLongBinaryOperator());
 127         totalLong = 0;
 128         for(int i = startIndex; i < endIndex; i++) {
 129             totalLong += longBackArr[i];
 130             assertEquals(totalLong, longArr2[i]);
 131         }
 132     }
 133 
 134     @Test
 135     public void testParallelPrefixForDouble() {
 136         int startIndex = rand.nextInt(ARRAY_SIZE);
 137         int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
 138         double[] doubleArr1 = generateDoubleData(ARRAY_SIZE);
 139         double[] doubleArr2 = Arrays.copyOf(doubleArr1, ARRAY_SIZE);
 140         double[] doubleBackArr = Arrays.copyOf(doubleArr1, ARRAY_SIZE);
 141         Arrays.parallelPrefix(doubleArr1, LambdaUtilities.addDoubleBinaryOperator());
 142         assertEquals(doubleArr1.length, doubleBackArr.length);
 143         double totalDouble = 0;
 144         for(int i = 0; i < ARRAY_SIZE; i++) {
 145             totalDouble += doubleBackArr[i];
 146             assertEquals(totalDouble, doubleArr1[i]);
 147         }
 148         Arrays.parallelPrefix(doubleArr2, startIndex, endIndex, LambdaUtilities.addDoubleBinaryOperator());
 149         totalDouble = 0;
 150         for(int i = startIndex; i < endIndex; i++) {
 151             totalDouble += doubleBackArr[i];
 152             assertEquals(totalDouble, doubleArr2[i]);
 153         }
 154     }
 155 
 156     @Test
 157     public void testParallelPrefix() {
 158         int startIndex = rand.nextInt(ARRAY_SIZE);
 159         int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
 160         StringBuilder[] sbArr1 = generateSBData(ARRAY_SIZE);
 161         StringBuilder[] sbArr2 = Arrays.copyOf(sbArr1, ARRAY_SIZE);
 162         StringBuilder[] sbBackArr = Arrays.copyOf(sbArr1, ARRAY_SIZE);
 163         Arrays.parallelPrefix(sbArr1, LambdaUtilities.appendSBBinaryOperator());
 164         assertEquals(sbArr1.length, sbBackArr.length);
 165         StringBuilder sbTotal = new StringBuilder();
 166         for(int i = 0; i < ARRAY_SIZE; i++) {
 167             sbTotal.append(sbBackArr[i]);
 168             assertEquals(sbTotal.toString(), sbArr1[i].toString());
 169         }
 170         Arrays.parallelPrefix(sbArr2, startIndex, endIndex, LambdaUtilities.appendSBBinaryOperator());
 171         sbTotal = new StringBuilder();
 172         for(int i = startIndex; i < endIndex; i++) {
 173             sbTotal.append(sbBackArr[i]);
 174             assertEquals(sbTotal.toString(), sbArr2[i].toString());
 175         }
 176     }
 177 
 178     @Test
 179     public void testSetAll() {
 180         boolean[] both = new boolean[]{true, false};
 181         for(boolean isParallel:both) {
 182             //test Arrays.setAll(double[], IntFunction)
 183             int[] iArray = new int[ARRAY_SIZE];
 184             if (isParallel)
 185                 Arrays.parallelSetAll(iArray, i -> 2 * i);
 186             else
 187                 Arrays.setAll(iArray, i -> 2 * i);
 188             for(int i = 0; i < iArray.length; i++)
 189                 assertEquals(iArray[i], 2 * i);
 190 
 191             //test Arrays.setAll(long[], IntFunction)
 192             long[] lArray = new long[ARRAY_SIZE];
 193             if (isParallel)
 194                 Arrays.parallelSetAll(lArray, i -> (long)i << 32);
 195             else
 196                 Arrays.setAll(lArray, i -> (long)i << 32);
 197             for(int i = 0; i < lArray.length; i++)
 198                 assertEquals(lArray[i] >> 32, i);
 199 
 200             //test Arrays.setAll(double[], IntToDoubleFunction)
 201             double[] dArray = new double[ARRAY_SIZE];
 202             if (isParallel)
 203                 Arrays.parallelSetAll(dArray, i -> Math.sin(i));
 204             else
 205                 Arrays.setAll(dArray, i -> Math.sin(i));
 206             for(int i = 0; i < dArray.length; i++)
 207                 assertEquals(dArray[i], Math.sin(i));
 208 
 209             //test Arrays.setAll(T[], IntFunction<? extends T>)
 210             //This is a other version of Arrays.copy()
 211             String[] sArrExpected = generateStringData(ARRAY_SIZE);
 212             String[] sArr = new String[ARRAY_SIZE];
 213             if (isParallel)
 214                 Arrays.parallelSetAll(sArr, i -> sArrExpected[i]);
 215             else
 216                 Arrays.setAll(sArr, i -> sArrExpected[i]);
 217             for(int i = 0; i < sArr.length; i++)
 218                 assertEquals(sArrExpected[i], sArrExpected[i]); 
 219         }
 220     }
 221 }