<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
If you have a look at my benchmarks, currently I only fuse gather(…) + collect(…) (so in this case not allMatch).<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="Signature">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Cheers,<br>
√</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b><br>
</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>Viktor Klang</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Monday, 29 January 2024 10:42<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</font>
<div> </div>
</div>
<div>
<div style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">
<div><br>
</div>
<div><br>
</div>
<hr id="x_zwchr" data-marker="__DIVIDER__">
<div data-marker="__HEADERS__">
<blockquote style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<b>From: </b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br>
<b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.java.net>, "Paul Sandoz" <psandoz@openjdk.java.net><br>
<b>Sent: </b>Monday, January 29, 2024 8:41:21 AM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</blockquote>
</div>
<div><style style="display:none">
<!--
p
        {margin-top:0;
        margin-bottom:0}
-->
</style></div>
<div data-marker="__QUOTED_TEXT__">
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div class="x_elementToProof" data-mce-style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
For monomorphic benches it is likely not going to make any difference as the JIT will likely do the same thing, also, the bench might be dominated by other factors.</div>
</blockquote>
<div><br>
</div>
<div>For me, it's more that lambdas may be able to use late-inlining (inlining after the return value of an invokedynamic is known as constant) so results may be better than it should.<br data-mce-bogus="1">
</div>
<div>Here is an example,<br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
<div>
<div data-mce-style="background-color: #ffffff; color: #080808;" style="background-color:#ffffff; color:#080808">
<pre data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt"><span data-mce-style="color: #9e880d;" style="color:#9e880d">@Benchmark<br></span><span data-mce-style="color: #0033b3;" style="color:#0033b3">public boolean </span><span data-mce-style="color: #00627a;" style="color:#00627a">map_allMatch_repeat_3</span>() {<br>  <span data-mce-style="color: #0033b3;" style="color:#0033b3">return </span><span data-mce-style="color: #871094;" style="color:#871094">integers</span>.stream()<br>    .map(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">1</span>)<br>    .map(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">2</span>)<br>    .map(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">3</span>)<br>    .allMatch(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>< <span data-mce-style="color: #1750eb;" style="color:#1750eb">1_000_000</span>);<br>}<br><span data-mce-style="color: #9e880d;" style="color:#9e880d">@Benchmark<br></span><span data-mce-style="color: #0033b3;" style="color:#0033b3">public boolean </span><span data-mce-style="color: #00627a;" style="color:#00627a">mapToInt_allMatch_repeat_3</span>() {<br>  <span data-mce-style="color: #0033b3;" style="color:#0033b3">return </span><span data-mce-style="color: #871094;" style="color:#871094">integers</span>.stream()<br>    .mapToInt(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">1</span>)<br>    .map(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">2</span>)<br>    .map(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">3</span>)<br>    .allMatch(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>< <span data-mce-style="color: #1750eb;" style="color:#1750eb">1_000_000</span>);<br>}<br><span data-mce-style="color: #9e880d;" style="color:#9e880d">@Benchmark<br></span><span data-mce-style="color: #0033b3;" style="color:#0033b3">public boolean </span><span data-mce-style="color: #00627a;" style="color:#00627a">gatherer_map_allMatch_repeat_3</span>() {<br>  // Gatherer with lambdas<br>  <span data-mce-style="color: #0033b3;" style="color:#0033b3">return </span><span data-mce-style="color: #871094;" style="color:#871094">integers</span>.stream()<br>    .gather(<span data-mce-style="color: #00627a; font-style: italic;" style="color:#00627a; font-style:italic">map</span>(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">1</span>))<br>    .gather(<span data-mce-style="color: #00627a; font-style: italic;" style="color:#00627a; font-style:italic">map</span>(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">2</span>))<br>    .gather(<span data-mce-style="color: #00627a; font-style: italic;" style="color:#00627a; font-style:italic">map</span>(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">3</span>))<br>    .allMatch(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>< <span data-mce-style="color: #1750eb;" style="color:#1750eb">1_000_000</span>);<br>}<br><span data-mce-style="color: #9e880d;" style="color:#9e880d">@Benchmark<br></span><span data-mce-style="color: #0033b3;" style="color:#0033b3">public boolean </span><span data-mce-style="color: #00627a;" style="color:#00627a">gatherer_mapsublcass_allMatch_repeat_3</span>() {<br>  // Gatherer as subclass<br>  <span data-mce-style="color: #0033b3;" style="color:#0033b3">return </span><span data-mce-style="color: #871094;" style="color:#871094">integers</span>.stream()<br>    .gather(<span data-mce-style="color: #00627a; font-style: italic;" style="color:#00627a; font-style:italic">mapSubclass</span>(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">1</span>))<br>    .gather(<span data-mce-style="color: #00627a; font-style: italic;" style="color:#00627a; font-style:italic">mapSubclass</span>(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">2</span>))<br>    .gather(<span data-mce-style="color: #00627a; font-style: italic;" style="color:#00627a; font-style:italic">mapSubclass</span>(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>+ <span data-mce-style="color: #1750eb;" style="color:#1750eb">3</span>))<br>    .allMatch(<span data-mce-style="color: #000000;" style="color:#000000">v </span>-> <span data-mce-style="color: #000000;" style="color:#000000">v </span>< <span data-mce-style="color: #1750eb;" style="color:#1750eb">1_000_000</span>);<br>}</pre>
</div>
</div>
<div><br>
</div>
<div>With 10 second warmups,</div>
<pre>Benchmark                                                    Mode  Cnt     Score     Error  Units<br>MapGathererBenchmark.gatherer_map_allMatch_repeat_3          avgt    5  3359.336 ± 137.314  us/op<br>MapGathererBenchmark.gatherer_mapsublcass_allMatch_repeat_3  avgt    5  3755.388 ±  50.858  us/op<br>MapGathererBenchmark.mapToInt_allMatch_repeat_3              avgt    5   559.891 ±   1.542  us/op<br>MapGathererBenchmark.map_allMatch_repeat_3                   avgt    5  1642.167 ±   5.804  us/op<br><br></pre>
<p>Also, I wonder if fusing is not an anti-pattern for gatherers/streams, c2 take a loooong time to come with as code wich is not very fast.<br>
<br>
</p>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<pre class="x_elementToProof" data-mce-style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</pre>
<div id="x_Signature">
<div data-mce-style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
</div>
</blockquote>
<div><br>
</div>
<div>Rémi<br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div id="x_Signature">
<div data-mce-style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-size: 11pt; color: #000000; font-family: Calibri, sans-serif;" style="font-size:11pt; color:#000000; font-family:Calibri,sans-serif"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Thursday, 25 January 2024 14:57<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div>
<div data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">
<div><br>
</div>
<div><br>
</div>
<hr id="x_x_zwchr">
<div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<b>From: </b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br>
<b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.java.net>, "Paul Sandoz" <psandoz@openjdk.java.net><br>
<b>Sent: </b>Wednesday, January 24, 2024 2:45:15 PM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</blockquote>
</div>
<div><br>
</div>
<div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div class="x_x_elementToProof"><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">As
 a (related) side-note, the ability to implement the interface directly has a significant benefit to being able to have tighter control on efficiency/performance as well as behavior under composition, here are some examples:
