changeset 6445:0a30434d0121

Ensure stream flags are correctly obtained from combined stream and ops flags.
author psandoz
date Tue, 20 Nov 2012 13:53:19 +0100
parents c54ba7563085
children ffc074f5b2e9
files src/share/classes/java/util/stream/AbstractPipeline.java src/share/classes/java/util/stream/StreamOpFlags.java test-ng/tests/org/openjdk/tests/java/util/stream/StreamFlagsTest.java test-ng/tests/org/openjdk/tests/java/util/stream/StreamOpFlagsTest.java
diffstat 4 files changed, 64 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/AbstractPipeline.java	Mon Nov 19 18:05:09 2012 -0500
+++ b/src/share/classes/java/util/stream/AbstractPipeline.java	Tue Nov 20 13:53:19 2012 +0100
@@ -109,7 +109,7 @@
         this.op = Objects.requireNonNull(op);
         this.depth = upstream.depth + 1;
         this.sourceState = upstream.sourceState;
-        this.combinedOpFlags = StreamOpFlags.combineOpFlags(upstream.combinedOpFlags, op.getOpFlags());
+        this.combinedOpFlags = StreamOpFlags.combineOpFlags(op.getOpFlags(), upstream.combinedOpFlags);
 
         assert upstream.getOutputShape().getStreamType() == op.inputShape().getStreamType();
         assert (upstream.depth == 0) ^ (upstream.op != null);
@@ -147,7 +147,7 @@
                         iSourceFlags,
                         StreamOpFlags.combineOpFlags(statefulOp.getOpFlags(), opsFlags[upToOp]));
                 // Get the source flags for the intermediate stream
-                iSourceFlags = StreamOpFlags.flagsToStreamFlags(sourceAndOpsFlags)
+                iSourceFlags = StreamOpFlags.getStreamFlags(sourceAndOpsFlags)
                                | StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED;
                 // Create stream accessor from node using the stream flags
                 iSource = iNode.spliterator();
@@ -531,7 +531,7 @@
 
     @Override
     public int getStreamFlags() {
-        return StreamOpFlags.combineStreamFlags(sourceState.getSourceFlags(), combinedOpFlags);
+        return StreamOpFlags.getStreamFlags(StreamOpFlags.combineStreamFlags(sourceState.getSourceFlags(), combinedOpFlags));
     }
 
     @Override
--- a/src/share/classes/java/util/stream/StreamOpFlags.java	Mon Nov 19 18:05:09 2012 -0500
+++ b/src/share/classes/java/util/stream/StreamOpFlags.java	Tue Nov 20 13:53:19 2012 +0100
@@ -28,7 +28,7 @@
 
 /**
  * Flags describing dynamic properties of streams, such as sortedness or distinctness.
- *
+ * <p/>
  * Streams either have, or do not have, the specified property.  Intermediate stream
  * operations can describe whether it preserves, clears, or injects the specified
  * property.  So, for example, a {@code Stream} derived from a {@code List} has the
@@ -36,26 +36,31 @@
  * preserves sized-ness, whereas the {@code filter()} operation clears sized-ness.
  * Most flags can apply either to a stream or a stream operation, though some can only
  * apply to stream operations (such as {@code SHORT_CIRCUIT}.)
- *
+ * <p/>
  * Combinations of flags are generally described using int-sized bitmaps for efficiency,
- * with each flag (generally) taking two bits.  There are two forms of the bitmap:
- *
+ * with each flag (generally) taking two bits.  There are three forms of the bitmap:
+ * <p/>
  * <ul>
- * <li>The stream form, where the specific bits are either set or not set;</li>
+ * <li>The stream form, where one bit is used to encode whether a
+ * stream property is set or not set;</li>
  * <li>The operation form, where two bits are used to encode whether the
- * operation clears, preserves, or injects the stream property;</li>
+ * operation clears, preserves, or injects a stream property,
+ * or whether the operation sets a stream operation property; and</li>
+ * <li>The combined stream and operation form, where two bits are used to encode whether a
+ * stream property is set, preserved or cleared, or whether a stream operation property is set.</li>
  * </ul>
- *
+ * <p/>
  * For each flag, there is an enum value ({@code SIZED}) as well as derived constants for
  * set ({@code IS_SIZED}) and cleared ({@code NOT_SIZED}).  To construct the stream form
  * of flags, OR together the {@code IS} flags ({@code IS_SORTED | IS_DISTINCT}), or to
  * clear, mask off the {@code IS} flags.  To construct the operation form, you need to
  * OR together the {@code IS} or {@code NOT} forms.
- *
+ * <p/>
  * To combine the stream bitmap with the operation bitmap for one or more operations, first
- * combine all the operation bitmaps using {@code combineOpFlags}, and then combine the
- * stream bitmap with the combined operation bitmap with {@code combineStreamFlags}.
- *
+ * combine all the operation bitmaps using {@link #combineOpFlags(int, int) }, then combine the
+ * stream bitmap with the combined operation bitmap with {@link #combineStreamFlags(int, int) },
+ * and finally get the stream flags from the combined stream and operations bitmap with
+ * {@link #getStreamFlags(int) }.
  */
 // @@@ When a new flag is added what should happen for existing operations?
 //     Need to move to a builder approach used by ops where the masks for the new flag are
