changeset 5985:924765645619 it2-bootstrap

Minimal Test of ForEachOp with linear and map shaped datasets.
author mduigou
date Thu, 06 Sep 2012 13:07:52 -0700
parents a826f7ac7136
children 893f8c8ab82b
files src/share/classes/java/util/HashMap.java src/share/classes/java/util/MapIterator.java src/share/classes/java/util/Mapping.java src/share/classes/java/util/streams/ops/AllMatchOp.java src/share/classes/java/util/streams/ops/ForEachOp.java test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java test-ng/tests/org/openjdk/tests/java/util/streams/MapStreamTestDataProvider.java test-ng/tests/org/openjdk/tests/java/util/streams/ops/ForEachOpTest.java test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java
diffstat 9 files changed, 145 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/HashMap.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/src/share/classes/java/util/HashMap.java	Thu Sep 06 13:07:52 2012 -0700
@@ -703,7 +703,7 @@
         return result;
     }
 
-    static class Entry<K,V> implements Map.Entry<K,V> {
+    static class Entry<K,V> extends Mapping.AbstractMapping<K,V> implements Map.Entry<K,V> {
         final K key;
         V value;
         Entry<K,V> next;
@@ -733,26 +733,6 @@
             return oldValue;
         }
 
-        public final boolean equals(Object o) {
-            if (!(o instanceof Map.Entry))
-                return false;
-            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
-            Object k1 = getKey();
-            Object k2 = e.getKey();
-            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
-                Object v1 = getValue();
-                Object v2 = e.getValue();
-                if (v1 == v2 || (v1 != null && v1.equals(v2)))
-                    return true;
-            }
-            return false;
-        }
-
-        public final int hashCode() {
-            return (key==null   ? 0 : key.hashCode()) ^
-                   (value==null ? 0 : value.hashCode());
-        }
-
         public final String toString() {
             return getKey() + "=" + getValue();
         }
@@ -855,7 +835,7 @@
 
     private final class ValueIterator extends HashIterator<V> {
         public V next() {
-            return nextEntry().value;
+            return nextEntry().getValue();
         }
     }
 
--- a/src/share/classes/java/util/MapIterator.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/src/share/classes/java/util/MapIterator.java	Thu Sep 06 13:07:52 2012 -0700
@@ -112,6 +112,7 @@
 
         @Override
         public Mapping<K, V> next() {
+            System.out.println("MapIterator.IteratorAdapter.next() called");
             current = source.next();
             return current;
         }
--- a/src/share/classes/java/util/Mapping.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/src/share/classes/java/util/Mapping.java	Thu Sep 06 13:07:52 2012 -0700
@@ -63,10 +63,10 @@
          * @return {@code true} if the specified object is equal to this map entry
          */
         @Override