</span><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><a href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/test/micro/org/openjdk/bench/java/util/stream/ops/ref/BenchmarkGathererImpls.java*L113__;Iw!!ACWV5N9M2RV99hQ!MFknMPf08p9oLTHtcHIIljRuma7ct6sarJRqTWKzmBiiGJBjtDEZsgGrkDbwxLl1NhEwVwz-RhHv3h3t54rw$" id="LPlnk753508" target="_blank" rel="noopener" data-mce-href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/test/micro/org/openjdk/bench/java/util/stream/ops/ref/BenchmarkGathererImpls.java*L113__;Iw!!ACWV5N9M2RV99hQ!MFknMPf08p9oLTHtcHIIljRuma7ct6sarJRqTWKzmBiiGJBjtDEZsgGrkDbwxLl1NhEwVwz-RhHv3h3t54rw$">https://github.com/openjdk/jdk/blob/master/test/micro/org/openjdk/bench/java/util/stream/ops/ref/BenchmarkGathererImpls.java#L113</a></span><br>
</div>
<div class="x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
</blockquote>
<div><br>
</div>
<div>I've not seen any differences in term of performance:<br>
</div>
<pre><span data-mce-style="font-family: lucida console,sans-serif;" style="font-family:lucida console,sans-serif">MapGathererBenchmark.gatherer_map_sum                avgt    5  546.058 ± 4.224  us/op</span><br><span data-mce-style="font-family: lucida console,sans-serif;" style="font-family:lucida console,sans-serif">MapGathererBenchmark.gatherer_mapsublcass_sum  avgt    5  546.391 ± 1.508  us/op</span><br></pre>
<div>but yes, being able to override andThen() is important.</div>
<div><br>
</div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div class="x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div id="x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>Rémi<br>
</div>
<div><br>
</div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div id="x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-size: 11pt; color: #000000; font-family: Calibri, sans-serif;" style="font-size:11pt; color:#000000; font-family:Calibri,sans-serif"><b>From:</b> core-libs-dev <core-libs-dev-retn@openjdk.org>
 on behalf of Viktor Klang <viktor.klang@oracle.com><br>
<b>Sent:</b> Wednesday, 24 January 2024 14:34<br>
<b>To:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> Re: Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div dir="ltr">
<div class="x_x_x_elementToProof"><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">Presuming
 that you mean mutating the Gatherer such that its behavior isn't stable, the difference (at least to me) is that creating such a mutable Gatherer would violate the specification of Gatherer:
