changeset 7281:c20d8fb25a17

Clean up FindOp
author briangoetz
date Tue, 05 Feb 2013 14:07:23 -0500
parents 57f32115652d
children ad394630273b
files src/share/classes/java/util/stream/DoublePipeline.java src/share/classes/java/util/stream/FindOp.java src/share/classes/java/util/stream/IntPipeline.java src/share/classes/java/util/stream/LongPipeline.java src/share/classes/java/util/stream/ReferencePipeline.java
diffstat 5 files changed, 76 insertions(+), 210 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/DoublePipeline.java	Tue Feb 05 11:52:03 2013 -0500
+++ b/src/share/classes/java/util/stream/DoublePipeline.java	Tue Feb 05 14:07:23 2013 -0500
@@ -227,12 +227,12 @@
 
     @Override
     public OptionalDouble findFirst() {
-        return pipeline(FindOp.OfDouble.first());
+        return pipeline(FindOp.makeDouble(true));
     }
 
     @Override
     public OptionalDouble findAny() {
-        return pipeline(FindOp.OfDouble.any());
+        return pipeline(FindOp.makeDouble(false));
     }
 
     @Override
--- a/src/share/classes/java/util/stream/FindOp.java	Tue Feb 05 11:52:03 2013 -0500
+++ b/src/share/classes/java/util/stream/FindOp.java	Tue Feb 05 14:07:23 2013 -0500
@@ -26,243 +26,109 @@
 
 import java.util.*;
 import java.util.concurrent.CountedCompleter;
+import java.util.function.Predicate;
 import java.util.function.Supplier;
 
