1
1
/*
2
- * Copyright (c) 2012, 2016 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2012, 2021 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,7 @@ private SliceOps() { }
50
50
* @return the sliced size
51
51
*/
52
52
private static long calcSize (long size , long skip , long limit ) {
53
- return size >= 0 ? Math .max (- 1 , Math .min (size - skip , limit )) : -1 ;
53
+ return size >= 0 ? Math .max (0 , Math .min (size - skip , limit )) : -1 ;
54
54
}
55
55
56
56
/**
@@ -72,28 +72,23 @@ private static long calcSliceFence(long skip, long limit) {
72
72
* spliterator type. Requires that the underlying Spliterator
73
73
* be SUBSIZED.
74
74
*/
75
- @ SuppressWarnings ("unchecked" )
76
75
private static <P_IN > Spliterator <P_IN > sliceSpliterator (StreamShape shape ,
77
76
Spliterator <P_IN > s ,
78
77
long skip , long limit ) {
79
78
assert s .hasCharacteristics (Spliterator .SUBSIZED );
80
79
long sliceFence = calcSliceFence (skip , limit );
81
- switch (shape ) {
82
- case REFERENCE :
83
- return new StreamSpliterators
84
- .SliceSpliterator .OfRef <>(s , skip , sliceFence );
85
- case INT_VALUE :
86
- return (Spliterator <P_IN >) new StreamSpliterators
87
- .SliceSpliterator .OfInt ((Spliterator .OfInt ) s , skip , sliceFence );
88
- case LONG_VALUE :
89
- return (Spliterator <P_IN >) new StreamSpliterators
90
- .SliceSpliterator .OfLong ((Spliterator .OfLong ) s , skip , sliceFence );
91
- case DOUBLE_VALUE :
92
- return (Spliterator <P_IN >) new StreamSpliterators
93
- .SliceSpliterator .OfDouble ((Spliterator .OfDouble ) s , skip , sliceFence );
94
- default :
95
- throw new IllegalStateException ("Unknown shape " + shape );
96
- }
80
+ @ SuppressWarnings ("unchecked" )
81
+ Spliterator <P_IN > sliceSpliterator = (Spliterator <P_IN >) switch (shape ) {
82
+ case REFERENCE
83
+ -> new StreamSpliterators .SliceSpliterator .OfRef <>(s , skip , sliceFence );
84
+ case INT_VALUE
85
+ -> new StreamSpliterators .SliceSpliterator .OfInt ((Spliterator .OfInt ) s , skip , sliceFence );
86
+ case LONG_VALUE
87
+ -> new StreamSpliterators .SliceSpliterator .OfLong ((Spliterator .OfLong ) s , skip , sliceFence );
88
+ case DOUBLE_VALUE
89
+ -> new StreamSpliterators .SliceSpliterator .OfDouble ((Spliterator .OfDouble ) s , skip , sliceFence );
90
+ };
91
+ return sliceSpliterator ;
97
92
}
98
93
99
94
/**
@@ -110,9 +105,15 @@ public static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream,
110
105
long skip , long limit ) {
111
106
if (skip < 0 )
112
107
throw new IllegalArgumentException ("Skip must be non-negative: " + skip );
108
+ long normalizedLimit = limit >= 0 ? limit : Long .MAX_VALUE ;
113
109
114
110
return new ReferencePipeline .StatefulOp <T , T >(upstream , StreamShape .REFERENCE ,
115
111
flags (limit )) {
112
+ @ Override
113
+ long exactOutputSize (long previousSize ) {
114
+ return calcSize (previousSize , skip , normalizedLimit );
115
+ }
116
+
116
117
Spliterator <T > unorderedSkipLimitSpliterator (Spliterator <T > s ,
117
118
long skip , long limit , long sizeIfKnown ) {
118
119
if (skip <= sizeIfKnown ) {
@@ -182,9 +183,9 @@ <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
182
183
183
184
@ Override
184
185
Sink <T > opWrapSink (int flags , Sink <T > sink ) {
185
- return new Sink .ChainedReference <T , T >(sink ) {
186
+ return new Sink .ChainedReference <>(sink ) {
186
187
long n = skip ;
187
- long m = limit >= 0 ? limit : Long . MAX_VALUE ;
188
+ long m = normalizedLimit ;
188
189
189
190
@ Override
190
191
public void begin (long size ) {
@@ -226,9 +227,15 @@ public static IntStream makeInt(AbstractPipeline<?, Integer, ?> upstream,
226
227
long skip , long limit ) {
227
228
if (skip < 0 )
228
229
throw new IllegalArgumentException ("Skip must be non-negative: " + skip );
230
+ long normalizedLimit = limit >= 0 ? limit : Long .MAX_VALUE ;
229
231
230
232
return new IntPipeline .StatefulOp <Integer >(upstream , StreamShape .INT_VALUE ,
231
233
flags (limit )) {
234
+ @ Override
235
+ long exactOutputSize (long previousSize ) {
236
+ return calcSize (previousSize , skip , normalizedLimit );
237
+ }
238
+
232
239
Spliterator .OfInt unorderedSkipLimitSpliterator (
233
240
Spliterator .OfInt s , long skip , long limit , long sizeIfKnown ) {
234
241
if (skip <= sizeIfKnown ) {
@@ -291,9 +298,9 @@ <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
291
298
292
299
@ Override
293
300
Sink <Integer > opWrapSink (int flags , Sink <Integer > sink ) {
294
- return new Sink .ChainedInt <Integer >(sink ) {
301
+ return new Sink .ChainedInt <>(sink ) {
295
302
long n = skip ;
296
- long m = limit >= 0 ? limit : Long . MAX_VALUE ;
303
+ long m = normalizedLimit ;
297
304
298
305
@ Override
299
306
public void begin (long size ) {
@@ -335,9 +342,15 @@ public static LongStream makeLong(AbstractPipeline<?, Long, ?> upstream,
335
342
long skip , long limit ) {
336
343
if (skip < 0 )
337
344
throw new IllegalArgumentException ("Skip must be non-negative: " + skip );
345
+ long normalizedLimit = limit >= 0 ? limit : Long .MAX_VALUE ;
338
346
339
347
return new LongPipeline .StatefulOp <Long >(upstream , StreamShape .LONG_VALUE ,
340
348
flags (limit )) {
349
+ @ Override
350
+ long exactOutputSize (long previousSize ) {
351
+ return calcSize (previousSize , skip , normalizedLimit );
352
+ }
353
+
341
354
Spliterator .OfLong unorderedSkipLimitSpliterator (
342
355
Spliterator .OfLong s , long skip , long limit , long sizeIfKnown ) {
343
356
if (skip <= sizeIfKnown ) {
@@ -400,9 +413,9 @@ <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
400
413
401
414
@ Override
402
415
Sink <Long > opWrapSink (int flags , Sink <Long > sink ) {
403
- return new Sink .ChainedLong <Long >(sink ) {
416
+ return new Sink .ChainedLong <>(sink ) {
404
417
long n = skip ;
405
- long m = limit >= 0 ? limit : Long . MAX_VALUE ;
418
+ long m = normalizedLimit ;
406
419
407
420
@ Override
408
421
public void begin (long size ) {
@@ -444,9 +457,15 @@ public static DoubleStream makeDouble(AbstractPipeline<?, Double, ?> upstream,
444
457
long skip , long limit ) {
445
458
if (skip < 0 )
446
459
throw new IllegalArgumentException ("Skip must be non-negative: " + skip );
460
+ long normalizedLimit = limit >= 0 ? limit : Long .MAX_VALUE ;
447
461
448
462
return new DoublePipeline .StatefulOp <Double >(upstream , StreamShape .DOUBLE_VALUE ,
449
463
flags (limit )) {
464
+ @ Override
465
+ long exactOutputSize (long previousSize ) {
466
+ return calcSize (previousSize , skip , normalizedLimit );
467
+ }
468
+
450
469
Spliterator .OfDouble unorderedSkipLimitSpliterator (
451
470
Spliterator .OfDouble s , long skip , long limit , long sizeIfKnown ) {
452
471
if (skip <= sizeIfKnown ) {
@@ -509,9 +528,9 @@ <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
509
528
510
529
@ Override
511
530
Sink <Double > opWrapSink (int flags , Sink <Double > sink ) {
512
- return new Sink .ChainedDouble <Double >(sink ) {
531
+ return new Sink .ChainedDouble <>(sink ) {
513
532
long n = skip ;
514
- long m = limit >= 0 ? limit : Long . MAX_VALUE ;
533
+ long m = normalizedLimit ;
515
534
516
535
@ Override
517
536
public void begin (long size ) {
@@ -541,7 +560,7 @@ public boolean cancellationRequested() {
541
560
}
542
561
543
562
private static int flags (long limit ) {
544
- return StreamOpFlag .NOT_SIZED | ((limit != -1 ) ? StreamOpFlag .IS_SHORT_CIRCUIT : 0 );
563
+ return StreamOpFlag .IS_SIZE_ADJUSTING | ((limit != -1 ) ? StreamOpFlag .IS_SHORT_CIRCUIT : 0 );
545
564
}
546
565
547
566
/**
0 commit comments