1 /* 2 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.util.stream; 26 27 import java.util.EnumMap; 28 import java.util.Map; 29 import java.util.Spliterator; 30 31 /** 32 * Flags corresponding to characteristics of streams and operations. Flags are 33 * utilized by the stream framework to control, specialize or optimize 34 * computation. 35 * 36 * <p> 37 * Stream flags may be used to describe characteristics of several different 38 * entities associated with streams: stream sources, intermediate operations, 39 * and terminal operations. Not all stream flags are meaningful for all 40 * entities; the following table summarizes which flags are meaningful in what 41 * contexts: 42 * 43 * <div> 44 * <table class="borderless"> 45 * <caption>Type Characteristics</caption> 46 * <thead class="tableSubHeadingColor"> 47 * <tr> 48 * <th colspan="2"> </th> 49 * <th>{@code DISTINCT}</th> 50 * <th>{@code SORTED}</th> 51 * <th>{@code ORDERED}</th> 52 * <th>{@code SIZED}</th> 53 * <th>{@code SHORT_CIRCUIT}</th> 54 * </tr> 55 * </thead> 56 * <tbody> 57 * <tr> 58 * <th colspan="2" class="tableSubHeadingColor">Stream source</th> 59 * <td>Y</td> 60 * <td>Y</td> 61 * <td>Y</td> 62 * <td>Y</td> 63 * <td>N</td> 64 * </tr> 65 * <tr> 66 * <th colspan="2" class="tableSubHeadingColor">Intermediate operation</th> 67 * <td>PCI</td> 68 * <td>PCI</td> 69 * <td>PCI</td> 70 * <td>PC</td> 71 * <td>PI</td> 72 * </tr> 73 * <tr> 74 * <th colspan="2" class="tableSubHeadingColor">Terminal operation</th> 75 * <td>N</td> 76 * <td>N</td> 77 * <td>PC</td> 78 * <td>N</td> 79 * <td>PI</td> 80 * </tr> 81 * </tbody> 82 * <tfoot> 83 * <tr> 84 * <th class="tableSubHeadingColor" colspan="2">Legend</th> 85 * <th colspan="6" rowspan="7"> </th> 86 * </tr> 87 * <tr> 88 * <th class="tableSubHeadingColor">Flag</th> 89 * <th class="tableSubHeadingColor">Meaning</th> 90 * <th colspan="6"></th> 91 * </tr> 92 * <tr><td>Y</td><td>Allowed</td></tr> 93 * <tr><td>N</td><td>Invalid</td></tr> 94 * <tr><td>P</td><td>Preserves</td></tr> 95 * <tr><td>C</td><td>Clears</td></tr> 96 * <tr><td>I</td><td>Injects</td></tr> 97 * </tfoot> 98 * </table> 99 * </div> 100 * 101 * <p>In the above table, "PCI" means "may preserve, clear, or inject"; "PC" 102 * means "may preserve or clear", "PI" means "may preserve or inject", and "N" 103 * means "not valid". 104 * 105 * <p>Stream flags are represented by unioned bit sets, so that a single word 106 * may describe all the characteristics of a given stream entity, and that, for 107 * example, the flags for a stream source can be efficiently combined with the 108 * flags for later operations on that stream. 109 * 110 * <p>The bit masks {@link #STREAM_MASK}, {@link #OP_MASK}, and 111 * {@link #TERMINAL_OP_MASK} can be ANDed with a bit set of stream flags to 112 * produce a mask containing only the valid flags for that entity type. 113 * 114 * <p>When describing a stream source, one only need describe what 115 * characteristics that stream has; when describing a stream operation, one need 116 * describe whether the operation preserves, injects, or clears that 117 * characteristic. Accordingly, two bits are used for each flag, so as to allow 118 * representing not only the presence of a characteristic, but how an 119 * operation modifies that characteristic. There are two common forms in which 120 * flag bits are combined into an {@code int} bit set. <em>Stream flags</em> 121 * are a unioned bit set constructed by ORing the enum characteristic values of 122 * {@link #set()} (or, more commonly, ORing the corresponding static named 123 * constants prefixed with {@code IS_}). <em>Operation flags</em> are a unioned 124 * bit set constructed by ORing the enum characteristic values of {@link #set()} 125 * or {@link #clear()} (to inject, or clear, respectively, the corresponding 126 * flag), or more commonly ORing the corresponding named constants prefixed with 127 * {@code IS_} or {@code NOT_}. Flags that are not marked with {@code IS_} or 128 * {@code NOT_} are implicitly treated as preserved. Care must be taken when 129 * combining bitsets that the correct combining operations are applied in the 130 * correct order. 131 * 132 * <p> 133 * With the exception of {@link #SHORT_CIRCUIT}, stream characteristics can be 134 * derived from the equivalent {@link java.util.Spliterator} characteristics: 135 * {@link java.util.Spliterator#DISTINCT}, {@link java.util.Spliterator#SORTED}, 136 * {@link java.util.Spliterator#ORDERED}, and 137 * {@link java.util.Spliterator#SIZED}. A spliterator characteristics bit set 138 * can be converted to stream flags using the method 139 * {@link #fromCharacteristics(java.util.Spliterator)} and converted back using 140 * {@link #toCharacteristics(int)}. (The bit set 141 * {@link #SPLITERATOR_CHARACTERISTICS_MASK} is used to AND with a bit set to 142 * produce a valid spliterator characteristics bit set that can be converted to 143 * stream flags.) 144 * 145 * <p> 146 * The source of a stream encapsulates a spliterator. The characteristics of 147 * that source spliterator when transformed to stream flags will be a proper 148 * subset of stream flags of that stream. 149 * For example: 150 * <pre> {@code 151 * Spliterator s = ...; 152 * Stream stream = Streams.stream(s); 153 * flagsFromSplitr = fromCharacteristics(s.characteristics()); 154 * assert(flagsFromSplitr & stream.getStreamFlags() == flagsFromSplitr); 155 * }</pre> 156 * 157 * <p> 158 * An intermediate operation, performed on an input stream to create a new 159 * output stream, may preserve, clear or inject stream or operation 160 * characteristics. Similarly, a terminal operation, performed on an input 161 * stream to produce an output result may preserve, clear or inject stream or 162 * operation characteristics. Preservation means that if that characteristic 163 * is present on the input, then it is also present on the output. Clearing 164 * means that the characteristic is not present on the output regardless of the 165 * input. Injection means that the characteristic is present on the output 166 * regardless of the input. If a characteristic is not cleared or injected then 167 * it is implicitly preserved. 168 * 169 * <p> 170 * A pipeline consists of a stream source encapsulating a spliterator, one or 171 * more intermediate operations, and finally a terminal operation that produces 172 * a result. At each stage of the pipeline, a combined stream and operation 173 * flags can be calculated, using {@link #combineOpFlags(int, int)}. Such flags 174 * ensure that preservation, clearing and injecting information is retained at 175 * each stage. 176 * 177 * The combined stream and operation flags for the source stage of the pipeline 178 * is calculated as follows: 179 * <pre> {@code 180 * int flagsForSourceStage = combineOpFlags(sourceFlags, INITIAL_OPS_VALUE); 181 * }</pre> 182 * 183 * The combined stream and operation flags of each subsequent intermediate 184 * operation stage in the pipeline is calculated as follows: 185 * <pre> {@code 186 * int flagsForThisStage = combineOpFlags(flagsForPreviousStage, thisOpFlags); 187 * }</pre> 188 * 189 * Finally the flags output from the last intermediate operation of the pipeline 190 * are combined with the operation flags of the terminal operation to produce 191 * the flags output from the pipeline. 192 * 193 * <p>Those flags can then be used to apply optimizations. For example, if 194 * {@code SIZED.isKnown(flags)} returns true then the stream size remains 195 * constant throughout the pipeline, this information can be utilized to 196 * pre-allocate data structures and combined with 197 * {@link java.util.Spliterator#SUBSIZED} that information can be utilized to 198 * perform concurrent in-place updates into a shared array. 199 * 200 * For specific details see the {@link AbstractPipeline} constructors. 201 * 202 * @since 1.8 203 * @hide Visible for CTS testing only (OpenJDK8 tests). 204 */ 205 // Android-changed: Made public for CTS tests only. 206 public enum StreamOpFlag { 207 208 /* 209 * Each characteristic takes up 2 bits in a bit set to accommodate 210 * preserving, clearing and setting/injecting information. 211 * 212 * This applies to stream flags, intermediate/terminal operation flags, and 213 * combined stream and operation flags. Even though the former only requires 214 * 1 bit of information per characteristic, is it more efficient when 215 * combining flags to align set and inject bits. 216 * 217 * Characteristics belong to certain types, see the Type enum. Bit masks for 218 * the types are constructed as per the following table: 219 * 220 * DISTINCT SORTED ORDERED SIZED SHORT_CIRCUIT 221 * SPLITERATOR 01 01 01 01 00 222 * STREAM 01 01 01 01 00 223 * OP 11 11 11 10 01 224 * TERMINAL_OP 00 00 10 00 01 225 * UPSTREAM_TERMINAL_OP 00 00 10 00 00 226 * 227 * 01 = set/inject 228 * 10 = clear 229 * 11 = preserve 230 * 231 * Construction of the columns is performed using a simple builder for 232 * non-zero values. 233 */ 234 235 236 // The following flags correspond to characteristics on Spliterator 237 // and the values MUST be equal. 238 // 239 240 /** 241 * Characteristic value signifying that, for each pair of 242 * encountered elements in a stream {@code x, y}, {@code !x.equals(y)}. 243 * <p> 244 * A stream may have this value or an intermediate operation can preserve, 245 * clear or inject this value. 246 */ 247 // 0, 0x00000001 248 // Matches Spliterator.DISTINCT 249 DISTINCT(0, 250 set(Type.SPLITERATOR).set(Type.STREAM).setAndClear(Type.OP)), 251 252 /** 253 * Characteristic value signifying that encounter order follows a natural 254 * sort order of comparable elements. 255 * <p> 256 * A stream can have this value or an intermediate operation can preserve, 257 * clear or inject this value. 258 * <p> 259 * Note: The {@link java.util.Spliterator#SORTED} characteristic can define 260 * a sort order with an associated non-null comparator. Augmenting flag 261 * state with addition properties such that those properties can be passed 262 * to operations requires some disruptive changes for a singular use-case. 263 * Furthermore, comparing comparators for equality beyond that of identity 264 * is likely to be unreliable. Therefore the {@code SORTED} characteristic 265 * for a defined non-natural sort order is not mapped internally to the 266 * {@code SORTED} flag. 267 */ 268 // 1, 0x00000004 269 // Matches Spliterator.SORTED 270 SORTED(1, 271 set(Type.SPLITERATOR).set(Type.STREAM).setAndClear(Type.OP)), 272 273 /** 274 * Characteristic value signifying that an encounter order is 275 * defined for stream elements. 276 * <p> 277 * A stream can have this value, an intermediate operation can preserve, 278 * clear or inject this value, or a terminal operation can preserve or clear 279 * this value. 280 */ 281 // 2, 0x00000010 282 // Matches Spliterator.ORDERED 283 ORDERED(2, 284 set(Type.SPLITERATOR).set(Type.STREAM).setAndClear(Type.OP).clear(Type.TERMINAL_OP) 285 .clear(Type.UPSTREAM_TERMINAL_OP)), 286 287 /** 288 * Characteristic value signifying that size of the stream 289 * is of a known finite size that is equal to the known finite 290 * size of the source spliterator input to the first stream 291 * in the pipeline. 292 * <p> 293 * A stream can have this value or an intermediate operation can preserve or 294 * clear this value. 295 */ 296 // 3, 0x00000040 297 // Matches Spliterator.SIZED 298 SIZED(3, 299 set(Type.SPLITERATOR).set(Type.STREAM).clear(Type.OP)), 300 301 // The following Spliterator characteristics are not currently used but a 302 // gap in the bit set is deliberately retained to enable corresponding 303 // stream flags if//when required without modification to other flag values. 304 // 305 // 4, 0x00000100 NONNULL(4, ... 306 // 5, 0x00000400 IMMUTABLE(5, ... 307 // 6, 0x00001000 CONCURRENT(6, ... 308 // 7, 0x00004000 SUBSIZED(7, ... 309 310 // The following 4 flags are currently undefined and a free for any further 311 // spliterator characteristics. 312 // 313 // 8, 0x00010000 314 // 9, 0x00040000 315 // 10, 0x00100000 316 // 11, 0x00400000 317 318 // The following flags are specific to streams and operations 319 // 320 321 /** 322 * Characteristic value signifying that an operation may short-circuit the 323 * stream. 324 * <p> 325 * An intermediate operation can preserve or inject this value, 326 * or a terminal operation can preserve or inject this value. 327 */ 328 // 12, 0x01000000 329 SHORT_CIRCUIT(12, 330 set(Type.OP).set(Type.TERMINAL_OP)), 331 332 /** 333 * Characteristic value signifying that an operation may adjust the 334 * total size of the stream. 335 * <p> 336 * The flag, if present, is only valid when SIZED is present; 337 * and is only valid for sequential streams. 338 * <p> 339 * An intermediate operation can preserve or inject this value. 340 */ 341 // 13, 0x04000000 342 SIZE_ADJUSTING(13, 343 set(Type.OP)); 344 345 // The following 2 flags are currently undefined and a free for any further 346 // stream flags if/when required 347 // 348 // 14, 0x10000000 349 // 15, 0x40000000 350 351 /** 352 * Type of a flag 353 */ 354 enum Type { 355 /** 356 * The flag is associated with spliterator characteristics. 357 */ 358 SPLITERATOR, 359 360 /** 361 * The flag is associated with stream flags. 362 */ 363 STREAM, 364 365 /** 366 * The flag is associated with intermediate operation flags. 367 */ 368 OP, 369 370 /** 371 * The flag is associated with terminal operation flags. 372 */ 373 TERMINAL_OP, 374 375 /** 376 * The flag is associated with terminal operation flags that are 377 * propagated upstream across the last stateful operation boundary 378 */ 379 UPSTREAM_TERMINAL_OP 380 } 381 382 /** 383 * The bit pattern for setting/injecting a flag. 384 */ 385 private static final int SET_BITS = 0b01; 386 387 /** 388 * The bit pattern for clearing a flag. 389 */ 390 private static final int CLEAR_BITS = 0b10; 391 392 /** 393 * The bit pattern for preserving a flag. 394 */ 395 private static final int PRESERVE_BITS = 0b11; 396 set(Type t)397 private static MaskBuilder set(Type t) { 398 return new MaskBuilder(new EnumMap<>(Type.class)).set(t); 399 } 400 401 private static class MaskBuilder { 402 final Map<Type, Integer> map; 403 MaskBuilder(Map<Type, Integer> map)404 MaskBuilder(Map<Type, Integer> map) { 405 this.map = map; 406 } 407 mask(Type t, Integer i)408 MaskBuilder mask(Type t, Integer i) { 409 map.put(t, i); 410 return this; 411 } 412 set(Type t)413 MaskBuilder set(Type t) { 414 return mask(t, SET_BITS); 415 } 416 clear(Type t)417 MaskBuilder clear(Type t) { 418 return mask(t, CLEAR_BITS); 419 } 420 setAndClear(Type t)421 MaskBuilder setAndClear(Type t) { 422 return mask(t, PRESERVE_BITS); 423 } 424 build()425 Map<Type, Integer> build() { 426 for (Type t : Type.values()) { 427 map.putIfAbsent(t, 0b00); 428 } 429 return map; 430 } 431 } 432 433 /** 434 * The mask table for a flag, this is used to determine if a flag 435 * corresponds to a certain flag type and for creating mask constants. 436 */ 437 private final Map<Type, Integer> maskTable; 438 439 /** 440 * The bit position in the bit mask. 441 */ 442 private final int bitPosition; 443 444 /** 445 * The set 2 bit set offset at the bit position. 446 */ 447 private final int set; 448 449 /** 450 * The clear 2 bit set offset at the bit position. 451 */ 452 private final int clear; 453 454 /** 455 * The preserve 2 bit set offset at the bit position. 456 */ 457 private final int preserve; 458 StreamOpFlag(int position, MaskBuilder maskBuilder)459 private StreamOpFlag(int position, MaskBuilder maskBuilder) { 460 this.maskTable = maskBuilder.build(); 461 // Two bits per flag 462 position *= 2; 463 this.bitPosition = position; 464 this.set = SET_BITS << position; 465 this.clear = CLEAR_BITS << position; 466 this.preserve = PRESERVE_BITS << position; 467 } 468 469 /** 470 * Gets the bitmap associated with setting this characteristic. 471 * 472 * @return the bitmap for setting this characteristic 473 */ 474 // Android-changed: Made public for CTS tests only. set()475 public int set() { 476 return set; 477 } 478 479 /** 480 * Gets the bitmap associated with clearing this characteristic. 481 * 482 * @return the bitmap for clearing this characteristic 483 */ 484 // Android-changed: Made public for CTS tests only. clear()485 public int clear() { 486 return clear; 487 } 488 489 /** 490 * Determines if this flag is a stream-based flag. 491 * 492 * @return true if a stream-based flag, otherwise false. 493 */ 494 // Android-changed: Made public for CTS tests only. isStreamFlag()495 public boolean isStreamFlag() { 496 return maskTable.get(Type.STREAM) > 0; 497 } 498 499 /** 500 * Checks if this flag is set on stream flags, injected on operation flags, 501 * and injected on combined stream and operation flags. 502 * 503 * @param flags the stream flags, operation flags, or combined stream and 504 * operation flags 505 * @return true if this flag is known, otherwise false. 506 */ 507 // Android-changed: Made public for CTS tests only. isKnown(int flags)508 public boolean isKnown(int flags) { 509 return (flags & preserve) == set; 510 } 511 512 /** 513 * Checks if this flag is cleared on operation flags or combined stream and 514 * operation flags. 515 * 516 * @param flags the operation flags or combined stream and operations flags. 517 * @return true if this flag is preserved, otherwise false. 518 */ 519 // Android-changed: Made public for CTS tests only. isCleared(int flags)520 public boolean isCleared(int flags) { 521 return (flags & preserve) == clear; 522 } 523 524 /** 525 * Checks if this flag is preserved on combined stream and operation flags. 526 * 527 * @param flags the combined stream and operations flags. 528 * @return true if this flag is preserved, otherwise false. 529 */ 530 // Android-changed: Made public for CTS tests only. isPreserved(int flags)531 public boolean isPreserved(int flags) { 532 return (flags & preserve) == preserve; 533 } 534 535 /** 536 * Determines if this flag can be set for a flag type. 537 * 538 * @param t the flag type. 539 * @return true if this flag can be set for the flag type, otherwise false. 540 */ 541 // Android-changed: Made public for CTS tests only. canSet(Type t)542 public boolean canSet(Type t) { 543 return (maskTable.get(t) & SET_BITS) > 0; 544 } 545 546 /** 547 * The bit mask for spliterator characteristics 548 */ 549 // Android-changed: Made public for CTS tests only. 550 public static final int SPLITERATOR_CHARACTERISTICS_MASK = createMask(Type.SPLITERATOR); 551 552 /** 553 * The bit mask for source stream flags. 554 */ 555 // Android-changed: Made public for CTS tests only. 556 public static final int STREAM_MASK = createMask(Type.STREAM); 557 558 /** 559 * The bit mask for intermediate operation flags. 560 */ 561 // Android-changed: Made public for CTS tests only. 562 public static final int OP_MASK = createMask(Type.OP); 563 564 /** 565 * The bit mask for terminal operation flags. 566 */ 567 // Android-changed: Made public for CTS tests only. 568 public static final int TERMINAL_OP_MASK = createMask(Type.TERMINAL_OP); 569 570 /** 571 * The bit mask for upstream terminal operation flags. 572 */ 573 // Android-changed: Made public for CTS tests only. 574 public static final int UPSTREAM_TERMINAL_OP_MASK = createMask(Type.UPSTREAM_TERMINAL_OP); 575 createMask(Type t)576 private static int createMask(Type t) { 577 int mask = 0; 578 for (StreamOpFlag flag : StreamOpFlag.values()) { 579 mask |= flag.maskTable.get(t) << flag.bitPosition; 580 } 581 return mask; 582 } 583 584 /** 585 * Complete flag mask. 586 */ 587 private static final int FLAG_MASK = createFlagMask(); 588 createFlagMask()589 private static int createFlagMask() { 590 int mask = 0; 591 for (StreamOpFlag flag : StreamOpFlag.values()) { 592 mask |= flag.preserve; 593 } 594 return mask; 595 } 596 597 /** 598 * Flag mask for stream flags that are set. 599 */ 600 private static final int FLAG_MASK_IS = STREAM_MASK; 601 602 /** 603 * Flag mask for stream flags that are cleared. 604 */ 605 private static final int FLAG_MASK_NOT = STREAM_MASK << 1; 606 607 /** 608 * The initial value to be combined with the stream flags of the first 609 * stream in the pipeline. 610 */ 611 // Android-changed: Made public for CTS tests only. 612 public static final int INITIAL_OPS_VALUE = FLAG_MASK_IS | FLAG_MASK_NOT; 613 614 /** 615 * The bit value to set or inject {@link #DISTINCT}. 616 */ 617 // Android-changed: Made public for CTS tests only. 618 public static final int IS_DISTINCT = DISTINCT.set; 619 620 /** 621 * The bit value to clear {@link #DISTINCT}. 622 */ 623 // Android-changed: Made public for CTS tests only. 624 public static final int NOT_DISTINCT = DISTINCT.clear; 625 626 /** 627 * The bit value to set or inject {@link #SORTED}. 628 */ 629 // Android-changed: Made public for CTS tests only. 630 public static final int IS_SORTED = SORTED.set; 631 632 /** 633 * The bit value to clear {@link #SORTED}. 634 */ 635 // Android-changed: Made public for CTS tests only. 636 public static final int NOT_SORTED = SORTED.clear; 637 638 /** 639 * The bit value to set or inject {@link #ORDERED}. 640 */ 641 // Android-changed: Made public for CTS tests only. 642 public static final int IS_ORDERED = ORDERED.set; 643 644 /** 645 * The bit value to clear {@link #ORDERED}. 646 */ 647 // Android-changed: Made public for CTS tests only. 648 public static final int NOT_ORDERED = ORDERED.clear; 649 650 /** 651 * The bit value to set {@link #SIZED}. 652 */ 653 // Android-changed: Made public for CTS tests only. 654 public static final int IS_SIZED = SIZED.set; 655 656 /** 657 * The bit value to clear {@link #SIZED}. 658 */ 659 // Android-changed: Made public for CTS tests only. 660 public static final int NOT_SIZED = SIZED.clear; 661 662 /** 663 * The bit value to inject {@link #SHORT_CIRCUIT}. 664 */ 665 // Android-changed: Made public for CTS tests only. 666 public static final int IS_SHORT_CIRCUIT = SHORT_CIRCUIT.set; 667 668 /** 669 * The bit value to inject {@link #SIZE_ADJUSTING}. 670 */ 671 // Android-changed: Made public for CTS tests only. 672 public static final int IS_SIZE_ADJUSTING = SIZE_ADJUSTING.set; 673 getMask(int flags)674 private static int getMask(int flags) { 675 return (flags == 0) 676 ? FLAG_MASK 677 : ~(flags | ((FLAG_MASK_IS & flags) << 1) | ((FLAG_MASK_NOT & flags) >> 1)); 678 } 679 680 /** 681 * Combines stream or operation flags with previously combined stream and 682 * operation flags to produce updated combined stream and operation flags. 683 * <p> 684 * A flag set on stream flags or injected on operation flags, 685 * and injected combined stream and operation flags, 686 * will be injected on the updated combined stream and operation flags. 687 * 688 * <p> 689 * A flag set on stream flags or injected on operation flags, 690 * and cleared on the combined stream and operation flags, 691 * will be cleared on the updated combined stream and operation flags. 692 * 693 * <p> 694 * A flag set on the stream flags or injected on operation flags, 695 * and preserved on the combined stream and operation flags, 696 * will be injected on the updated combined stream and operation flags. 697 * 698 * <p> 699 * A flag not set on the stream flags or cleared/preserved on operation 700 * flags, and injected on the combined stream and operation flags, 701 * will be injected on the updated combined stream and operation flags. 702 * 703 * <p> 704 * A flag not set on the stream flags or cleared/preserved on operation 705 * flags, and cleared on the combined stream and operation flags, 706 * will be cleared on the updated combined stream and operation flags. 707 * 708 * <p> 709 * A flag not set on the stream flags, 710 * and preserved on the combined stream and operation flags 711 * will be preserved on the updated combined stream and operation flags. 712 * 713 * <p> 714 * A flag cleared on operation flags, 715 * and preserved on the combined stream and operation flags 716 * will be cleared on the updated combined stream and operation flags. 717 * 718 * <p> 719 * A flag preserved on operation flags, 720 * and preserved on the combined stream and operation flags 721 * will be preserved on the updated combined stream and operation flags. 722 * 723 * @param newStreamOrOpFlags the stream or operation flags. 724 * @param prevCombOpFlags previously combined stream and operation flags. 725 * The value {#link INITIAL_OPS_VALUE} must be used as the seed value. 726 * @return the updated combined stream and operation flags. 727 */ 728 // Android-changed: Made public for CTS tests only. combineOpFlags(int newStreamOrOpFlags, int prevCombOpFlags)729 public static int combineOpFlags(int newStreamOrOpFlags, int prevCombOpFlags) { 730 // 0x01 or 0x10 nibbles are transformed to 0x11 731 // 0x00 nibbles remain unchanged 732 // Then all the bits are flipped 733 // Then the result is logically or'ed with the operation flags. 734 return (prevCombOpFlags & StreamOpFlag.getMask(newStreamOrOpFlags)) | newStreamOrOpFlags; 735 } 736 737 /** 738 * Converts combined stream and operation flags to stream flags. 739 * 740 * <p>Each flag injected on the combined stream and operation flags will be 741 * set on the stream flags. 742 * 743 * @param combOpFlags the combined stream and operation flags. 744 * @return the stream flags. 745 */ 746 // Android-changed: Made public for CTS tests only. toStreamFlags(int combOpFlags)747 public static int toStreamFlags(int combOpFlags) { 748 // By flipping the nibbles 0x11 become 0x00 and 0x01 become 0x10 749 // Shift left 1 to restore set flags and mask off anything other than the set flags 750 return ((~combOpFlags) >> 1) & FLAG_MASK_IS & combOpFlags; 751 } 752 753 /** 754 * Converts stream flags to a spliterator characteristic bit set. 755 * 756 * @param streamFlags the stream flags. 757 * @return the spliterator characteristic bit set. 758 */ 759 // Android-changed: Made public for CTS tests only. toCharacteristics(int streamFlags)760 public static int toCharacteristics(int streamFlags) { 761 return streamFlags & SPLITERATOR_CHARACTERISTICS_MASK; 762 } 763 764 /** 765 * Converts a spliterator characteristic bit set to stream flags. 766 * 767 * @implSpec 768 * If the spliterator is naturally {@code SORTED} (the associated 769 * {@code Comparator} is {@code null}) then the characteristic is converted 770 * to the {@link #SORTED} flag, otherwise the characteristic is not 771 * converted. 772 * 773 * @param spliterator the spliterator from which to obtain characteristic 774 * bit set. 775 * @return the stream flags. 776 */ 777 // Android-changed: Made public for CTS tests only. fromCharacteristics(Spliterator<?> spliterator)778 public static int fromCharacteristics(Spliterator<?> spliterator) { 779 int characteristics = spliterator.characteristics(); 780 if ((characteristics & Spliterator.SORTED) != 0 && spliterator.getComparator() != null) { 781 // Do not propagate the SORTED characteristic if it does not correspond 782 // to a natural sort order 783 return characteristics & SPLITERATOR_CHARACTERISTICS_MASK & ~Spliterator.SORTED; 784 } 785 else { 786 return characteristics & SPLITERATOR_CHARACTERISTICS_MASK; 787 } 788 } 789 790 /** 791 * Converts a spliterator characteristic bit set to stream flags. 792 * 793 * @param characteristics the spliterator characteristic bit set. 794 * @return the stream flags. 795 */ 796 // Android-changed: Made public for CTS tests only. fromCharacteristics(int characteristics)797 public static int fromCharacteristics(int characteristics) { 798 return characteristics & SPLITERATOR_CHARACTERISTICS_MASK; 799 } 800 } 801