aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/java/util/stream/IntPipeline.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/java/util/stream/IntPipeline.java')
-rw-r--r--src/share/classes/java/util/stream/IntPipeline.java30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/share/classes/java/util/stream/IntPipeline.java b/src/share/classes/java/util/stream/IntPipeline.java
index 313045f96c..3f809ea4cc 100644
--- a/src/share/classes/java/util/stream/IntPipeline.java
+++ b/src/share/classes/java/util/stream/IntPipeline.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -296,6 +296,12 @@ abstract class IntPipeline<E_IN>
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
+ // true if cancellationRequested() has been called
+ boolean cancellationRequestedCalled;
+
+ // cache the consumer to avoid creation on every accepted element
+ IntConsumer downstreamAsInt = downstream::accept;
+
@Override
public void begin(long size) {
downstream.begin(-1);
@@ -304,11 +310,27 @@ abstract class IntPipeline<E_IN>
@Override
public void accept(int t) {
try (IntStream result = mapper.apply(t)) {
- // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
- if (result != null)
- result.sequential().forEach(i -> downstream.accept(i));
+ if (result != null) {
+ if (!cancellationRequestedCalled) {
+ result.sequential().forEach(downstreamAsInt);
+ }
+ else {
+ Spliterator.OfInt s = result.sequential().spliterator();
+ do { } while (!downstream.cancellationRequested() && s.tryAdvance(downstreamAsInt));
+ }
+ }
}
}
+
+ @Override
+ public boolean cancellationRequested() {
+ // If this method is called then an operation within the stream
+ // pipeline is short-circuiting (see AbstractPipeline.copyInto).
+ // Note that we cannot differentiate between an upstream or
+ // downstream operation
+ cancellationRequestedCalled = true;
+ return downstream.cancellationRequested();
+ }
};
}
};