• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&nbsp;</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">&nbsp;</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