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