</span><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><a href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherer.java*L63__;Iw!!ACWV5N9M2RV99hQ!MFknMPf08p9oLTHtcHIIljRuma7ct6sarJRqTWKzmBiiGJBjtDEZsgGrkDbwxLl1NhEwVwz-RhHv3uXOerfv$" id="LPlnk633725" target="_blank" rel="noopener" data-mce-href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherer.java*L63__;Iw!!ACWV5N9M2RV99hQ!MFknMPf08p9oLTHtcHIIljRuma7ct6sarJRqTWKzmBiiGJBjtDEZsgGrkDbwxLl1NhEwVwz-RhHv3uXOerfv$">https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherer.java#L63</a></span><br>
</div>
<div class="x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div class="x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div class="x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div id="x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_x_x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-size: 11pt; color: #000000; font-family: Calibri, sans-serif;" style="font-size:11pt; color:#000000; font-family:Calibri,sans-serif"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Tuesday, 23 January 2024 21:04<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div>
<div data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">
<div><br>
</div>
<div><br>
</div>
<hr id="x_x_x_x_zwchr">
<div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<b>From: </b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br>
<b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.java.net>, "Paul Sandoz" <psandoz@openjdk.java.net><br>
<b>Sent: </b>Monday, January 22, 2024 10:06:27 PM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</blockquote>
</div>
<div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div class="x_x_x_x_elementToProof"><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-right: 0px; margin-left: 0.8ex; padding-left: 1ex; border-left: 3px solid #c8c8c8;" style="margin-right:0px; margin-left:0.8ex; padding-left:1ex; border-left:3px solid #c8c8c8">
<div class="x_x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
The flags are in sync with the implementation because the only way to create a Gatherer if through the factory methods and those factory methods (and only them) compute the proper combination of SEQUENTIAL | STATELESS | GREEDY. A user should not be able to
 set those flags. Only the flags KEEP_* are settable by a user.</div>
</blockquote>
<div class="x_x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
But I presume this also requires to have a `int characteristics()`-method on the Gatherer interfacewhich means that users who are not using the factory methods will have full possibility of not only returning the flags, but returning any int.</div>
</blockquote>
<div><br>
</div>
<div>The current implementation suffers the same kind of issue, it's easy to write a mutable Gatherer and change the functions after creation, worst, right in the middle of a call to stream.gather(...).<br>
</div>
<div><br>
</div>
<div>Perhaps the Gatherer interface should be sealed ? We did not have that option during the 1.8 timeframe, when the Collector API was created.<br>
</div>
<div><br>
</div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div class="x_x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<span data-mce-style="color: #000000;" style="color:#000000"><br>
</span></div>
<div class="x_x_x_x_elementToProof"><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-right: 0px; margin-left: 0.8ex; padding-left: 1ex; border-left: 3px solid #c8c8c8;" style="margin-right:0px; margin-left:0.8ex; padding-left:1ex; border-left:3px solid #c8c8c8">
<div class="x_x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
The stream implementation has a whole mechanism in place to propagate/preverse flags like SIZED, DISTINCT or SORTED. For me, discussing about the merit of this mechanism seems a little off topic.  I would prefer the Gatherer to be a good citizen and works seemlessly
 with the other intermediary operations.</div>
</blockquote>
<div class="x_x_x_x_elementToProof"><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">I
 can see where you're coming from here, but to me, adding API surface needs to pull its weight.</span></div>
<div class="x_x_x_x_elementToProof"><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">In
 this case I wasn't convinced that it did, hence we're having this conversation. <span id="x_x_x_x_🙂">
\uD83D\uDE42</span><br>
</span></div>
<div class="x_x_x_x_elementToProof"><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">Cheers,<br>
√</span></div>
</blockquote>
<div><br>
</div>
<div>regards,<br>
</div>
<div>Rémi<br>
</div>
<div><br>
</div>
<blockquote data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" style="border-left:2px solid #1010FF; margin-left:5px; padding-left:5px; color:#000; font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div><span data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000"><b><br>
</b></span></div>
<div><span data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000"><b>Viktor Klang</b></span></div>
<div><span data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">Software Architect, Java Platform Group<br>
Oracle</span></div>
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div data-mce-style="direction: ltr;" style="direction:ltr"><span data-mce-style="font-family: Calibri,sans-serif; font-size: 11pt; color: #000000;" style="font-family:Calibri,sans-serif; font-size:11pt; color:#000000"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Monday, 22 January 2024 19:56<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<hr>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><b>From:
</b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br>
<b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.java.net>, "Paul Sandoz" <psandoz@openjdk.java.net><br>
<b>Sent: </b>Monday, January 22, 2024 4:22:11 PM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</span></blockquote>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">Hi
 Rémi,</span></div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Hello,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">For
 instance, stateless is neither recessive nor dominant, since the composition of two stateless operations is only ever stateless if they both are greedy as well:
