You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2010/06/03 19:21:56 UTC

svn commit: r951074 - in /tapestry/tapestry5/trunk/tapestry-func/src: main/java/org/apache/tapestry5/func/ test/java/org/apache/tapestry5/func/

Author: hlship
Date: Thu Jun  3 17:21:55 2010
New Revision: 951074

URL: http://svn.apache.org/viewvc?rev=951074&view=rev
Log:
Add a drop() method to Flow

Added:
    tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyDrop.java   (contents, props changed)
      - copied, changed from r950889, tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncAssert.java
    tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/BaseFuncTest.java   (with props)
    tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/TakeDropTests.java   (with props)
Removed:
    tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncAssert.java
    tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/TakeTests.java
Modified:
    tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/AbstractFlow.java
    tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/ArrayFlow.java
    tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/EmptyFlow.java
    tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/Flow.java
    tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncTest.java
    tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/RangeTests.java

Modified: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/AbstractFlow.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/AbstractFlow.java?rev=951074&r1=951073&r2=951074&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/AbstractFlow.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/AbstractFlow.java Thu Jun  3 17:21:55 2010
@@ -201,4 +201,13 @@ abstract class AbstractFlow<T> implement
         return F.lazy(new LazyTake<T>(length, this));
     }
 
+    public Flow<T> drop(int length)
+    {
+        assert length >= 0;
+
+        if (length == 0)
+            return this;
+
+        return F.lazy(new LazyDrop<T>(length, this));
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/ArrayFlow.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/ArrayFlow.java?rev=951074&r1=951073&r2=951074&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/ArrayFlow.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/ArrayFlow.java Thu Jun  3 17:21:55 2010
@@ -186,4 +186,16 @@ class ArrayFlow<T> extends AbstractFlow<
         return new ArrayFlow<T>(values, start, Math.min(count, length));
     }
 
