1 /*
2  * Copyright (c) 2012, 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 package java.util.stream;
24 
25 import org.testng.annotations.DataProvider;
26 import org.testng.annotations.Test;
27 
28 import java.util.*;
29 import java.util.function.DoubleConsumer;
30 import java.util.function.IntConsumer;
31 import java.util.function.LongConsumer;
32 
33 import static org.testng.Assert.assertEquals;
34 import static org.testng.Assert.assertFalse;
35 
36 @Test
37 public class SpinedBufferTest {
38 
39     // Create sizes around the boundary of spines
40     static List<Integer> sizes;
41     static {
42         try {
43             sizes = IntStream.range(0, 15)
44                              .map(i -> 1 << i)
45                              .flatMap(i -> Arrays.stream(new int[] { i-2, i-1, i, i+1, i+2 }))
46                              .filter(i -> i >= 0)
47                              .boxed()
48                              .distinct()
49                              .collect(Collectors.toList());
50         }
51         catch (Exception e) {
52             e.printStackTrace();
53         }
54     }
55 
56     private static final int TEST_SIZE = 5000;
57 
58     // SpinedBuffer
59 
60     @DataProvider(name = "SpinedBuffer")
createSpinedBuffer()61     public Object[][] createSpinedBuffer() {
62         List<Object[]> params = new ArrayList<>();
63 
64         for (int size : sizes) {
65             int[] array = IntStream.range(0, size).toArray();
66 
67             SpinedBuffer<Integer> sb = new SpinedBuffer<>();
68             Arrays.stream(array).boxed().forEach(sb);
69             params.add(new Object[]{array, sb});
70 
71             sb = new SpinedBuffer<>(size / 2);
72             Arrays.stream(array).boxed().forEach(sb);
73             params.add(new Object[]{array, sb});
74 
75             sb = new SpinedBuffer<>(size);
76             Arrays.stream(array).boxed().forEach(sb);
77             params.add(new Object[]{array, sb});
78 
79             sb = new SpinedBuffer<>(size * 2);
80             Arrays.stream(array).boxed().forEach(sb);
81             params.add(new Object[]{array, sb});
82         }
83 
84         return params.toArray(new Object[0][]);
85     }
86 
87     @Test(dataProvider = "SpinedBuffer")
testSpliterator(int[] array, SpinedBuffer<Integer> sb)88     public void testSpliterator(int[] array, SpinedBuffer<Integer> sb) {
89         assertEquals(sb.count(), array.length);
90         assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
91 
92         SpliteratorTestHelper.testSpliterator(sb::spliterator);
93     }
94 
95     @Test(dataProvider = "SpinedBuffer", groups = { "serialization-hostile" })
testLastSplit(int[] array, SpinedBuffer<Integer> sb)96     public void testLastSplit(int[] array, SpinedBuffer<Integer> sb) {
97         Spliterator<Integer> spliterator = sb.spliterator();
98         Spliterator<Integer> split = spliterator.trySplit();
99         long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
100         long lastSplitSize = spliterator.getExactSizeIfKnown();
101         splitSizes += lastSplitSize;
102 
103         assertEquals(splitSizes, array.length);
104 
105         List<Integer> contentOfLastSplit = new ArrayList<>();
106         spliterator.forEachRemaining(contentOfLastSplit::add);
107 
108         assertEquals(contentOfLastSplit.size(), lastSplitSize);
109 
110         List<Integer> end = Arrays.stream(array)
111                 .boxed()
112                 .skip(array.length - lastSplitSize)
113                 .collect(Collectors.toList());
114         assertEquals(contentOfLastSplit, end);
115     }
116 
117     @Test(groups = { "serialization-hostile" })
testSpinedBuffer()118     public void testSpinedBuffer() {
119         List<Integer> list1 = new ArrayList<>();
120         List<Integer> list2 = new ArrayList<>();
121         SpinedBuffer<Integer> sb = new SpinedBuffer<>();
122         for (int i = 0; i < TEST_SIZE; i++) {
123             list1.add(i);
124             sb.accept(i);
125         }
126         Iterator<Integer> it = sb.iterator();
127         for (int i = 0; i < TEST_SIZE; i++)
128             list2.add(it.next());
129         assertFalse(it.hasNext());
130         assertEquals(list1, list2);
131 
132         for (int i = 0; i < TEST_SIZE; i++)
133             assertEquals(sb.get(i), (Integer) i, Integer.toString(i));
134 
135         list2.clear();
136         sb.forEach(list2::add);
137         assertEquals(list1, list2);
138         Integer[] array = sb.asArray(LambdaTestHelpers.integerArrayGenerator);
139         list2.clear();
140         for (Integer i : array)
141             list2.add(i);
142         assertEquals(list1, list2);
143     }
144 
145     // IntSpinedBuffer
146 
147     @DataProvider(name = "IntSpinedBuffer")
createIntSpinedBuffer()148     public Object[][] createIntSpinedBuffer() {
149         List<Object[]> params = new ArrayList<>();
150 
151         for (int size : sizes) {
152             int[] array = IntStream.range(0, size).toArray();
153             SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
154             Arrays.stream(array).forEach(sb);
155 
156             params.add(new Object[]{array, sb});
157         }
158 
159         return params.toArray(new Object[0][]);
160     }
161 
162     @Test(dataProvider = "IntSpinedBuffer")
testIntSpliterator(int[] array, SpinedBuffer.OfInt sb)163     public void testIntSpliterator(int[] array, SpinedBuffer.OfInt sb) {
164         assertEquals(sb.count(), array.length);
165         assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
166 
167         SpliteratorTestHelper.testIntSpliterator(sb::spliterator);
168     }
169 
170     @Test(dataProvider = "IntSpinedBuffer", groups = { "serialization-hostile" })
testIntLastSplit(int[] array, SpinedBuffer.OfInt sb)171     public void testIntLastSplit(int[] array, SpinedBuffer.OfInt sb) {
172         Spliterator.OfInt spliterator = sb.spliterator();
173         Spliterator.OfInt split = spliterator.trySplit();
174         long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
175         long lastSplitSize = spliterator.getExactSizeIfKnown();
176         splitSizes += lastSplitSize;
177 
178         assertEquals(splitSizes, array.length);
179 
180         List<Integer> contentOfLastSplit = new ArrayList<>();
181         spliterator.forEachRemaining((IntConsumer) contentOfLastSplit::add);
182 
183         assertEquals(contentOfLastSplit.size(), lastSplitSize);
184 
185         List<Integer> end = Arrays.stream(array)
186                 .boxed()
187                 .skip(array.length - lastSplitSize)
188                 .collect(Collectors.toList());
189         assertEquals(contentOfLastSplit, end);
190     }
191 
192     @Test(groups = { "serialization-hostile" })
testIntSpinedBuffer()193     public void testIntSpinedBuffer() {
194         List<Integer> list1 = new ArrayList<>();
195         List<Integer> list2 = new ArrayList<>();
196         SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
197         for (int i = 0; i < TEST_SIZE; i++) {
198             list1.add(i);
199             sb.accept(i);
200         }
201         PrimitiveIterator.OfInt it = sb.iterator();
202         for (int i = 0; i < TEST_SIZE; i++)
203             list2.add(it.nextInt());
204         assertFalse(it.hasNext());
205         assertEquals(list1, list2);
206 
207         for (int i = 0; i < TEST_SIZE; i++)
208             assertEquals(sb.get(i), i, Integer.toString(i));
209 
210         list2.clear();
211         sb.forEach((int i) -> list2.add(i));
212         assertEquals(list1, list2);
213         int[] array = sb.asPrimitiveArray();
214         list2.clear();
215         for (int i : array)
216             list2.add(i);
217         assertEquals(list1, list2);
218     }
219 
220     // LongSpinedBuffer
221 
222     @DataProvider(name = "LongSpinedBuffer")
createLongSpinedBuffer()223     public Object[][] createLongSpinedBuffer() {
224         List<Object[]> params = new ArrayList<>();
225 
226         for (int size : sizes) {
227             long[] array = LongStream.range(0, size).toArray();
228             SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
229             Arrays.stream(array).forEach(sb);
230 
231             params.add(new Object[]{array, sb});
232         }
233 
234         return params.toArray(new Object[0][]);
235     }
236 
237     @Test(dataProvider = "LongSpinedBuffer")
testLongSpliterator(long[] array, SpinedBuffer.OfLong sb)238     public void testLongSpliterator(long[] array, SpinedBuffer.OfLong sb) {
239         assertEquals(sb.count(), array.length);
240         assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
241 
242         SpliteratorTestHelper.testLongSpliterator(sb::spliterator);
243     }
244 
245     @Test(dataProvider = "LongSpinedBuffer", groups = { "serialization-hostile" })
testLongLastSplit(long[] array, SpinedBuffer.OfLong sb)246     public void testLongLastSplit(long[] array, SpinedBuffer.OfLong sb) {
247         Spliterator.OfLong spliterator = sb.spliterator();
248         Spliterator.OfLong split = spliterator.trySplit();
249         long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
250         long lastSplitSize = spliterator.getExactSizeIfKnown();
251         splitSizes += lastSplitSize;
252 
253         assertEquals(splitSizes, array.length);
254 
255         List<Long> contentOfLastSplit = new ArrayList<>();
256         spliterator.forEachRemaining((LongConsumer) contentOfLastSplit::add);
257 
258         assertEquals(contentOfLastSplit.size(), lastSplitSize);
259 
260         List<Long> end = Arrays.stream(array)
261                 .boxed()
262                 .skip(array.length - lastSplitSize)
263                 .collect(Collectors.toList());
264         assertEquals(contentOfLastSplit, end);
265     }
266 
267     @Test(groups = { "serialization-hostile" })
testLongSpinedBuffer()268     public void testLongSpinedBuffer() {
269         List<Long> list1 = new ArrayList<>();
270         List<Long> list2 = new ArrayList<>();
271         SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
272         for (long i = 0; i < TEST_SIZE; i++) {
273             list1.add(i);
274             sb.accept(i);
275         }
276         PrimitiveIterator.OfLong it = sb.iterator();
277         for (int i = 0; i < TEST_SIZE; i++)
278             list2.add(it.nextLong());
279         assertFalse(it.hasNext());
280         assertEquals(list1, list2);
281 
282         for (int i = 0; i < TEST_SIZE; i++)
283             assertEquals(sb.get(i), i, Long.toString(i));
284 
285         list2.clear();
286         sb.forEach((long i) -> list2.add(i));
287         assertEquals(list1, list2);
288         long[] array = sb.asPrimitiveArray();
289         list2.clear();
290         for (long i : array)
291             list2.add(i);
292         assertEquals(list1, list2);
293     }
294 
295     // DoubleSpinedBuffer
296 
297     @DataProvider(name = "DoubleSpinedBuffer")
createDoubleSpinedBuffer()298     public Object[][] createDoubleSpinedBuffer() {
299         List<Object[]> params = new ArrayList<>();
300 
301         for (int size : sizes) {
302             // @@@ replace with double range when implemented
303             double[] array = LongStream.range(0, size).asDoubleStream().toArray();
304             SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
305             Arrays.stream(array).forEach(sb);
306 
307             params.add(new Object[]{array, sb});
308         }
309 
310         return params.toArray(new Object[0][]);
311     }
312 
313     @Test(dataProvider = "DoubleSpinedBuffer")
testDoubleSpliterator(double[] array, SpinedBuffer.OfDouble sb)314     public void testDoubleSpliterator(double[] array, SpinedBuffer.OfDouble sb) {
315         assertEquals(sb.count(), array.length);
316         assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
317 
318         SpliteratorTestHelper.testDoubleSpliterator(sb::spliterator);
319     }
320 
321     @Test(dataProvider = "DoubleSpinedBuffer", groups = { "serialization-hostile" })
testLongLastSplit(double[] array, SpinedBuffer.OfDouble sb)322     public void testLongLastSplit(double[] array, SpinedBuffer.OfDouble sb) {
323         Spliterator.OfDouble spliterator = sb.spliterator();
324         Spliterator.OfDouble split = spliterator.trySplit();
325         long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
326         long lastSplitSize = spliterator.getExactSizeIfKnown();
327         splitSizes += lastSplitSize;
328 
329         assertEquals(splitSizes, array.length);
330 
331         List<Double> contentOfLastSplit = new ArrayList<>();
332         spliterator.forEachRemaining((DoubleConsumer) contentOfLastSplit::add);
333 
334         assertEquals(contentOfLastSplit.size(), lastSplitSize);
335 
336         List<Double> end = Arrays.stream(array)
337                 .boxed()
338                 .skip(array.length - lastSplitSize)
339                 .collect(Collectors.toList());
340         assertEquals(contentOfLastSplit, end);
341     }
342 
343     @Test(groups = { "serialization-hostile" })
testDoubleSpinedBuffer()344     public void testDoubleSpinedBuffer() {
345         List<Double> list1 = new ArrayList<>();
346         List<Double> list2 = new ArrayList<>();
347         SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
348         for (long i = 0; i < TEST_SIZE; i++) {
349             list1.add((double) i);
350             sb.accept((double) i);
351         }
352         PrimitiveIterator.OfDouble it = sb.iterator();
353         for (int i = 0; i < TEST_SIZE; i++)
354             list2.add(it.nextDouble());
355         assertFalse(it.hasNext());
356         assertEquals(list1, list2);
357 
358         for (int i = 0; i < TEST_SIZE; i++)
359             assertEquals(sb.get(i), (double) i, Double.toString(i));
360 
361         list2.clear();
362         sb.forEach((double i) -> list2.add(i));
363         assertEquals(list1, list2);
364         double[] array = sb.asPrimitiveArray();
365         list2.clear();
366         for (double i : array)
367             list2.add(i);
368         assertEquals(list1, list2);
369     }
370 }
371