<a href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherers.java*L588__;Iw!!ACWV5N9M2RV99hQ!Lm52jd6kovd5t-cmrqqSLiRcIajBGXLxh85LO3eeiL6UxbKZuNPcUnO6z2i0FzMEoNr7U-cOBuWPCjo57FVW$" id="OWA0b03fd05-7fe2-6c29-b6f7-9f3306789017" class="x_x_x_x_OWAAutoLink" target="_blank" rel="noopener" data-mce-href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherers.java*L588__;Iw!!ACWV5N9M2RV99hQ!Lm52jd6kovd5t-cmrqqSLiRcIajBGXLxh85LO3eeiL6UxbKZuNPcUnO6z2i0FzMEoNr7U-cOBuWPCjo57FVW$">
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherers.java#L588</a></span><br>
</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Okay, so choosing SEQUENTIAL vs PARALELLIZABLE is not that important given that
 the combination is ad-hoc, reflecting the characterristics is enough.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">So
 even if making it represented as ints (more like Spliterator, rather than Collector) makes things faster, it's still both work to track, propagate, and also becomes a side-channel that needs to remain in sync with the actual implementation of the logic.</span></div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">The flags are in sync with the implementation because the only way to create
 a Gatherer if through the factory methods and those factory methods (and only them) compute the proper combination of SEQUENTIAL | STATELESS | GREEDY. A user should not be able to set those flags. Only the flags KEEP_* are settable by a user.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">One
 could argue that logic such as: someCollection.stream().map(…).count() is a performance bug/inefficiency in an of itself as it would be faster to do someCollection.size().</span></div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">The stream implementation has a whole mechanism in place to propagate/preverse
 flags like SIZED, DISTINCT or SORTED. For me, discussing about the merit of this mechanism seems a little off topic.  I would prefer the Gatherer to be a good citizen and works seemlessly with the other intermediary operations.</span></div>
<div class="x_x_x_x_elementToProof"><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div class="x_x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div class="x_x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div class="x_x_x_x_elementToProof" data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div id="x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_x_x_x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-family: Calibri,sans-serif; font-size: 11pt; color: #000000;" style="font-family:Calibri,sans-serif; font-size:11pt; color:#000000"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Monday, 22 January 2024 19:56<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<hr>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><b>From:
</b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br>
<b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.java.net>, "Paul Sandoz" <psandoz@openjdk.java.net><br>
<b>Sent: </b>Monday, January 22, 2024 4:22:11 PM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</span></blockquote>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">Hi
 Rémi,</span></div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Hello,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">For
 instance, stateless is neither recessive nor dominant, since the composition of two stateless operations is only ever stateless if they both are greedy as well:
<a href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherers.java*L588__;Iw!!ACWV5N9M2RV99hQ!Lm52jd6kovd5t-cmrqqSLiRcIajBGXLxh85LO3eeiL6UxbKZuNPcUnO6z2i0FzMEoNr7U-cOBuWPCjo57FVW$" id="OWA28d62600-62df-f108-f943-a3c7e4d8d976" class="x_x_x_x_OWAAutoLink" target="_blank" rel="noopener" data-mce-href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherers.java*L588__;Iw!!ACWV5N9M2RV99hQ!Lm52jd6kovd5t-cmrqqSLiRcIajBGXLxh85LO3eeiL6UxbKZuNPcUnO6z2i0FzMEoNr7U-cOBuWPCjo57FVW$">
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherers.java#L588</a></span><br>
</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Okay, so choosing SEQUENTIAL vs PARALELLIZABLE is not that important given that
 the combination is ad-hoc, reflecting the characterristics is enough.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
So even if making it represented as ints (more like Spliterator, rather than Collector) makes things faster, it's still both work to track, propagate, and also becomes a side-channel that needs to remain in sync with the actual implementation of the logic.</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">The flags are in sync with the implementation because the only way to create
 a Gatherer if through the factory methods and those factory methods (and only them) compute the proper combination of SEQUENTIAL | STATELESS | GREEDY. A user should not be able to set those flags. Only the flags KEEP_* are settable by a user.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
One could argue that logic such as: someCollection.stream().map(…).count() is a performance bug/inefficiency in an of itself as it would be faster to do someCollection.size().</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">The stream implementation has a whole mechanism in place to propagate/preverse flags
 like SIZED, DISTINCT or SORTED. For me, discussing about the merit of this mechanism seems a little off topic.  I would prefer the Gatherer to be a good citizen and works seemlessly with the other intermediary operations.<br>
