> On 21 Nov 2016, at 12:46, Martin Buchholz <marti...@google.com> wrote: > > Thanks, Paul. > > + * <p>The stream binds to this bit set when the terminal stream operation > + * commences. If the bit set is modified during that operation then the > + * result is undefined. (Specifically, the spliterator for the stream is > + * <a href="../Spliterator.html#binding"><em>late-binding</em></a>.) > > It looks like the parenthetical remark applies only to the first sentence, > not the second. If so, it should be moved. >
Yes, i will do that, thanks. > The CONCURRENT Spliterators in j.u.c. do not document late-binding, but > probably they should, given the implementation effort we've already done to > make it so. > Late-binding really only applies to spliterators not reporting IMMUTABLE or CONCURRENT. What did you have in mind? > We could have simple tests that create a Spliterator, add elements to the > collection, then verify that they were found in the iteration. > Is there a programmatic way for a test to determine whether a Spliterator > should be late-binding? > See the SpliteratorLateBindingFailFastTest. That could be refactored out as it’s conflating two concepts and is too collection/map focused. Paul. > > > On Mon, Nov 21, 2016 at 12:30 PM, Paul Sandoz <paul.san...@oracle.com> wrote: > Hi, > > Please review this specification clarification for the stream returning > methods on CharSequence and BitStream. Those methods specify that the stream > is late-binding for mutable sequences. > > I think those are the only relevant cases, please tell me if there are more! > > When looking at AbstractStringBuilder i found a bug: > > @Override > public IntStream chars() { > byte[] val = this.value; int count = this.count; byte coder = this.coder; > checkOffset(count, val.length >> coder); > // Reuse String-based spliterator. This requires a supplier to > // capture the value and count when the terminal operation is executed > return StreamSupport.intStream( > () -> coder == LATIN1 ? new StringLatin1.CharsSpliterator(val, 0, > count, 0) > : new StringUTF16.CharsSpliterator(val, 0, > count, 0), > Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED, > false); > } > > The returned stream is not late-binding since it captures state as local > variables. That was an oversight missed in review when the compact string > changes were pushed. I will file an issue and fix it (including tests). > > Paul. > > > diff -r a11577c64a1d src/java.base/share/classes/java/lang/CharSequence.java > --- a/src/java.base/share/classes/java/lang/CharSequence.java Mon Nov 21 > 10:50:01 2016 -0800 > +++ b/src/java.base/share/classes/java/lang/CharSequence.java Mon Nov 21 > 12:17:08 2016 -0800 > @@ -121,8 +121,11 @@ > * href="{@docRoot}/java/lang/Character.html#unicode">surrogate code > * point</a> is passed through uninterpreted. > * > - * <p>If the sequence is mutated while the stream is being read, the > - * result is undefined. > + * <p>The stream binds to this sequence when the terminal stream > operation > + * commences. If the sequence is modified during that operation then the > + * result is undefined. (Specifically, for mutable sequences the > + * spliterator for the stream is > + * <a href="../Spliterator.html#binding"><em>late-binding</em></a>.) > * > * @return an IntStream of char values from this sequence > * @since 1.8 > @@ -168,8 +171,11 @@ > * unpaired surrogates, and undefined code units, are zero-extended to > * {@code int} values which are then passed to the stream. > * > - * <p>If the sequence is mutated while the stream is being read, the > result > - * is undefined. > + * <p>The stream binds to this sequence when the terminal stream > operation > + * commences. If the sequence is modified during that operation then the > + * result is undefined. (Specifically, for mutable sequences the > + * spliterator for the stream is > + * <a href="../Spliterator.html#binding"><em>late-binding</em></a>.) > * > * @return an IntStream of Unicode code points from this sequence > * @since 1.8 > diff -r a11577c64a1d src/java.base/share/classes/java/util/BitSet.java > --- a/src/java.base/share/classes/java/util/BitSet.java Mon Nov 21 10:50:01 > 2016 -0800 > +++ b/src/java.base/share/classes/java/util/BitSet.java Mon Nov 21 12:17:08 > 2016 -0800 > @@ -1210,9 +1210,10 @@ > * is the number of bits in the set state, equal to the value > * returned by the {@link #cardinality()} method. > * > - * <p>The bit set must remain constant during the execution of the > - * terminal stream operation. Otherwise, the result of the terminal > - * stream operation is undefined. > + * <p>The stream binds to this bit set when the terminal stream operation > + * commences. If the bit set is modified during that operation then the > + * result is undefined. (Specifically, the spliterator for the stream is > + * <a href="../Spliterator.html#binding"><em>late-binding</em></a>.) > * > * @return a stream of integers representing set indices > * @since 1.8 >