-        public boolean equals(Object other) {
+        public final boolean equals(Object other) {
             if (other instanceof Mapping) {
                 @SuppressWarnings("raw")
-                Mapping likeMe = (Mapping)other;
+                Mapping likeMe = (Mapping) other;
                 return Objects.equals(getKey(), likeMe.getKey())
                         && Objects.equals(getValue(), likeMe.getValue());
             }
@@ -84,17 +84,22 @@
          * {@code e2}, as required by the general contract of
          * {@code Object.hashCode}
          *
-         * @return the hash code value for this map entry
+         * @return the hash code value for this mapping
          * @see Object#hashCode()
          * @see Object#equals(Object)
          * @see #equals(Object)
          */
         @Override
-        public int hashCode() {
+        public final int hashCode() {
             return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
         }
     }
 
+    /**
+     * A simple {@code Mapping} instance.
+     * @param <K>
+     * @param <V>
+     */
     public static class MappingValue<K, V> extends AbstractMapping<K, V> {
         private final K k;
         private final V v;
--- a/src/share/classes/java/util/streams/ops/AllMatchOp.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/AllMatchOp.java	Thu Sep 06 13:07:52 2012 -0700
@@ -25,7 +25,9 @@
 package java.util.streams.ops;
 
 import java.util.Iterator;
+import java.util.MapIterator;
 import java.util.Objects;
+import java.util.functions.BiPredicate;
 import java.util.functions.Predicate;
 
 /**
@@ -54,4 +56,15 @@
 
         return true;
     }
+    
+    public static <K,V> boolean allMatch(MapIterator<K,V> iterator, BiPredicate<? super K, ? super V> predicate) {
+        while (iterator.hasNext()) {
+            if(!predicate.test(iterator.nextKey(), iterator.curValue())) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
 }
--- a/src/share/classes/java/util/streams/ops/ForEachOp.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/ForEachOp.java	Thu Sep 06 13:07:52 2012 -0700
@@ -44,11 +44,12 @@
     private final Stream.Shape shape;
 
     protected ForEachOp(TerminalSink<T, Void> sink, Stream.Shape shape) {
-        this.shape = shape;
+        this.shape = Objects.requireNonNull(shape);
         this.sink = Objects.requireNonNull(sink);
     }
 
     public static<T> ForEachOp<T> make(final Block<? super T> block) {
+        Objects.requireNonNull(block);
         return new ForEachOp<>(new TerminalSink<T, Void>() {
          @Override
             public void accept(T t) {
@@ -72,6 +73,8 @@
 
             @Override
             public void accept(Mapping<K, V> mapping) {
+                System.out.println("ForEachOp.accept(Mapping) called.");
+                Thread.dumpStack();
                 block.apply(mapping.getKey(), mapping.getValue());
             }
 
--- a/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java	Thu Sep 06 13:07:52 2012 -0700
@@ -38,6 +38,10 @@
 public class LambdaTestHelpers {
     public static final String LONG_STRING = "When in the Course of human events it becomes necessary for one people to dissolve the political bands which have connected them with another and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.";
 
+    public static final Block bEmpty = x -> { Objects.hashCode(x); };
+    public static final BiBlock bBiEmpty = (x,y) -> { Objects.hash(x, y); };
+    public static final Block bHashCode = x -> { Objects.hashCode(x); };
+    public static final BiBlock bBiHashCode = (x,y) -> { Objects.hash(x, y); };
     public static final Mapper<Integer, Integer> mZero = x -> 0;
     public static final Mapper<Integer, Integer> mId = x -> x;
     public static final Mapper<Integer, Integer> mDoubler = x -> x * 2;
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/MapStreamTestDataProvider.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/MapStreamTestDataProvider.java	Thu Sep 06 13:07:52 2012 -0700
@@ -74,7 +74,13 @@
         ConcurrentHashMap.class,
         ConcurrentSkipListMap.class
     };
-    private static final int[] SIZES = {0, 1, 10, 100, 1000};
+    private static final int[] SIZES = {
+        0,
+        1,
+        10,
+        100,
+        1000
+    };
     private static final Object[][] TEST_DATA;
 
     static {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/ForEachOpTest.java	Thu Sep 06 13:07:52 2012 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.streams.ops;
+
+import java.util.List;
+import java.util.streams.ops.ForEachOp;
+import org.openjdk.tests.java.util.streams.StreamTestDataProvider;
+import org.testng.annotations.Test;
+
+import java.util.functions.Block;
+import java.util.streams.Streams;
+
+import static org.openjdk.tests.java.util.LambdaTestHelpers.*;
+import org.openjdk.tests.java.util.streams.MapStreamTestDataProvider;
+
+/**
+ * MapOpTest
+ */
+@Test
+public class ForEachOpTest extends StreamOpTestCase {
+
+    @Test(dataProvider = "opArrays", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData<Integer> data) {
+        exerciseOps(data, ForEachOp.<Integer>make(bEmpty));
+    }
+
+    @Test(dataProvider = "opMaps", dataProviderClass = MapStreamTestDataProvider.class)
+    public void testOps(String name, MapTestData<Integer,?> data) {
+        exerciseOps(data, ForEachOp.make(bBiEmpty));
+    }
+}
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java	Wed Sep 05 18:19:53 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java	Thu Sep 06 13:07:52 2012 -0700
@@ -179,6 +179,57 @@
         return answer;
     }
 
+    protected <K, V, U> U exerciseOps(MapTestData<K,V> data, TerminalOp<Mapping<K,V>, U> terminal) {
+        return exerciseOps(data, terminal, new IntermediateOp[0]);
+    }
+
+    protected <K, V, U> U exerciseOps(MapTestData<K,V> data, TerminalOp<Mapping<K,V>, U> terminal, IntermediateOp... ops) {
+        // @@@ Compiler bug if lambda literal used. Fine as a local.
+        BiPredicate<U,U> equalator = (u, v) -> Objects.equals(u,v);
+        return exerciseOps(data, equalator, terminal, ops);
+    }
+
+    @SuppressWarnings({ "raw", "unchecked" })
+    protected static <K, V, U> U exerciseOps(MapTestData<K,V> data,
+                                          BiPredicate<U, U> equalator,
+                                          TerminalOp<Mapping<K,V>, U> terminalOp,
+                                          IntermediateOp[] ops) {
+        final U answer;
+
+        if (terminalOp.isShortCircuit()) {
+            // First pass -- wrap Iterator
+            answer = terminalOp.evaluate(data.iterator());
+        }
+        else {
+            // First pass -- create a sink and evaluate, with no size advice
+            TerminalSink<Mapping<K,V>, U> terminalSink = terminalOp.sink();
+            Sink<Mapping<K,V>, ?, ?> sink = sink(terminalSink, ops);
+            sink.begin(-1);
+            data.forEach((BiBlock<K,V>) sink);
+            sink.end();
+            answer = terminalSink.getAndClearState();
+
+            // Create a sink and evaluate, with size advice
+            TerminalSink<Mapping<K,V>, U> terminalSink2 = terminalOp.sink();
+            Sink<Mapping<K,V>, ?, ?> sink2 = sink(terminalSink2, ops);
+            sink2.begin(data.size());
+            data.forEach((BiBlock<K,V>) sink2);
+            sink2.end();
+            U answer2 = terminalSink2.getAndClearState();
+            assertTrue(equalator.test(answer, answer2));
+        }
+
+        // Third pass -- wrap with SequentialPipeline.op
+        U answer3 = data.seq(terminalOp, ops);
+        assertTrue(equalator.test(answer, answer3));
+
+        // Fourth pass -- wrap with ParallelPipeline.op
+        U answer4 = data.par(terminalOp, ops);
+        assertTrue(equalator.test(answer, answer4));
+
+        return answer;
+    }
+
     protected static <U> void assertEquals(StreamResult<U> sink1, StreamResult<U> sink2) {
         try {
             assertEquals(sink1.size(), sink2.size());
@@ -503,7 +554,7 @@
         }
 
         @Override
-        public Iterator<Mapping<K,V>> iterator() {
+        public MapIterator<K,V> iterator() {
             return map.iterator();
         }