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 */
23package java.util.stream;
24
25import org.testng.annotations.DataProvider;
26import org.testng.annotations.Test;
27
28import java.util.*;
29import java.util.function.DoubleConsumer;
30import java.util.function.IntConsumer;
31import java.util.function.LongConsumer;
32
33import static org.testng.Assert.assertEquals;
34import static org.testng.Assert.assertFalse;
35
36@Test
37public 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")
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")
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" })
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" })
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")
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")
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" })
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" })
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")
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")
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" })
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" })
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")
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")
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" })
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" })
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