</span>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div id="x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">regards,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Rémi</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div id="x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_x_x_x_x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-family: Calibri,sans-serif; font-size: 11pt; color: #000000;" style="font-family:Calibri,sans-serif; font-size:11pt; color:#000000"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Saturday, 20 January 2024 17:40<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<hr>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><b>From:
</b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br>
<b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.java.net>, "Paul Sandoz" <psandoz@openjdk.java.net><br>
<b>Sent: </b>Thursday, January 18, 2024 5:14:38 PM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</span></blockquote>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<blockquote data-mce-style="margin-right: 0px; margin-left: 0.8ex; padding-left: 1ex; border-left: 3px solid #c8c8c8;" style="margin-right:0px; margin-left:0.8ex; padding-left:1ex; border-left:3px solid #c8c8c8">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
And for A.andThen(B), A.flags & B.flags should work, the stream is sorted if both gatherers keep it sorted.</div>
</blockquote>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
That is unfortunately not the case. That would presume that you can implement the composition such that it can preserve all the common flags. Some flags could be "dominant" and some "recessive" to use genetics nomenclature.</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Some flags of the stream pipeline are "recessive", mainly SHORT_CIRCUIT, but
 not the characteristics of the Gatherer which can have the corresponding "dominant" flag, GREEDY, in this case.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">And the same for sequential, the flag should be PARALELIZABLE and not SEQUENTIAL.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">The idea is that the Gatherer characteristics can have the same bit set at the
 same position as the stream op flags (as defined by StreamOpFlag).</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">So KEEP_DISTINCT is in position 0, KEEP_SORTED in in position 2 and KEEP_SIZED
 is in position 3.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">For GREEDY, we use the same position as SHORT_CIRCUIT and we will flip the bit
 (using XOR) when we want to extract the stream op flags from the characteristics</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">All the factory methods call the generic of() with a combination of PARALELIZABLE
 and STATELESS and the user can adds the characteristics GREEDY, KEEP_DISTINCT, KEEP_SORTED and KEEP_SIZED (otherwise an exception should be raised).</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">In StreamOpFlag, there are two unused positions (14 and 15), that's perfect for
 our two new states PARALELIZABLE and STATELESS, so no problem here (technically we can also reuse positions of the Spliterator characteristic given that those flags are masked before being sent to the GathererOp super constructor).</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">The way to transform a Gatherer characteristics op to a stream flags op is to
 flip the bits corresponding to SHORT_CIRCUIT, add the highter bit of all flags but SHORT-CIRCUIT (because stream op flags are encoded using 2 bits) and mask to only retain SHORT_CIRCUIT, KEEP_DISTINCT, KEEP_SORTED and KEEP_SIZED.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div data-mce-style="background-color: #ffffff;" style="background-color:#ffffff">
<div><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #00627a;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#00627a">toOpFlags</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">^
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SHORT_CIRCUIT_MASK</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 | </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>HIGHER_BITS</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 & </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STREAM_OP_MASK</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
}</span></div>
</div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">see below for a full script.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<blockquote data-mce-style="margin-right: 0px; margin-left: 0.8ex; padding-left: 1ex; border-left: 3px solid #c8c8c8;" style="margin-right:0px; margin-left:0.8ex; padding-left:1ex; border-left:3px solid #c8c8c8">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
I suppose that if those flags already exist, it's because they have a purpose and i do not understand how it can make the other operations slower.</div>
</blockquote>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
Extra invocations, extra storage, and extra composition overhead is not free. Since Stream is one-shot you need to include the construction cost with the execution cost. For something like an empty Stream construction cost scan be 90+% of the total costs.</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">If you create a Gatherer, the characteristics is a constant (so the validity
 check is removed, it's just a mask and a test) so the result of calling toOpFlags() is a constant too.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">If the factory method is not inlined, the cost is 3 bitwise operations which
 is I believe faster than the "instanceof Greedy" used in the current code.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div id="x_x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">regards,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Rémi</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">---</span></div>
