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