1 /* 2 * Copyright (c) 2012, 2013, 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> 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 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 // The following 2 flags are currently undefined and a free for any further 333 // stream flags if/when required 334 // 335 // 13, 0x04000000 336 // 14, 0x10000000 337 // 15, 0x40000000 338 339 /** 340 * Type of a flag 341 */ 342 enum Type { 343 /** 344 * The flag is associated with spliterator characteristics. 345 */ 346 SPLITERATOR, 347 348 /** 349 * The flag is associated with stream flags. 350 */ 351 STREAM, 352 353 /** 354 * The flag is associated with intermediate operation flags. 355 */ 356 OP, 357 358 /** 359 * The flag is associated with terminal operation flags. 360 */ 361 TERMINAL_OP, 362 363 /** 364 * The flag is associated with terminal operation flags that are 365 * propagated upstream across the last stateful operation boundary 366 */ 367 UPSTREAM_TERMINAL_OP 368 } 369 370 /** 371 * The bit pattern for setting/injecting a flag. 372 */ 373 private static final int SET_BITS = 0b01; 374 375 /** 376 * The bit pattern for clearing a flag. 377 */ 378 private static final int CLEAR_BITS = 0b10; 379 380 /** 381 * The bit pattern for preserving a flag. 382 */ 383 private static final int PRESERVE_BITS = 0b11; 384 set(Type t)385 private static MaskBuilder set(Type t) { 386 return new MaskBuilder(new EnumMap<>(Type.class)).set(t); 387 } 388 389 private static class MaskBuilder { 390 final Map<Type, Integer> map; 391 MaskBuilder(Map<Type, Integer> map)392 MaskBuilder(Map<Type, Integer> map) { 393 this.map = map; 394 } 395 mask(Type t, Integer i)396 MaskBuilder mask(Type t, Integer i) { 397 map.put(t, i); 398 return this; 399 } 400 set(Type t)401 MaskBuilder set(Type t) { 402 return mask(t, SET_BITS); 403 } 404 clear(Type t)405 MaskBuilder clear(Type t) { 406 return mask(t, CLEAR_BITS); 407 } 408 setAndClear(Type t)409 MaskBuilder setAndClear(Type t) { 410 return mask(t, PRESERVE_BITS); 411 } 412 build()413 Map<Type, Integer> build() { 414 for (Type t : Type.values()) { 415 map.putIfAbsent(t, 0b00); 416 } 417 return map; 418 } 419 } 420 421 /** 422 * The mask table for a flag, this is used to determine if a flag 423 * corresponds to a certain flag type and for creating mask constants. 424 */ 425 private final Map<Type, Integer> maskTable; 426 427 /** 428 * The bit position in the bit mask. 429 */ 430 private final int bitPosition; 431 432 /** 433 * The set 2 bit set offset at the bit position. 434 */ 435 private final int set; 436 437 /** 438 * The clear 2 bit set offset at the bit position. 439 */ 440 private final int clear; 441 442 /** 443 * The preserve 2 bit set offset at the bit position. 444 */ 445 private final int preserve; 446 StreamOpFlag(int position, MaskBuilder maskBuilder)447 private StreamOpFlag(int position, MaskBuilder maskBuilder) { 448 this.maskTable = maskBuilder.build(); 449 // Two bits per flag 450 position *= 2; 451 this.bitPosition = position; 452 this.set = SET_BITS << position; 453 this.clear = CLEAR_BITS << position; 454 this.preserve = PRESERVE_BITS << position; 455 } 456 457 /** 458 * Gets the bitmap associated with setting this characteristic. 459 * 460 * @return the bitmap for setting this characteristic 461 */ 462 // Android-changed: Made public for CTS tests only. set()463 public int set() { 464 return set; 465 } 466 467 /** 468 * Gets the bitmap associated with clearing this characteristic. 469 * 470 * @return the bitmap for clearing this characteristic 471 */ 472 // Android-changed: Made public for CTS tests only. clear()473 public int clear() { 474 return clear; 475 } 476 477 /** 478 * Determines if this flag is a stream-based flag. 479 * 480 * @return true if a stream-based flag, otherwise false. 481 */ 482 // Android-changed: Made public for CTS tests only. isStreamFlag()483 public boolean isStreamFlag() { 484 return maskTable.get(Type.STREAM) > 0; 485 } 486 487 /** 488 * Checks if this flag is set on stream flags, injected on operation flags, 489 * and injected on combined stream and operation flags. 490 * 491 * @param flags the stream flags, operation flags, or combined stream and 492 * operation flags 493 * @return true if this flag is known, otherwise false. 494 */ 495 // Android-changed: Made public for CTS tests only. isKnown(int flags)496 public boolean isKnown(int flags) { 497 return (flags & preserve) == set; 498 } 499 500 /** 501 * Checks if this flag is cleared on operation flags or combined stream and 502 * operation flags. 503 * 504 * @param flags the operation flags or combined stream and operations flags. 505 * @return true if this flag is preserved, otherwise false. 506 */ 507 // Android-changed: Made public for CTS tests only. isCleared(int flags)508 public boolean isCleared(int flags) { 509 return (flags & preserve) == clear; 510 } 511 512 /** 513 * Checks if this flag is preserved on combined stream and operation flags. 514 * 515 * @param flags the combined stream and operations flags. 516 * @return true if this flag is preserved, otherwise false. 517 */ 518 // Android-changed: Made public for CTS tests only. isPreserved(int flags)519 public boolean isPreserved(int flags) { 520 return (flags & preserve) == preserve; 521 } 522 523 /** 524 * Determines if this flag can be set for a flag type. 525 * 526 * @param t the flag type. 527 * @return true if this flag can be set for the flag type, otherwise false. 528 */ 529 // Android-changed: Made public for CTS tests only. canSet(Type t)530 public boolean canSet(Type t) { 531 return (maskTable.get(t) & SET_BITS) > 0; 532 } 533 534 /** 535 * The bit mask for spliterator characteristics 536 */ 537 // Android-changed: Made public for CTS tests only. 538 public static final int SPLITERATOR_CHARACTERISTICS_MASK = createMask(Type.SPLITERATOR); 539 540 /** 541 * The bit mask for source stream flags. 542 */ 543 // Android-changed: Made public for CTS tests only. 544 public static final int STREAM_MASK = createMask(Type.STREAM); 545 546 /** 547 * The bit mask for intermediate operation flags. 548 */ 549 // Android-changed: Made public for CTS tests only. 550 public static final int OP_MASK = createMask(Type.OP); 551 552 /** 553 * The bit mask for terminal operation flags. 554 */ 555 // Android-changed: Made public for CTS tests only. 556 public static final int TERMINAL_OP_MASK = createMask(Type.TERMINAL_OP); 557 558 /** 559 * The bit mask for upstream terminal operation flags. 560 */ 561 // Android-changed: Made public for CTS tests only. 562 public static final int UPSTREAM_TERMINAL_OP_MASK = createMask(Type.UPSTREAM_TERMINAL_OP); 563 createMask(Type t)564 private static int createMask(Type t) { 565 int mask = 0; 566 for (StreamOpFlag flag : StreamOpFlag.values()) { 567 mask |= flag.maskTable.get(t) << flag.bitPosition; 568 } 569 return mask; 570 } 571 572 /** 573 * Complete flag mask. 574 */ 575 private static final int FLAG_MASK = createFlagMask(); 576 createFlagMask()577 private static int createFlagMask() { 578 int mask = 0; 579 for (StreamOpFlag flag : StreamOpFlag.values()) { 580 mask |= flag.preserve; 581 } 582 return mask; 583 } 584 585 /** 586 * Flag mask for stream flags that are set. 587 */ 588 private static final int FLAG_MASK_IS = STREAM_MASK; 589 590 /** 591 * Flag mask for stream flags that are cleared. 592 */ 593 private static final int FLAG_MASK_NOT = STREAM_MASK << 1; 594 595 /** 596 * The initial value to be combined with the stream flags of the first 597 * stream in the pipeline. 598 */ 599 // Android-changed: Made public for CTS tests only. 600 public static final int INITIAL_OPS_VALUE = FLAG_MASK_IS | FLAG_MASK_NOT; 601 602 /** 603 * The bit value to set or inject {@link #DISTINCT}. 604 */ 605 // Android-changed: Made public for CTS tests only. 606 public static final int IS_DISTINCT = DISTINCT.set; 607 608 /** 609 * The bit value to clear {@link #DISTINCT}. 610 */ 611 // Android-changed: Made public for CTS tests only. 612 public static final int NOT_DISTINCT = DISTINCT.clear; 613 614 /** 615 * The bit value to set or inject {@link #SORTED}. 616 */ 617 // Android-changed: Made public for CTS tests only. 618 public static final int IS_SORTED = SORTED.set; 619 620 /** 621 * The bit value to clear {@link #SORTED}. 622 */ 623 // Android-changed: Made public for CTS tests only. 624 public static final int NOT_SORTED = SORTED.clear; 625 626 /** 627 * The bit value to set or inject {@link #ORDERED}. 628 */ 629 // Android-changed: Made public for CTS tests only. 630 public static final int IS_ORDERED = ORDERED.set; 631 632 /** 633 * The bit value to clear {@link #ORDERED}. 634 */ 635 // Android-changed: Made public for CTS tests only. 636 public static final int NOT_ORDERED = ORDERED.clear; 637 638 /** 639 * The bit value to set {@link #SIZED}. 640 */ 641 // Android-changed: Made public for CTS tests only. 642 public static final int IS_SIZED = SIZED.set; 643 644 /** 645 * The bit value to clear {@link #SIZED}. 646 */ 647 // Android-changed: Made public for CTS tests only. 648 public static final int NOT_SIZED = SIZED.clear; 649 650 /** 651 * The bit value to inject {@link #SHORT_CIRCUIT}. 652 */ 653 // Android-changed: Made public for CTS tests only. 654 public static final int IS_SHORT_CIRCUIT = SHORT_CIRCUIT.set; 655 getMask(int flags)656 private static int getMask(int flags) { 657 return (flags == 0) 658 ? FLAG_MASK 659 : ~(flags | ((FLAG_MASK_IS & flags) << 1) | ((FLAG_MASK_NOT & flags) >> 1)); 660 } 661 662 /** 663 * Combines stream or operation flags with previously combined stream and 664 * operation flags to produce updated combined stream and operation flags. 665 * <p> 666 * A flag set on stream flags or injected on operation flags, 667 * and injected combined stream and operation flags, 668 * will be injected on the updated combined stream and operation flags. 669 * 670 * <p> 671 * A flag set on stream flags or injected on operation flags, 672 * and cleared on the combined stream and operation flags, 673 * will be cleared on the updated combined stream and operation flags. 674 * 675 * <p> 676 * A flag set on the stream flags or injected on operation flags, 677 * and preserved on the combined stream and operation flags, 678 * will be injected on the updated combined stream and operation flags. 679 * 680 * <p> 681 * A flag not set on the stream flags or cleared/preserved on operation 682 * flags, and injected on the combined stream and operation flags, 683 * will be injected on the updated combined stream and operation flags. 684 * 685 * <p> 686 * A flag not set on the stream flags or cleared/preserved on operation 687 * flags, and cleared on the combined stream and operation flags, 688 * will be cleared on the updated combined stream and operation flags. 689 * 690 * <p> 691 * A flag not set on the stream flags, 692 * and preserved on the combined stream and operation flags 693 * will be preserved on the updated combined stream and operation flags. 694 * 695 * <p> 696 * A flag cleared on operation flags, 697 * and preserved on the combined stream and operation flags 698 * will be cleared on the updated combined stream and operation flags. 699 * 700 * <p> 701 * A flag preserved on operation flags, 702 * and preserved on the combined stream and operation flags 703 * will be preserved on the updated combined stream and operation flags. 704 * 705 * @param newStreamOrOpFlags the stream or operation flags. 706 * @param prevCombOpFlags previously combined stream and operation flags. 707 * The value {#link INITIAL_OPS_VALUE} must be used as the seed value. 708 * @return the updated combined stream and operation flags. 709 */ 710 // Android-changed: Made public for CTS tests only. combineOpFlags(int newStreamOrOpFlags, int prevCombOpFlags)711 public static int combineOpFlags(int newStreamOrOpFlags, int prevCombOpFlags) { 712 // 0x01 or 0x10 nibbles are transformed to 0x11 713 // 0x00 nibbles remain unchanged 714 // Then all the bits are flipped 715 // Then the result is logically or'ed with the operation flags. 716 return (prevCombOpFlags & StreamOpFlag.getMask(newStreamOrOpFlags)) | newStreamOrOpFlags; 717 } 718 719 /** 720 * Converts combined stream and operation flags to stream flags. 721 * 722 * <p>Each flag injected on the combined stream and operation flags will be 723 * set on the stream flags. 724 * 725 * @param combOpFlags the combined stream and operation flags. 726 * @return the stream flags. 727 */ 728 // Android-changed: Made public for CTS tests only. toStreamFlags(int combOpFlags)729 public static int toStreamFlags(int combOpFlags) { 730 // By flipping the nibbles 0x11 become 0x00 and 0x01 become 0x10 731 // Shift left 1 to restore set flags and mask off anything other than the set flags 732 return ((~combOpFlags) >> 1) & FLAG_MASK_IS & combOpFlags; 733 } 734 735 /** 736 * Converts stream flags to a spliterator characteristic bit set. 737 * 738 * @param streamFlags the stream flags. 739 * @return the spliterator characteristic bit set. 740 */ 741 // Android-changed: Made public for CTS tests only. toCharacteristics(int streamFlags)742 public static int toCharacteristics(int streamFlags) { 743 return streamFlags & SPLITERATOR_CHARACTERISTICS_MASK; 744 } 745 746 /** 747 * Converts a spliterator characteristic bit set to stream flags. 748 * 749 * @implSpec 750 * If the spliterator is naturally {@code SORTED} (the associated 751 * {@code Comparator} is {@code null}) then the characteristic is converted 752 * to the {@link #SORTED} flag, otherwise the characteristic is not 753 * converted. 754 * 755 * @param spliterator the spliterator from which to obtain characteristic 756 * bit set. 757 * @return the stream flags. 758 */ 759 // Android-changed: Made public for CTS tests only. fromCharacteristics(Spliterator<?> spliterator)760 public static int fromCharacteristics(Spliterator<?> spliterator) { 761 int characteristics = spliterator.characteristics(); 762 if ((characteristics & Spliterator.SORTED) != 0 && spliterator.getComparator() != null) { 763 // Do not propagate the SORTED characteristic if it does not correspond 764 // to a natural sort order 765 return characteristics & SPLITERATOR_CHARACTERISTICS_MASK & ~Spliterator.SORTED; 766 } 767 else { 768 return characteristics & SPLITERATOR_CHARACTERISTICS_MASK; 769 } 770 } 771 772 /** 773 * Converts a spliterator characteristic bit set to stream flags. 774 * 775 * @param characteristics the spliterator characteristic bit set. 776 * @return the stream flags. 777 */ 778 // Android-changed: Made public for CTS tests only. fromCharacteristics(int characteristics)779 public static int fromCharacteristics(int characteristics) { 780 return characteristics & SPLITERATOR_CHARACTERISTICS_MASK; 781 } 782 } 783