<div data-mce-style="background-color: #ffffff;" style="background-color:#ffffff">
<div><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public class
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">GathererFlag
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">{<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #8c8c8c;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#8c8c8c"><i>// cut and paste from StreamOpFlag<br>
/**<br>
* The bit pattern for setting/injecting a flag.<br>
*/<br>
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">0b01</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #8c8c8c;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#8c8c8c"><i>/**<br>
* The bit pattern for clearing a flag.<br>
*/<br>
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>CLEAR_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">0b10</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #8c8c8c;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#8c8c8c"><i>/**<br>
* The bit pattern for preserving a flag.<br>
*/<br>
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PRESERVE_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">0b11</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #00627a;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#00627a">position</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">opFlagSet</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">Integer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.<i>numberOfTrailingZeros</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">opFlagSet</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 >> </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
}<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>DISTINCT_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
<i>position</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">StreamOpFlag</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>IS_DISTINCT</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SORTED_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
<i>position</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">StreamOpFlag</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>IS_SORTED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SIZED_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
<i>position</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">StreamOpFlag</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>IS_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SHORT_CIRCUIT_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
<i>position</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">StreamOpFlag</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>IS_SHORT_CIRCUIT</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">14</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PARELLIZABLE_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">15</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PARELLIZABLE
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><< (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PARELLIZABLE_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><<
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><< (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><<
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>GREEDY
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><< (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SHORT_CIRCUIT_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><<
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><< (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>DISTINCT_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><<
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SORTED
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><< (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SORTED_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><<
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><< (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SIZED_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><<
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SHORT_CIRCUIT_MASK
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SET_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><< (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SHORT_CIRCUIT_POSITION
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808"><<
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #8c8c8c;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#8c8c8c"><i>// no GREEDY here<br>
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>HIGHER_BITS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">= (</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PARELLIZABLE
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SORTED
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 << </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">private static final int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STREAM_OP_MASK
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=<br>
((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>GREEDY
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SORTED
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 << </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #1750eb;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#1750eb">1</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 |<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>GREEDY
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SORTED
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">String
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #00627a;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#00627a">toString</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">Stream</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.<i>of</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)<br>
.<</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">String</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">>mapMulti((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">f</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">,
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">consumer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 -> {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">f
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">&
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PARELLIZABLE</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 == </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PARELLIZABLE</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">consumer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.accept(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"PARELLIZABLE"</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">f
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">&
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 == </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">consumer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.accept(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"STATELESS"</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">f
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">&
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>GREEDY</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 == </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>GREEDY</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">consumer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.accept(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"GREEDY"</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">f
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">&
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 == </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">consumer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.accept(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"KEEP_DISTINCT"</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">f
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">&
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SORTED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 == </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SORTED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">consumer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.accept(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"KEEP_SORTED"</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">f
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">&
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 == </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">consumer</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.accept(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"KEEP_SIZED"</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">);<br>
}<br>
})<br>
.collect(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">Collectors</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.<i>joining</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">",
 "</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">));<br>
}<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #00627a;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#00627a">toOpFlags</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">((</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">^
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>SHORT_CIRCUIT_MASK</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 | </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>HIGHER_BITS</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 & </span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STREAM_OP_MASK</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
}<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">public static
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">String
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #00627a;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#00627a">toOpFlagsString</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">int
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">opFlags</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">Arrays</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.<i>stream</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">StreamOpFlag</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.<i>values</i>())<br>
.map(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">-> {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.isPreserved(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #851691;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#851691">opFlags</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">))
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"preserved "
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">+
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.isCleared(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #851691;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#851691">opFlags</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">))
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"cleared "
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">+
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">if
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.isKnown(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #851691;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#851691">opFlags</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">))
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"set "
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">+
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
}<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">return
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">"?? "
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">+
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">op</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
})<br>
.collect(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">Collectors</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.<i>joining</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #067d17;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#067d17">",
 "</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">));<br>
}<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">void
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #00627a;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#00627a">main</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">()
 {<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">var
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>PARELLIZABLE
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>GREEDY
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SORTED
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">System</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>out</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.println(<i>toOpFlagsString</i>(<i>toOpFlags</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)));<br>
<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #0033b3;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#0033b3">var
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics2
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">=
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>STATELESS
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_DISTINCT
</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">|
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>KEEP_SIZED</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">;<br>
</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">System</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #871094;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#871094"><i>out</i></span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">.println(<i>toOpFlagsString</i>(<i>toOpFlags</i>(</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #000000;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#000000">characteristics2</span><span data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt; color: #080808;" style="font-family:'JetBrains Mono',monospace; font-size:9.8pt; color:#080808">)));<br>
}<br>
}</span></div>
</div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div id="x_x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_x_x_x_x_x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-family: Calibri,sans-serif; font-size: 11pt; color: #000000;" style="font-family:Calibri,sans-serif; font-size:11pt; color:#000000"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Thursday, 18 January 2024 16:17<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<hr>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><b>From:
</b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br>
<b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.java.net>, "Paul Sandoz" <psandoz@openjdk.java.net><br>
<b>Sent: </b>Thursday, January 18, 2024 3:36:07 PM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</span></blockquote>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
I suspect that it is a rather slippery slope, once KEEP-flags are added, then others will want to be able to have INJECT-flags, and then people might have different opinions w.r.t. the default should be to clear all flags etc.</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
And that's even before one looks at the composition-part of it, what are the flags for A.andThen(B)? (then extrapolate to N compositions and the available set of flags always approaches 0)</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
I spent quite a bit of time on this and in the end tracking all this info, and making sure that the flags of implementations correspond to the actual behavior, just ended up costing performance for most streams and introduced an extra dimension to creation
 and maintenance which I had a hard time justifying.</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">It can be a slippery slope if we were designing from the ground up but the stream
 implementation already exists and SORTED, DISTINCT and SIZED are the flags that are already tracked by the current implementation.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Currently only SHORT_CIRCUIT is set (if not greedy),</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">see
<a href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/GathererOp.java*L209__;Iw!!ACWV5N9M2RV99hQ!PhMxqlDzLWPRuwYc7ECRKNPVs0BtnoE-RdT-Jdkng7S-iFuERAHYcWvJ-OMKGLrkPdSrUl3xj1R9ypyeqeWI$" id="OWA1de4dae1-4def-061e-101c-71b3a0489acb" class="x_x_x_x_x_x_OWAAutoLink" target="_blank" rel="noopener" data-mce-href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/GathererOp.java*L209__;Iw!!ACWV5N9M2RV99hQ!PhMxqlDzLWPRuwYc7ECRKNPVs0BtnoE-RdT-Jdkng7S-iFuERAHYcWvJ-OMKGLrkPdSrUl3xj1R9ypyeqeWI$">
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/GathererOp.java#L209</a></span><br>
</div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">And for A.andThen(B), A.flags & B.flags should work, the stream is sorted if
 both gatherers keep it sorted.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
Making specific, rare, combinations of operations faster at the expense of making 99% of all others slower is a hard pill for most to swallow.</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">I suppose that if those flags already exist, it's because they have a purpose
 and i do not understand how it can make the other operations slower.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div id="x_x_x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">regards,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Rémi</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div id="x_x_x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_x_x_x_x_x_x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-family: Calibri,sans-serif; font-size: 11pt; color: #000000;" style="font-family:Calibri,sans-serif; font-size:11pt; color:#000000"><b>From:</b> forax@univ-mlv.fr <forax@univ-mlv.fr><br>
<b>Sent:</b> Thursday, 18 January 2024 10:28<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.java.net>; Paul Sandoz <psandoz@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<hr>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><b>From:
</b>"Viktor Klang" <viktor.klang@oracle.com><br>
<b>To: </b>"Remi Forax" <forax@univ-mlv.fr>, "core-libs-dev" <core-libs-dev@openjdk.java.net><br>
<b>Sent: </b>Wednesday, January 17, 2024 8:48:07 PM<br>
<b>Subject: </b>Re: Gatherer: spliterator characteristics are not propagated<br>
</span></blockquote>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
Hi Rémi,</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div><span data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">You
 can find some of my benches here: <a href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/tree/master/test/micro/org/openjdk/bench/java/util/stream/ops/ref__;!!ACWV5N9M2RV99hQ!JJy6F9NoL6wKZQK5158up_fTRvH8X7F6JK8T7Euuf8vzbSQbr23eWa9S_yb61ksONVrLrdesCF_au5zyje2l$" id="OWA64353d4a-525b-69fa-1b1c-136f7ddf895a" class="x_x_x_x_x_x_OWAAutoLink" target="_blank" rel="noopener" data-mce-href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/tree/master/test/micro/org/openjdk/bench/java/util/stream/ops/ref__;!!ACWV5N9M2RV99hQ!JJy6F9NoL6wKZQK5158up_fTRvH8X7F6JK8T7Euuf8vzbSQbr23eWa9S_yb61ksONVrLrdesCF_au5zyje2l$">
https://github.com/openjdk/jdk/tree/master/test/micro/org/openjdk/bench/java/util/stream/ops/ref</a></span><br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
Initially I had Characteristics such as ORDERED etc on Gatherer but it just didn't end up worth it when looking at the bench results over a wide array of stream sizes and number of operations.</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">I think there are 3 gatherer characteristics that make sense: KEEP_SORTED, KEEP_DISTINCT
 and KEEP_SIZED,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">all of them say that if the stream was sorted/distinct/sized then the stream
 returned by a call to gather() is still sorted (with the same comparator), distinct or sized.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">As examples, map() is KEEP_SIZED, filter() is KEEP_SORTED | KEEP_DISTINCT and
 windowFixed is KEEP_DISTINCT.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">[CC Paul, so he can correct me if i'm saying something stupid]</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Now for the benchmarks, it depends what you want to measure, benchmarking streams
 is tricky. This is what i know about benchmarking streams.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">First, the JIT has two ways to profile types at runtime,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Either a method takes a function as parameter</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">  void map(Function function) {</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">    function.apply(...)</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">  }</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">and when map is called with a subtype of Function, the JIT will propagate the
 exact type when map is inlined,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Or a method use a field</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">  class Op {</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">    Function function;</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">    void map() {</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">       function.apply(...)</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">    }</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">  }</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">in that case, the VM records the profile of function.apply() and if there are
 more than two different profiles, the VM declare profile poluttion and do not try to optimize.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">The Stream implementation tries very hard to use only parameters instead of fields,
 that's why it does not use classical Iterator that are pull iterator (a filter iterator requires a field) but a Spliterator which is a push iterator, the element is sent as parameter of the consumer.That's also why collect does not use the builder pattern
 (that accumulate values in fields) but a Collector that publish the functions to be called as parameter.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Obvisously, this is more complex than that, a Collector stores the functions
 in fields so it should not work well but the implementation uses a record that plays well with escape analysis. Escape analysis see the fields of an instance as parameters so the functions of a Collector are correctly propagated (if the escape analysis works).
 And lambdas are using invokedynamic, and the VM tries really hard to inline invokedynamic, so lambdas (that captures value or not) are routinely fully inlined with the intermediate operation of a stream.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">In your tests, i've not seen comparaisons between an existing method like map()
 or filter() followed by a sorted()/distinct()/count()/toList(), i.e. operations where the characteristics KEEP_* have an impact and their equivalent using a Gatherer.</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div id="x_x_x_x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Cheers,<br>