+    public Flow<T> drop(int length)
+    {
+        assert length >= 0;
+
+        if (length == 0)
+            return this;
+
+        if (length >= count)
+            return F.emptyFlow();
+
+        return new ArrayFlow<T>(values, start + length, count - length);
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/EmptyFlow.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/EmptyFlow.java?rev=951074&r1=951073&r2=951074&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/EmptyFlow.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/EmptyFlow.java Thu Jun  3 17:21:55 2010
@@ -115,4 +115,9 @@ class EmptyFlow<T> extends AbstractFlow<
     {
         return this;
     }
+
+    public Flow<T> drop(int length)
+    {
+        return this;
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/Flow.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/Flow.java?rev=951074&r1=951073&r2=951074&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/Flow.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/Flow.java Thu Jun  3 17:21:55 2010
@@ -18,7 +18,7 @@ import java.util.Comparator;
 import java.util.List;
 
 /**
- * A Flow is a a functional interface for working with a ordered collection of values.
+ * A Flow is a a functional interface for working with an ordered collection of values.
  * A given Flow contains only values of a particular type. Standard operations allow for
  * filtering the Flow, or appending values to the Flow. Since Flows are immutable, all operations
  * on Flows return new immutable Flows. Flows are thread safe (to the extent that the {@link Mapper}s, {@link Predicate}
@@ -26,11 +26,15 @@ import java.util.List;
  * Flows are <em>lazy</em>: filtering, mapping, and concatenating Flows will do so with no, or a minimum, of evaluation.
  * However, converting a Flow into a {@link List} will force a realization of the entire Flow.
  * <p>
+ * In some cases, a Flow may be an infinite, lazily evaluated sequence. Operations that iterate over all values (such as
+ * {@link #count()} or {@link #reduce(Reducer, Object)}) may become infinite loops.
+ * <p>
  * Using Flows allows for a very fluid interface.
  * <p>
  * Flows are initially created using {@link F#flow(java.util.Collection)} or {@link F#flow(Object...)}.
  * 
  * @since 5.2.0
+ * @see F#lazy(LazyFunction)
  */
 public interface Flow<T> extends Iterable<T>
 {
@@ -131,4 +135,12 @@ public interface Flow<T> extends Iterabl
      *            maximum number of values in the Flow
      */
     Flow<T> take(int length);
+
+    /**
+     * Returns a new Flow with the first values omitted.
+     * 
+     * @param length
+     *            number of values to drop
+     */
+    Flow<T> drop(int length);
 }

Copied: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyDrop.java (from r950889, tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncAssert.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyDrop.java?p2=tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyDrop.java&p1=tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncAssert.java&r1=950889&r2=951074&rev=951074&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncAssert.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyDrop.java Thu Jun  3 17:21:55 2010
@@ -14,27 +14,34 @@
 
 package org.apache.tapestry5.func;
 
-import java.util.Arrays;
-import java.util.List;
-
-import org.testng.Assert;
-
-public class FuncAssert extends Assert
+class LazyDrop<T> implements LazyFunction<T>
 {
+    private final int length;
 
-    protected <T> void assertFlowValues(Flow<T> actual, T... expected)
-    {
-        assertListsEquals(actual.toList(), expected);
-    }
+    private Flow<T> flow;
 
-    protected <T> void assertListsEquals(List<T> actual, T... expected)
+    public LazyDrop(int length, Flow<T> flow)
     {
-        assertEquals(actual, Arrays.asList(expected));
+        this.length = length;
+        this.flow = flow;
     }
 
-    protected void unreachable()
+    public LazyContinuation<T> next()
     {
-        throw new RuntimeException("Should not be reachable.");
+        for (int i = 0; i < length; i++)
+        {
+            if (flow.isEmpty())
+                return null;
+
+            flow = flow.rest();
+        }
+
+        // The case where the flow contains exactly length values.
+
+        if (flow.isEmpty())
+            return null;
+
+        return new LazyContinuation<T>(flow.first(), new LazyIterate<T>(flow.rest()));
     }
 
 }

Propchange: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyDrop.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/BaseFuncTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/BaseFuncTest.java?rev=951074&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/BaseFuncTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/BaseFuncTest.java Thu Jun  3 17:21:55 2010
@@ -0,0 +1,66 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.func;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.Assert;
+
+public class BaseFuncTest extends Assert
+{
+
+    protected Mapper<String, Integer> stringToLength = new Mapper<String, Integer>()
+    {
+        public Integer map(String input)
+        {
+            return input.length();
+        }
+    };
+
+    protected Mapper<Integer, Boolean> toEven = new Mapper<Integer, Boolean>()
+    {
+        public Boolean map(Integer input)
+        {
+            return evenp.accept(input);
+        }
+    };
+
+    protected Predicate<Number> evenp = new Predicate<Number>()
+    {
+        public boolean accept(Number object)
+        {
+            return object.longValue() % 2 == 0;
+        };
+    };
+
+    protected Flow<Integer> filteredEmpty = F.flow(1, 3, 5, 7).filter(evenp);
+
+    protected <T> void assertFlowValues(Flow<T> actual, T... expected)
+    {
+        assertListsEquals(actual.toList(), expected);
+    }
+
+    protected <T> void assertListsEquals(List<T> actual, T... expected)
+    {
+        assertEquals(actual, Arrays.asList(expected));
+    }
+
+    protected void unreachable()
+    {
+        throw new RuntimeException("Should not be reachable.");
+    }
+
+}

Propchange: tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/BaseFuncTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncTest.java?rev=951074&r1=951073&r2=951074&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncTest.java Thu Jun  3 17:21:55 2010
@@ -21,37 +21,23 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 
-import org.testng.Assert;
 import org.testng.annotations.Test;
 
-public class FuncTest extends FuncAssert
+public class FuncTest extends BaseFuncTest
 {
-
-    private Mapper<String, Integer> stringToLength = new Mapper<String, Integer>()
+    protected Mapper<Integer, Flow<Integer>> sequencer = new Mapper<Integer, Flow<Integer>>()
     {
-        public Integer map(String input)
-        {
-            return input.length();
-        }
-    };
 
-    private Mapper<Integer, Boolean> toEven = new Mapper<Integer, Boolean>()
-    {
-        public Boolean map(Integer input)
+        public Flow<Integer> map(Integer value)
         {
-            return evenp.accept(input);
-        }
-    };
+            Flow<Integer> flow = F.flow();
 
-    private Predicate<Number> evenp = new Predicate<Number>()
-    {
-        public boolean accept(Number object)
-        {
-            return object.longValue() % 2 == 0;
-        };
-    };
+            for (int i = 0; i < value; i++)
+                flow = flow.append(value);
 
-    private Flow<Integer> filteredEmpty = F.flow(1, 3, 5, 7).filter(evenp);
+            return flow;
+        }
+    };
 
     @Test
     public void map()
@@ -585,20 +571,6 @@ public class FuncTest extends FuncAssert
         }, initial), initial);
     }
 