@@ -284,7 +289,7 @@
      * @param opFlags the operation flags.
      * @param opsFlags previously combined operation flags.
      *                 The value {#link INITIAL_OPS_VALUE} must be used as the seed value.
-     * @return the result of combination.
+     * @return the combined operations flags.
      */
     public static int combineOpFlags(int opFlags, int opsFlags) {
         // 0x01 or 0x10 nibbles are transformed to 0x11
@@ -301,22 +306,22 @@
      *
      * @param streamFlags the stream flags.
      * @param opsFlags the combined operation flags.
-     * @return the result of combination.
+     * @return the combined stream and operations flags.
      */
     public static int combineStreamFlags(int streamFlags, int opsFlags) {
         // For stream flags all 0x00 nibbles are transformed to 0x11
-        // Then the result is logically and'ed with the combined operation flags
+        // Then the result is AND'ed with the combined operation flags
         // 0x01 nibbles correspond to set flags
         return (FLAG_MASK ^ ((FLAG_MASK_IS & streamFlags) << 1)) & opsFlags;
     }
 
     /**
-     * Obtain flags that can be set on a stream given combined stream and operation flags.
+     * Obtain the stream flags from the combined stream and operations flags.
      *
-     * @param flags the combined stream and operation flags.
-     * @return flags for a stream, all known properties are propagated and all not-known properties are ignored.
+     * @param flags the combined stream and operations flags.
+     * @return the stream flags.
      */
-    public static int flagsToStreamFlags(int flags) {
+    public static int getStreamFlags(int flags) {
         // By flipping the nibbles 0x11 become 0x00 and 0x01 become 0x10
         // Shift left 1 to restore set flags and mask off anything other than the set flags
         return ((~flags) >> 1) & FLAG_MASK_IS & flags;
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/StreamFlagsTest.java	Mon Nov 19 18:05:09 2012 -0500
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/StreamFlagsTest.java	Tue Nov 20 13:53:19 2012 +0100
@@ -75,9 +75,9 @@
         assertFlags(hashSet.getStreamFlags(),
                     EnumSet.of(SIZED, DISTINCT),
                     EnumSet.of(ORDERED, SORTED, SHORT_CIRCUIT, PARALLEL));
-//        assertFlags(treeSet.getStreamFlags(),
-//                    EnumSet.of(SIZED, DISTINCT, SORTED),
-//                    EnumSet.of(ORDERED, SHORT_CIRCUIT, PARALLEL));
+        assertFlags(treeSet.getStreamFlags(),
+                    EnumSet.of(ORDERED, SIZED, DISTINCT, SORTED),
+                    EnumSet.of(SHORT_CIRCUIT, PARALLEL));
         assertFlags(linkedHashSet.getStreamFlags(),
                     EnumSet.of(ORDERED, DISTINCT, SIZED),
                     EnumSet.of(SORTED, SHORT_CIRCUIT, PARALLEL));
@@ -86,13 +86,13 @@
                     EnumSet.of(SIZED, DISTINCT, SORTED, SHORT_CIRCUIT, PARALLEL));
     }
 
-//    @@@ Failing due to unexpected extra bits in output
-//    public void testFilter() {
-//        for (Stream<?> s : streams) {
-//            int baseFlags = s.getStreamFlags();
-//            int filteredFlags = s.filter((Object e) -> true).getStreamFlags();
-//            int expectedFlags = SIZED.clearFromFlags(baseFlags);
-//            assertEquals(expectedFlags, baseFlags);
-//        }
-//    }
+    public void testFilter() {
+        for (Stream<?> s : streams) {
+            int baseFlags = s.getStreamFlags();
+            int filteredFlags = s.filter((Object e) -> true).getStreamFlags();
+            int expectedFlags = SIZED.clearFromFlags(baseFlags);
+
+            assertEquals(filteredFlags, expectedFlags);
+        }
+    }
 }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/StreamOpFlagsTest.java	Mon Nov 19 18:05:09 2012 -0500
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/StreamOpFlagsTest.java	Tue Nov 20 13:53:19 2012 +0100
@@ -37,33 +37,32 @@
 @Test
 public class StreamOpFlagsTest {
 
-//    @@@ Failing due to unexpected extra bits in output
-//    public void testNullCombine() {
-//        int sourceFlags = StreamOpFlags.IS_SIZED;
-//        int opFlags = StreamOpFlags.INITIAL_OPS_VALUE;
-//        assertEquals(sourceFlags, StreamOpFlags.combineStreamFlags(sourceFlags, opFlags));
-//    }
-//
-//    public void testSameCombine() {
-//        int sourceFlags = StreamOpFlags.IS_SIZED;
-//        int opFlags = StreamOpFlags.INITIAL_OPS_VALUE;
-//        opFlags = StreamOpFlags.combineOpFlags(opFlags, StreamOpFlags.IS_SIZED);
-//        assertEquals(sourceFlags, StreamOpFlags.combineStreamFlags(sourceFlags, opFlags));
-//    }
-//
-//    public void testOpClear() {
-//        int sourceFlags = StreamOpFlags.IS_SIZED;
-//        int opFlags = StreamOpFlags.INITIAL_OPS_VALUE;
-//        opFlags = StreamOpFlags.combineOpFlags(opFlags, StreamOpFlags.NOT_SIZED);
-//        assertEquals(0, StreamOpFlags.combineStreamFlags(sourceFlags, opFlags));
-//    }
-//
-//    public void testOpInject() {
-//        int sourceFlags = 0;
-//        int opFlags = StreamOpFlags.INITIAL_OPS_VALUE;
-//        opFlags = StreamOpFlags.combineOpFlags(opFlags, StreamOpFlags.IS_SIZED);
-//        assertEquals(StreamOpFlags.IS_SIZED, StreamOpFlags.combineStreamFlags(sourceFlags, opFlags));
-//    }
+    public void testNullCombine() {
+        int sourceFlags = StreamOpFlags.IS_SIZED;
+        int opsFlags = StreamOpFlags.INITIAL_OPS_VALUE;
+        assertEquals(sourceFlags, StreamOpFlags.getStreamFlags(StreamOpFlags.combineStreamFlags(sourceFlags, opsFlags)));
+    }
+
+    public void testSameCombine() {
+        int sourceFlags = StreamOpFlags.IS_SIZED;
+        int opsFlags = StreamOpFlags.INITIAL_OPS_VALUE;
+        opsFlags = StreamOpFlags.combineOpFlags(StreamOpFlags.IS_SIZED, opsFlags);
+        assertEquals(sourceFlags, StreamOpFlags.getStreamFlags(StreamOpFlags.combineStreamFlags(sourceFlags, opsFlags)));
+    }
+
+    public void testOpClear() {
+        int sourceFlags = StreamOpFlags.IS_SIZED;
+        int opsFlags = StreamOpFlags.INITIAL_OPS_VALUE;
+        opsFlags = StreamOpFlags.combineOpFlags(StreamOpFlags.NOT_SIZED, opsFlags);
+        assertEquals(0, StreamOpFlags.getStreamFlags(StreamOpFlags.combineStreamFlags(sourceFlags, opsFlags)));
+    }
+
+    public void testOpInject() {
+        int sourceFlags = 0;
+        int opsFlags = StreamOpFlags.INITIAL_OPS_VALUE;
+        opsFlags = StreamOpFlags.combineOpFlags(StreamOpFlags.IS_SIZED, opsFlags);
+        assertEquals(StreamOpFlags.IS_SIZED, StreamOpFlags.getStreamFlags(StreamOpFlags.combineStreamFlags(sourceFlags, opsFlags)));
+    }
 
     public void test() {
         int sourceFlags = StreamOpFlags.IS_SIZED | StreamOpFlags.IS_DISTINCT;