diff options
Diffstat (limited to 'src/share/classes/java/util/stream/IntPipeline.java')
-rw-r--r-- | src/share/classes/java/util/stream/IntPipeline.java | 30 |
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(); + } }; } }; |