From a3578d3ac293442b64cbc5f5feb4cb9106799fdb Mon Sep 17 00:00:00 2001 From: Fabian Lange Date: Thu, 3 Jul 2014 23:52:05 +0200 Subject: [PATCH] Avoid object creation in getAllChildrenIterable in most cases. (#14142) API change from: public static Iterable getAllChildrenIterable(final ClientConnector connector) to public static Iterable getAllChildrenIterable(final ClientConnector connector) avoids creating wrappers in case the component has either no subcomponents or no extensions. This covers the vast majority of components. Change-Id: I48ffd2f26f09c265fae6e1aaabdbaa655d52ffb8 --- .../server/AbstractClientConnector.java | 118 +++++++++--------- .../src/com/vaadin/ui/ConnectorTracker.java | 2 +- .../tests/server/TestClassesSerializable.java | 2 + 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java index bafecdabf4..03300b20e2 100644 --- a/server/src/com/vaadin/server/AbstractClientConnector.java +++ b/server/src/com/vaadin/server/AbstractClientConnector.java @@ -41,6 +41,7 @@ import com.vaadin.shared.communication.ClientRpc; import com.vaadin.shared.communication.ServerRpc; import com.vaadin.shared.communication.SharedState; import com.vaadin.shared.ui.ComponentStateUtil; +import com.vaadin.ui.Component; import com.vaadin.ui.Component.Event; import com.vaadin.ui.HasComponents; import com.vaadin.ui.LegacyComponent; @@ -339,31 +340,6 @@ public abstract class AbstractClientConnector implements ClientConnector, } } - private static final class AllChildrenIterable implements - Iterable, Serializable { - private final ClientConnector connector; - - private AllChildrenIterable(ClientConnector connector) { - this.connector = connector; - } - - @Override - public Iterator iterator() { - CombinedIterator iterator = new CombinedIterator(); - - if (connector instanceof HasComponents) { - HasComponents hasComponents = (HasComponents) connector; - iterator.addIterator(hasComponents.iterator()); - } - - Collection extensions = connector.getExtensions(); - if (extensions.size() > 0) { - iterator.addIterator(extensions.iterator()); - } - return iterator; - } - } - private class RpcInvocationHandler implements InvocationHandler, Serializable { @@ -493,41 +469,6 @@ public abstract class AbstractClientConnector implements ClientConnector, } } - private static final class CombinedIterator implements Iterator, - Serializable { - - private final Collection> iterators = new ArrayList>(); - - public void addIterator(Iterator iterator) { - iterators.add(iterator); - } - - @Override - public boolean hasNext() { - for (Iterator i : iterators) { - if (i.hasNext()) { - return true; - } - } - return false; - } - - @Override - public T next() { - for (Iterator i : iterators) { - if (i.hasNext()) { - return i.next(); - } - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - /** * Get an Iterable for iterating over all child connectors, including both * extensions and child components. @@ -536,9 +477,62 @@ public abstract class AbstractClientConnector implements ClientConnector, * the connector to get children for * @return an Iterable giving all child connectors. */ - public static Iterable getAllChildrenIterable( + public static Iterable getAllChildrenIterable( final ClientConnector connector) { - return new AllChildrenIterable(connector); + + Collection extensions = connector.getExtensions(); + boolean hasComponents = connector instanceof HasComponents; + boolean hasExtensions = extensions.size() > 0; + if (!hasComponents && !hasExtensions) { + // If has neither component nor extensions, return immutable empty + // list as iterable. + return Collections.emptyList(); + } + if (hasComponents && !hasExtensions) { + // only components + return (HasComponents) connector; + } + if (!hasComponents && hasExtensions) { + // only extensions + return extensions; + } + + // combine the iterators of extensions and components to a new iterable. + final Iterator componentsIterator = ((HasComponents) connector) + .iterator(); + final Iterator extensionsIterator = extensions.iterator(); + Iterable combinedIterable = new Iterable() { + + @Override + public Iterator iterator() { + return new Iterator() { + + @Override + public boolean hasNext() { + return componentsIterator.hasNext() + || extensionsIterator.hasNext(); + } + + @Override + public ClientConnector next() { + if (componentsIterator.hasNext()) { + return componentsIterator.next(); + } + if (extensionsIterator.hasNext()) { + return extensionsIterator.next(); + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + } + }; + return combinedIterable; } @Override diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java index c0f973106b..b5a0227d99 100644 --- a/server/src/com/vaadin/ui/ConnectorTracker.java +++ b/server/src/com/vaadin/ui/ConnectorTracker.java @@ -366,7 +366,7 @@ public class ConnectorTracker implements Serializable { ClientConnector connector = stack.pop(); danglingConnectors.remove(connector); - Iterable children = AbstractClientConnector + Iterable children = AbstractClientConnector .getAllChildrenIterable(connector); for (ClientConnector child : children) { stack.add(child); diff --git a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java index e938a1cd37..63f79504ff 100644 --- a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java +++ b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java @@ -63,6 +63,8 @@ public class TestClassesSerializable extends TestCase { "com\\.vaadin\\.sass.*", // "com\\.vaadin\\.testbench.*", // "com\\.vaadin\\.util\\.CurrentInstance\\$1", // + "com\\.vaadin\\.server\\.AbstractClientConnector\\$1", // + "com\\.vaadin\\.server\\.AbstractClientConnector\\$1\\$1", // "com\\.vaadin\\.server\\.JsonCodec\\$1", // "com\\.vaadin\\.server\\.communication\\.PushConnection", // "com\\.vaadin\\.server\\.communication\\.AtmospherePushConnection", // -- 2.39.5