√</div>
</div>
</blockquote>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">regards,</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000">Rémi</span></div>
<div><span data-mce-style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:#000000"><br>
</span></div>
<blockquote data-mce-style="margin-left: 5px; padding-left: 5px; border-left: 2px solid #1010ff;" style="margin-left:5px; padding-left:5px; border-left:2px solid #1010ff">
<div id="x_x_x_x_x_x_x_x_Signature">
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<br>
</div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b><br>
</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
<b>Viktor Klang</b></div>
<div data-mce-style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:#000000">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<hr data-mce-style="display: inline-block; width: 98%;" style="display:inline-block; width:98%">
<div id="x_x_x_x_x_x_x_x_divRplyFwdMsg" dir="ltr"><span data-mce-style="font-family: Calibri,sans-serif; font-size: 11pt; color: #000000;" style="font-family:Calibri,sans-serif; font-size:11pt; color:#000000"><b>From:</b> core-libs-dev <core-libs-dev-retn@openjdk.org>
 on behalf of Remi Forax <forax@univ-mlv.fr><br>
<b>Sent:</b> Wednesday, 17 January 2024 16:48<br>
<b>To:</b> core-libs-dev <core-libs-dev@openjdk.java.net><br>
<b>Subject:</b> Gatherer: spliterator characteristics are not propagated</span>
<div> </div>
</div>
<div><span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 11pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:11pt; color:#000000">While doing some benchmarking of the Gatherer API, i've found that the characteristics
 of the spliterator was not propagated by the method Stream.gather() making the stream slower than it should.<br>