-abstract class FindOp<T, O> implements TerminalOp<T, O> {
-    public static final class OfReference<T> extends FindOp<T, Optional<T>> {
+class FindOp<T, O> implements TerminalOp<T, O> {
 
-        public static <T> FindOp<T, Optional<T>> any() {
-            return new OfReference<>(FindKind.ANY);
-        }
+    public static<T> FindOp<T, Optional<T>> makeRef(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.REFERENCE, Optional.empty(), Optional::isPresent, FindSink.OfRef::new);
+    }
 
-        public static <T> FindOp<T, Optional<T>> first() {
-            return new OfReference<>(FindKind.FIRST);
-        }
+    public static FindOp<Integer, OptionalInt> makeInt(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.INT_VALUE, OptionalInt.empty(), OptionalInt::isPresent, FindSink.OfInt::new);
+    }
 
-        private OfReference(FindKind findKind) {
-            super(findKind, StreamShape.REFERENCE);
+    public static FindOp<Long, OptionalLong> makeLong(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.LONG_VALUE, OptionalLong.empty(), OptionalLong::isPresent, FindSink.OfLong::new);
+    }
+
+    public static FindOp<Double, OptionalDouble> makeDouble(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.DOUBLE_VALUE, OptionalDouble.empty(), OptionalDouble::isPresent, FindSink.OfDouble::new);
+    }
+
+    static abstract class FindSink<T, O> implements TerminalSink<T, O> {
+        boolean hasValue;
+        T value;
+
+        @Override
+        public void accept(T value) {
+            if (!hasValue) {
+                hasValue = true;
+                this.value = value;
+            }
         }
 
         @Override
-        protected Optional<T> emptyResult() {
-            return Optional.empty();
+        public boolean cancellationRequested() {
+            return hasValue;
         }
 
-        @Override
-        protected boolean isPresent(Optional<T> optional) {
-            return optional.isPresent();
-        }
-
-        static class FindSink<T> implements TerminalSink<T, Optional<T>> {
-            boolean hasValue;
-            T value;
-
+        static class OfRef<T> extends FindSink<T, Optional<T>> {
             @Override
             public Optional<T> getAndClearState() {
                 return hasValue ? Optional.of(value) : null;
             }
-
-            @Override
-            public void accept(T value) {
-                // @@@ assert !hasValue when SortedOp supports short-circuit on Sink.end
-                //     for sequential operations
-                if (!hasValue) {
-                    hasValue = true;
-                    this.value = value;
-                }
-            }
-
-            @Override
-            public boolean cancellationRequested() {
-                return hasValue;
-            }
-        };
-
-        protected Supplier<TerminalSink<T, Optional<T>>> sinkSupplier() {
-            // @@@ Change to return FindSink::new when runtime bug fixed
-            return () -> new FindSink();
-        }
-    }
-
-    public static final class OfInt extends FindOp<Integer, OptionalInt> {
-
-        public static FindOp<Integer, OptionalInt> any() {
-            return new OfInt(FindKind.ANY);
         }
 
-        public static FindOp<Integer, OptionalInt> first() {
-            return new OfInt(FindKind.FIRST);
-        }
-
-        private OfInt(FindKind findKind) {
-            super(findKind, StreamShape.INT_VALUE);
-        }
-
-        @Override
-        protected OptionalInt emptyResult() {
-            return OptionalInt.empty();
-        }
-
-        @Override
-        protected boolean isPresent(OptionalInt optional) {
-            return optional.isPresent();
-        }
-
-        static class FindSink implements TerminalSink<Integer, OptionalInt>, Sink.OfInt {
-            boolean hasValue;
-            int value;
+        static class OfInt extends FindSink<Integer, OptionalInt> implements Sink.OfInt {
+            @Override
+            public void accept(int value) {
+                accept((Integer) value);
+            }
 
             @Override
             public OptionalInt getAndClearState() {
                 return hasValue ? OptionalInt.of(value) : null;
             }
-
-            @Override
-            public void accept(int value) {
-                if (!hasValue) {
-                    hasValue = true;
-                    this.value = value;
-                }
-            }
-
-            @Override
-            public boolean cancellationRequested() {
-                return hasValue;
-            }
-        };
-
-        protected Supplier<TerminalSink<Integer, OptionalInt>> sinkSupplier() {
-            return () -> new FindSink();
-        }
-    }
-
-    public static final class OfLong extends FindOp<Long, OptionalLong> {
-
-        public static FindOp<Long, OptionalLong> any() {
-            return new OfLong(FindKind.ANY);
         }
 
-        public static FindOp<Long, OptionalLong> first() {
-            return new OfLong(FindKind.FIRST);
-        }
-
-        private OfLong(FindKind findKind) {
-            super(findKind, StreamShape.LONG_VALUE);
-        }
-
-        @Override
-        protected OptionalLong emptyResult() {
-            return OptionalLong.empty();
-        }
-
-        @Override
-        protected boolean isPresent(OptionalLong optional) {
-            return optional.isPresent();
-        }
-
-        static class FindSink implements TerminalSink<Long, OptionalLong>, Sink.OfLong {
-            boolean hasValue;
-            long value;
+        static class OfLong extends FindSink<Long, OptionalLong> implements Sink.OfLong {
+            @Override
+            public void accept(long value) {
+                accept((Long) value);
+            }
 
             @Override
             public OptionalLong getAndClearState() {
                 return hasValue ? OptionalLong.of(value) : null;
             }
-
-            @Override
-            public void accept(long value) {
-                if (!hasValue) {
-                    hasValue = true;
-                    this.value = value;
-                }
-            }
-
-            @Override
-            public boolean cancellationRequested() {
-                return hasValue;
-            }
-        };
-
-        protected Supplier<TerminalSink<Long, OptionalLong>> sinkSupplier() {
-            return () -> new FindSink();
-        }
-    }
-
-    public static final class OfDouble extends FindOp<Double, OptionalDouble> {
-
-        public static FindOp<Double, OptionalDouble> any() {
-            return new OfDouble(FindKind.ANY);
         }
 
-        public static FindOp<Double, OptionalDouble> first() {
-            return new OfDouble(FindKind.FIRST);
-        }
-
-        private OfDouble(FindKind findKind) {
-            super(findKind, StreamShape.DOUBLE_VALUE);
-        }
-
-        @Override
-        protected OptionalDouble emptyResult() {
-            return OptionalDouble.empty();
-        }
-
-        @Override
-        protected boolean isPresent(OptionalDouble optional) {
-            return optional.isPresent();
-        }
-
-        static class FindSink implements TerminalSink<Double, OptionalDouble>, Sink.OfDouble {
-            boolean hasValue;
-            double value;
+        static class OfDouble extends FindSink<Double, OptionalDouble> implements Sink.OfDouble {
+            @Override
+            public void accept(double value) {
+                accept((Double) value);
+            }
 
             @Override
             public OptionalDouble getAndClearState() {
                 return hasValue ? OptionalDouble.of(value) : null;
             }
-
-            @Override
-            public void accept(double value) {
-                if (!hasValue) {
-                    hasValue = true;
-                    this.value = value;
-                }
-            }
-
-            @Override
-            public boolean cancellationRequested() {
-                return hasValue;
-            }
-        };
-
-        protected Supplier<TerminalSink<Double, OptionalDouble>> sinkSupplier() {
-            return () -> new FindSink();
         }
     }
 
-    private enum FindKind {
-        ANY,
-        FIRST
+    private final boolean mustFindFirst;
+    private final StreamShape shape;
+    private final O emptyValue;
+    private final Predicate<O> presentPredicate;
+    private final Supplier<TerminalSink<T, O>> sinkSupplier;
+
+    private FindOp(boolean mustFindFirst,
+                   StreamShape shape,
+                   O emptyValue,
+                   Predicate<O> presentPredicate,
+                   Supplier<TerminalSink<T, O>> sinkSupplier) {
+        this.mustFindFirst = mustFindFirst;
+        this.shape = shape;
+        this.emptyValue = emptyValue;
+        this.presentPredicate = presentPredicate;
+        this.sinkSupplier = sinkSupplier;
     }
 
-    private final FindKind findKind;
-
-    private final StreamShape shape;
-
-    private FindOp(FindKind findKind, StreamShape shape) {
-        this.findKind = findKind;
-        this.shape = shape;
-    }
-
-    protected abstract O emptyResult();
-
-    protected abstract boolean isPresent(O optional);
-
-    protected abstract Supplier<TerminalSink<T, O>> sinkSupplier();
-
     @Override
     public int getOpFlags() {
-        return StreamOpFlag.IS_SHORT_CIRCUIT | (findKind == FindKind.ANY ? StreamOpFlag.NOT_ORDERED : 0);
+        return StreamOpFlag.IS_SHORT_CIRCUIT | (mustFindFirst ? 0 : StreamOpFlag.NOT_ORDERED);
     }
 
     @Override
@@ -272,8 +138,8 @@
 
     @Override
     public <S> O evaluateSequential(PipelineHelper<S, T> helper) {
-        O result = helper.into(sinkSupplier().get(), helper.sourceSpliterator()).getAndClearState();
-        return result != null ? result : emptyResult();
+        O result = helper.into(sinkSupplier.get(), helper.sourceSpliterator()).getAndClearState();
+        return result != null ? result : emptyValue;
     }
 
     @Override
@@ -301,7 +167,7 @@
 
         @Override
         protected O getEmptyResult() {
-            return op.emptyResult();
+            return op.emptyValue;
         }
 
         private void foundResult(O answer) {
@@ -313,8 +179,8 @@
 
         @Override
         protected O doLeaf() {
-            O result = helper.into(op.sinkSupplier().get(), spliterator).getAndClearState();
-            if (op.findKind == FindKind.ANY) {
+            O result = helper.into(op.sinkSupplier.get(), spliterator).getAndClearState();
+            if (!op.mustFindFirst) {
                 if (result != null)
                     shortCircuit(result);
                 return null;
@@ -331,10 +197,10 @@
 
         @Override
         public void onCompletion(CountedCompleter<?> caller) {
-            if (op.findKind == FindKind.FIRST) {
+            if (op.mustFindFirst) {
                 for (FindTask<S, T, O> child = children; child != null; child = child.nextSibling) {
                     O result = child.getLocalResult();
-                    if (result != null && op.isPresent(result)) {
+                    if (result != null && op.presentPredicate.test(result)) {
                         setLocalResult(result);
                         foundResult(result);
                         break;
--- a/src/share/classes/java/util/stream/IntPipeline.java	Tue Feb 05 11:52:03 2013 -0500
+++ b/src/share/classes/java/util/stream/IntPipeline.java	Tue Feb 05 14:07:23 2013 -0500
@@ -252,12 +252,12 @@
 
     @Override
     public OptionalInt findFirst() {
-        return pipeline(FindOp.OfInt.first());
+        return pipeline(FindOp.makeInt(true));
     }
 
     @Override
     public OptionalInt findAny() {
-        return pipeline(FindOp.OfInt.any());
+        return pipeline(FindOp.makeInt(false));
     }
 
     @Override
--- a/src/share/classes/java/util/stream/LongPipeline.java	Tue Feb 05 11:52:03 2013 -0500
+++ b/src/share/classes/java/util/stream/LongPipeline.java	Tue Feb 05 14:07:23 2013 -0500
@@ -240,12 +240,12 @@
 
     @Override
     public OptionalLong findFirst() {
-        return pipeline(FindOp.OfLong.first());
+        return pipeline(FindOp.makeLong(true));
     }
 
     @Override
     public OptionalLong findAny() {
-        return pipeline(FindOp.OfLong.any());
+        return pipeline(FindOp.makeLong(false));
     }
 
     @Override
--- a/src/share/classes/java/util/stream/ReferencePipeline.java	Tue Feb 05 11:52:03 2013 -0500
+++ b/src/share/classes/java/util/stream/ReferencePipeline.java	Tue Feb 05 14:07:23 2013 -0500
@@ -254,12 +254,12 @@
 
     @Override
     public Optional<U> findFirst() {
-        return pipeline(FindOp.OfReference.first());
+        return pipeline(FindOp.makeRef(true));
     }
 
     @Override
     public Optional<U> findAny() {
-        return pipeline(FindOp.OfReference.any());
+        return pipeline(FindOp.makeRef(false));
     }
 
     @Override