You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/06/03 08:43:58 UTC
svn commit: r950886 - 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 06:43:58 2010
New Revision: 950886
URL: http://svn.apache.org/viewvc?rev=950886&view=rev
Log:
Replace most subclasses of AbstractFlow with a new LazyFlow combined with a LazyFunction (thus isolating virtually all synchronization to a single class, LazyFlow)
Added:
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyConcat.java (with props)
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyContinuation.java (with props)
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFilter.java (with props)
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFlow.java (contents, props changed)
- copied, changed from r950828, tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/MappedFlow.java
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFunction.java (with props)
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyIterate.java (with props)
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyMapper.java (with props)
Removed:
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/ConcatFlow.java
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/FilteredFlow.java
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/MappedFlow.java
Modified:
tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/AbstractFlow.java
tapestry/tapestry5/trunk/tapestry-func/src/test/java/org/apache/tapestry5/func/FuncTest.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=950886&r1=950885&r2=950886&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 06:43:58 2010
@@ -89,9 +89,7 @@ abstract class AbstractFlow<T> implement
public Flow<T> concat(Flow<? extends T> other)
{
- // Possible optimization is to check for EmptyFlow here (but not isEmpty(),
- // so as not to prematurely realize values in the Flow).
- return new ConcatFlow<T>(this, other);
+ return lazy(new LazyConcat<T>(this, other));
}
/** Subclasses may override this for efficiency. */
@@ -111,14 +109,19 @@ abstract class AbstractFlow<T> implement
{
assert predicate != null;
- return new FilteredFlow<T>(predicate, this);
+ return lazy(new LazyFilter<T>(predicate, this));
+ }
+
+ private static <Y> Flow<Y> lazy(LazyFunction<Y> function)
+ {
+ return new LazyFlow<Y>(function);
}
public <X> Flow<X> map(Mapper<T, X> mapper)
{
assert mapper != null;
- return new MappedFlow<T, X>(mapper, this);
+ return lazy(new LazyMapper<T, X>(mapper, this));
}
public <A> A reduce(Reducer<A, T> reducer, A initial)
Added: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyConcat.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyConcat.java?rev=950886&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyConcat.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyConcat.java Thu Jun 3 06:43:58 2010
@@ -0,0 +1,41 @@
+// 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;
+
+@SuppressWarnings("unchecked")
+class LazyConcat<T> implements LazyFunction<T>
+{
+ private final Flow<T> first, second;
+
+ public LazyConcat(Flow<T> first, Flow<? extends T> second)
+ {
+ this.first = first;
+ this.second = (Flow<T>) second;
+ }
+
+ public LazyContinuation<T> next()
+ {
+ if (first.isEmpty())
+ {
+ if (second.isEmpty())
+ return null;
+
+ return new LazyContinuation<T>(second.first(), new LazyIterate<T>(second.rest()));
+ }
+
+ return new LazyContinuation<T>(first.first(), new LazyConcat<T>(first.rest(), second));
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyConcat.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyContinuation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyContinuation.java?rev=950886&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyContinuation.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyContinuation.java Thu Jun 3 06:43:58 2010
@@ -0,0 +1,46 @@
+// 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;
+
+/**
+ * The result of the evaluation of a {@link LazyFunction}.
+ *
+ * @since 5.2.0
+ */
+public class LazyContinuation<T>
+{
+ private final T nextValue;
+
+ private final LazyFunction<T> nextFunction;
+
+ public LazyContinuation(T next, LazyFunction<T> nextFunction)
+ {
+ this.nextValue = next;
+ this.nextFunction = nextFunction;
+ }
+
+ /** Returns the next value computed by the lazy function. */
+ public T nextValue()
+ {
+ return nextValue;
+ }
+
+ /** Returns a new lazy function that will return the next continuation. */
+ public LazyFunction<T> nextFunction()
+ {
+ return nextFunction;
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyContinuation.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFilter.java?rev=950886&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFilter.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFilter.java Thu Jun 3 06:43:58 2010
@@ -0,0 +1,45 @@
+// 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;
+
+class LazyFilter<T> implements LazyFunction<T>
+{
+ private final Predicate<? super T> predicate;
+
+ private final Flow<T> flow;
+
+ public LazyFilter(Predicate<? super T> predicate, Flow<T> flow)
+ {
+ this.predicate = predicate;
+ this.flow = flow;
+ }
+
+ public LazyContinuation<T> next()
+ {
+ Flow<T> cursor = flow;
+
+ while (!cursor.isEmpty())
+ {
+ T potential = cursor.first();
+
+ if (predicate.accept(potential))
+ return new LazyContinuation<T>(potential, new LazyFilter<T>(predicate, cursor.rest()));
+
+ cursor = cursor.rest();
+ }
+
+ return null;
+ }
+}
Propchange: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Copied: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFlow.java (from r950828, tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/MappedFlow.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFlow.java?p2=tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFlow.java&p1=tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/MappedFlow.java&r1=950828&r2=950886&rev=950886&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/MappedFlow.java (original)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFlow.java Thu Jun 3 06:43:58 2010
@@ -14,38 +14,26 @@
package org.apache.tapestry5.func;
-/**
- * Flow that wraps around another Flow, transforming it value by value into a new Flow.
- *
- * @since 5.2.0
- */
-class MappedFlow<T, X> extends AbstractFlow<X>
+class LazyFlow<T> extends AbstractFlow<T>
{
- private final Mapper<T, X> mapper;
+ // All instance variables guarded by this
- // Used to determine first, rest
- // Guarded by this
- private Flow<T> mappedFlow;
-
- // Guarded by this
private boolean resolved;
- // Guarded by this
- private X first;
+ private boolean empty;
- // Guarded by this
- private Flow<X> rest;
+ private T first;
- // Guarded by this
- private boolean empty;
+ private Flow<T> rest;
- public MappedFlow(Mapper<T, X> mapper, Flow<T> mappedFlow)
+ private LazyFunction<T> lazyFunction;
+
+ public LazyFlow(LazyFunction<T> lazyFunction)
{
- this.mapper = mapper;
- this.mappedFlow = mappedFlow;
+ this.lazyFunction = lazyFunction;
}
- public synchronized X first()
+ public synchronized T first()
{
resolve();
@@ -59,43 +47,34 @@ class MappedFlow<T, X> extends AbstractF
return empty;
}
- public synchronized Flow<X> rest()
+ public synchronized Flow<T> rest()
{
resolve();
return rest;
}
- private void resolve()
+ private synchronized void resolve()
{
if (resolved)
return;
- if (mappedFlow.isEmpty())
+ LazyContinuation<T> continuation = lazyFunction.next();
+
+ if (continuation == null)
{
empty = true;
rest = F.emptyFlow();
}
else
{
- first = mapper.map(mappedFlow.first());
+ first = continuation.nextValue();
- rest = new MappedFlow<T, X>(mapper, mappedFlow.rest());
+ rest = new LazyFlow<T>(continuation.nextFunction());
}
- mappedFlow = null;
-
resolved = true;
+
+ lazyFunction = null;
}
-
- public synchronized int count()
- {
- if (resolved) {
- return empty ? 0 : 1 + rest.count(); }
-
- // Not yet resolved, so mappedFlow is still valid. Mapping never changes the count, thus:
-
- return mappedFlow.count();
- }
-
}
Propchange: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFlow.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFunction.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFunction.java?rev=950886&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFunction.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFunction.java Thu Jun 3 06:43:58 2010
@@ -0,0 +1,33 @@
+// 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;
+
+/**
+ * A lazy function is used to populate a {@link Flow} incrementally. Lazy functions allow calculations to be
+ * deferred. They also support infinitely large Flows, where successive values are computed just as needed.
+ *
+ * @since 5.2.0
+ */
+public interface LazyFunction<T>
+{
+ /**
+ * Calculates the next value for the function. The return value is tricky: it combines the next value in the
+ * {@link Flow} with a function to compute the value after that as a {@link LazyContinuation}. Alternately, a
+ * LazyFunction can return null to indicate that it has returned all the values it can.
+ *
+ * @return continuation containing next value and next function, or null when no more values can be produced
+ */
+ LazyContinuation<T> next();
+}
Propchange: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyFunction.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyIterate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyIterate.java?rev=950886&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyIterate.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyIterate.java Thu Jun 3 06:43:58 2010
@@ -0,0 +1,36 @@
+// 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;
+
+/**
+ * Used by {@link LazyConcat} to iterate the second flow.
+ */
+class LazyIterate<T> implements LazyFunction<T>
+{
+ private final Flow<T> flow;
+
+ public LazyIterate(Flow<T> flow)
+ {
+ this.flow = flow;
+ }
+
+ public LazyContinuation<T> next()
+ {
+ 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/LazyIterate.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyMapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyMapper.java?rev=950886&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyMapper.java (added)
+++ tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyMapper.java Thu Jun 3 06:43:58 2010
@@ -0,0 +1,39 @@
+// 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;
+
+class LazyMapper<T, X> implements LazyFunction<X>
+{
+ private final Mapper<T, X> mapper;
+
+ private final Flow<T> flow;
+
+ public LazyMapper(Mapper<T, X> mapper, Flow<T> flow)
+ {
+ this.mapper = mapper;
+ this.flow = flow;
+ }
+
+ public LazyContinuation<X> next()
+ {
+ if (flow.isEmpty())
+ return null;
+
+ X mapped = mapper.map(flow.first());
+
+ return new LazyContinuation<X>(mapped, new LazyMapper<T, X>(mapper, flow.rest()));
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-func/src/main/java/org/apache/tapestry5/func/LazyMapper.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=950886&r1=950885&r2=950886&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 06:43:58 2010
@@ -641,18 +641,6 @@ public class FuncTest extends Assert
}
@Test
- public void count_of_a_mapped_flow_before_and_after_realization()
- {
- Flow<Integer> flow = F.flow("Mary", "had", "a", "little", "lamb").map(stringToLength);
-
- assertEquals(flow.count(), 5);
-
- assertEquals(flow.first(), (Integer) 4);
-
- assertEquals(flow.count(), 5);
- }
-
- @Test
public void count_of_a_filtered_flow()
{
Flow<String> flow = F.flow("Mary", "had", "a", "little", "lamb");
@@ -678,4 +666,12 @@ public class FuncTest extends Assert
assertListsEquals(flow.map(F.<Integer> stringValueOf()).toList(), "1", "2", "3");
}
+ @Test
+ public void concat_empty_list()
+ {
+ Flow<Integer> flow = F.flow(1, 3);
+
+ assertListsEquals(flow.concat(flow.filter(evenp)).toList(), 1, 3);
+ }
+
}