-    private Mapper<Integer, Flow<Integer>> sequencer = new Mapper<Integer, Flow<Integer>>()
-    {
-
-        public Flow<Integer> map(Integer value)
-        {
-            Flow<Integer> flow = F.flow();
-
-            for (int i = 0; i < value; i++)
-                flow = flow.append(value);
-
-            return flow;
-        }
-    };
-
     @Test
     public void mapcat_on_empty_flow_is_empty()
     {

Modified: tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/RangeTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/RangeTests.java?rev=951074&r1=951073&r2=951074&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/RangeTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/RangeTests.java Thu Jun  3 17:21:55 2010
@@ -16,7 +16,7 @@ package org.apache.tapestry5.func;
 
 import org.testng.annotations.Test;
 
-public class RangeTests extends FuncAssert
+public class RangeTests extends BaseFuncTest
 {
     @Test
     public void empty_range_if_values_equal()
@@ -44,4 +44,12 @@ public class RangeTests extends FuncAsse
 
         assertFlowValues(series.take(5), 3, 8, 13, 18, 23);
     }
+
+    @Test
+    public void filtered_series()
+    {
+        Flow<Integer> series = F.series(1, 1);
+
+        assertFlowValues(series.filter(evenp).take(4), 2, 4, 6, 8);
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/TakeDropTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/TakeDropTests.java?rev=951074&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/TakeDropTests.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/TakeDropTests.java Thu Jun  3 17:21:55 2010
@@ -0,0 +1,93 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.func;
+
+import org.testng.annotations.Test;
+
+public class TakeDropTests extends BaseFuncTest
+{
+    @Test
+    public void take_from_empty_list()
+    {
+        assertSame(F.flow().take(34), F.EMPTY_FLOW);
+    }
+
+    @Test
+    public void take_from_flow()
+    {
+        assertFlowValues(F.series(1, 1).remove(evenp).take(2), 1, 3);
+    }
+
+    @Test
+    public void take_from_array_flow()
+    {
+        Flow<Integer> flow = F.flow(1, 2, 3, 4, 5);
+
+        assertFlowValues(flow.take(2), 1, 2);
+
+        assertFlowValues(flow.take(99), 1, 2, 3, 4, 5);
+
+        assertSame(flow.take(0), F.EMPTY_FLOW);
+    }
+
+    @Test
+    public void take_and_drop()
+    {
+        // This can go much, much larger but starts taking a while. Don't hold a reference to the start
+        // of the series or it can run out of memory.
+        int length = 100000;
+
+        assertFlowValues(F.series(1, 1).filter(evenp).drop(length).take(3), 2 * length + 2, 2 * length + 4,
+                2 * length + 6);
+    }
+
+    @Test
+    public void drop_from_empty_is_empty()
+    {
+        assertSame(F.flow().drop(99), F.EMPTY_FLOW);
+    }
+
+    @Test
+    public void drop_exact_size_of_flow_is_empty()
+    {
+        assertTrue(F.range(1, 10).filter(evenp).drop(4).isEmpty());
+    }
+
+    @Test
+    public void lazy_drop_more_than_available()
+    {
+        assertTrue(F.range(1, 10).filter(evenp).drop(5).isEmpty());
+    }
+
+    @Test
+    public void drop_all_from_array_flow_is_empty_flow()
+    {
+        assertSame(F.flow(1, 2, 3).drop(3), F.EMPTY_FLOW);
+    }
+
+    @Test
+    public void drop_zero_from_array_flow_is_same()
+    {
+        Flow<Integer> flow = F.flow(1, 2, 3);
+
+        assertSame(flow.drop(0), flow);
+    }
+
+    @Test
+    public void drop_from_array_flow()
+    {
+        assertFlowValues(F.range(1, 10).reverse().drop(2), 7, 6, 5, 4, 3, 2, 1);
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/TakeDropTests.java
------------------------------------------------------------------------------
    svn:eol-style = native