<br>
As an example, there is no way when reimplementing map() using a Gatherer to say that this intermediate operation keep the size, which is important if the terminal operation is toList() because if the size is known, toList() will presize the List and avoid
 the creation of an intermediary ArrayList.<br>
<br>
See <a href="https://urldefense.com/v3/__https://github.com/forax/we_are_all_to_gather/blob/master/src/main/java/com/gihtub/forax/wearealltogather/bench/MapGathererBenchmark.java__;!!ACWV5N9M2RV99hQ!JJy6F9NoL6wKZQK5158up_fTRvH8X7F6JK8T7Euuf8vzbSQbr23eWa9S_yb61ksONVrLrdesCF_auzwTY8aB$" id="OWA3c51d081-a9cb-0bb5-f558-a69a870fa1a1" class="x_x_x_x_x_x_OWAAutoLink" target="_blank" rel="noopener" data-mce-href="https://urldefense.com/v3/__https://github.com/forax/we_are_all_to_gather/blob/master/src/main/java/com/gihtub/forax/wearealltogather/bench/MapGathererBenchmark.java__;!!ACWV5N9M2RV99hQ!JJy6F9NoL6wKZQK5158up_fTRvH8X7F6JK8T7Euuf8vzbSQbr23eWa9S_yb61ksONVrLrdesCF_auzwTY8aB$">
https://github.com/forax/we_are_all_to_gather/blob/master/src/main/java/com/gihtub/forax/wearealltogather/bench/MapGathererBenchmark.java</a><br>
<br>
I think that adding a way to propagate the spliterator characteristics through a Gatherer would greatly improve the performance of commons streams (at least all the ones that end with a call to toList).<br>
<br>
I have some idea of how to do that, but I prefer first to hear if i've overlook something and if improving the performance is something worth changing the API.<br>
<br>
regards,<br>
Rémi</span></div>
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><br>
</span></blockquote>
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><br>
</span></blockquote>
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><br>
</span></blockquote>
<span data-mce-style="font-family: Helvetica,Arial,sans-serif; font-size: 12pt; color: #000000;" style="font-family:Helvetica,Arial,sans-serif; font-size:12pt; color:#000000"><br>
</span></blockquote>
<br>
</blockquote>
</div>
</div>
</div>
</div>
<br>
</blockquote>
</div>
</div>
</div>
<br>
</blockquote>
</div>
</div>
</div>
</body>
</html>