[jboss-cvs] JBossAS SVN: r99112 - in projects/jboss-deployers/trunk/deployers-impl/src: test/java/org/jboss/test/deployers/deployer/test and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Jan 7 07:58:21 EST 2010
Author: richard.opalka at jboss.com
Date: 2010-01-07 07:58:21 -0500 (Thu, 07 Jan 2010)
New Revision: 99112
Added:
projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/TopologicalOrderingDeployerSorter.java
projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/OptimizedTopologicalOrderingUnitTestCase.java
Modified:
projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/DeployerSorterFactory.java
projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/AbstractDeployerFlowUnitTest.java
projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/DominoOrderingUnitTestCase.java
projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/KahnOrderingUnitTestCase.java
projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/TopologicalOrderingUnitTestCase.java
Log:
[JBDEPLOY-229][JBDEPLOY-230] fixing issue
Modified: projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/DeployerSorterFactory.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/DeployerSorterFactory.java 2010-01-07 12:46:43 UTC (rev 99111)
+++ projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/DeployerSorterFactory.java 2010-01-07 12:58:21 UTC (rev 99112)
@@ -25,6 +25,7 @@
* Sorter factory.
*
* @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
*/
public class DeployerSorterFactory
{
@@ -36,6 +37,6 @@
*/
public static DeployerSorter newSorter()
{
- return new KahnDeployerSorter();
+ return new TopologicalOrderingDeployerSorter();
}
}
Added: projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/TopologicalOrderingDeployerSorter.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/TopologicalOrderingDeployerSorter.java (rev 0)
+++ projects/jboss-deployers/trunk/deployers-impl/src/main/java/org/jboss/deployers/plugins/sort/TopologicalOrderingDeployerSorter.java 2010-01-07 12:58:21 UTC (rev 99112)
@@ -0,0 +1,317 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright (c) 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.deployers.plugins.sort;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.jboss.deployers.spi.Ordered;
+import org.jboss.deployers.spi.deployer.Deployer;
+
+/**
+ * Implements <a href="http://en.wikipedia.org/wiki/Topological_sorting">topological sorting</a> for acyclic graphs.
+ * The algorithm complexity is O(m+n), where <b>m</b> = count of vertices and <b>n</b> = count of edges in general.
+ * However this complexity isn't true for this algorithm implementation, because there's backward compatibility
+ * requirement that deployers have to be ordered by their relative number or name if they're on the same processing level.
+ * <b>IOW this backward compatible sorting requirement breaks linear algorithm complexity :(</b>.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+public class TopologicalOrderingDeployerSorter implements DeployerSorter
+{
+
+ /**
+ * @see {@link DeployerSorter#sortDeployers(List, Deployer)}
+ */
+ public List<Deployer> sortDeployers(List<Deployer> registeredDeployers, Deployer newDeployer)
+ {
+ return this.createOrientedGraph(registeredDeployers, newDeployer).sort();
+ }
+
+ private Graph createOrientedGraph(final List<Deployer> deployers, final Deployer newDeployer)
+ {
+ final Graph graph = new Graph();
+
+ for (final Deployer deployer : deployers)
+ graph.addVertex(deployer);
+
+ graph.addVertex(newDeployer);
+ graph.createEdges();
+
+ return graph;
+ }
+
+
+ private static class Graph
+ {
+ private Map<String, Dependency> dependencies = new HashMap<String, Dependency>();
+ private Set<Vertex> vertices = new HashSet<Vertex>();
+
+ public void addVertex(final Deployer deployer)
+ {
+ // create disjunct sets
+ final Set<String> inputs = new HashSet<String>();
+ inputs.addAll(deployer.getInputs());
+ final Set<String> outputs = new HashSet<String>();
+ outputs.addAll(deployer.getOutputs());
+ final Set<String> intersection = this.getIntersection(inputs, outputs);
+
+ // register vertex
+ final Vertex vertex = new Vertex(deployer);
+ this.vertices.add(vertex);
+
+ // register dependencies
+ Dependency dependency = null;
+ for (final String in : inputs)
+ {
+ dependency = this.getDependency(in);
+ dependency.consumers.add(vertex);
+ }
+
+ for (final String inOut : intersection)
+ {
+ dependency = this.getDependency(inOut);
+ dependency.modifiers.add(vertex);
+ }
+
+ for (final String out : outputs)
+ {
+ dependency = this.getDependency(out);
+ dependency.producers.add(vertex);
+ }
+ }
+
+ public List<Deployer> sort()
+ {
+ // L ← Empty list that will contain the sorted elements
+ List<Deployer> retVal = new LinkedList<Deployer>();
+ // S ← Set of all nodes with no incoming edges
+ List<Vertex> roots = this.getRoots();
+ // ensure backward compatibility
+ Collections.sort(roots, Ordered.COMPARATOR);
+
+ // while S is non-empty do
+ Vertex root = null;
+ Set<Vertex> nextLevel = null;
+ while(!roots.isEmpty())
+ {
+ // remove a node n from S
+ root = roots.remove(0);
+ // insert n into L
+ retVal.add(root.getDeployer());
+
+ // for each node m with an edge e from n to m do
+ if (root.hasConsumers())
+ {
+ // ensure backward compatibility
+ nextLevel = new TreeSet<Vertex>(Ordered.COMPARATOR);
+ for(final Vertex consumer : root.consumers)
+ {
+ // remove edge e from the graph
+ consumer.decrementDegree();
+ // if m has no other incoming edges then insert m into S
+ if (!consumer.hasProducers())
+ {
+ this.remove(consumer);
+ nextLevel.add(consumer);
+ }
+ }
+
+ // append to the end of list in sorted order
+ roots.addAll(nextLevel);
+ }
+ }
+
+ if (this.vertices.size() > 0)
+ {
+ // if graph has edges then graph has at least one cycle
+ throw new IllegalStateException("Cycle detected");
+ }
+ else
+ {
+ // topologically sorted order
+ return retVal;
+ }
+ }
+
+ private Set<String> getIntersection(final Set<String> inputs, final Set<String> outputs)
+ {
+ final Set<String> intersection = new HashSet<String>();
+
+ for (final String input : inputs)
+ for (final String output : outputs)
+ if (input.equals(output))
+ intersection.add(input);
+
+ inputs.removeAll(intersection);
+ outputs.removeAll(intersection);
+
+ return intersection;
+ }
+
+ private Dependency getDependency(final String name)
+ {
+ if (this.dependencies.containsKey(name))
+ {
+ return this.dependencies.get(name);
+ }
+ else
+ {
+ final Dependency newDependency = new Dependency();
+ this.dependencies.put(name, newDependency);
+ return newDependency;
+ }
+ }
+
+ private void createEdges()
+ {
+ boolean hasModifiers = false;
+ Dependency dependency = null;
+
+ for (final String dependencyName : this.dependencies.keySet())
+ {
+ dependency = this.dependencies.get(dependencyName);
+ hasModifiers = dependency.modifiers.size() > 0;
+
+ if (hasModifiers)
+ {
+ this.createEdges(dependency.producers, dependency.modifiers);
+ this.createEdges(dependency.modifiers, dependency.consumers);
+ }
+ else
+ {
+ this.createEdges(dependency.producers, dependency.consumers);
+ }
+ }
+ }
+
+ private void createEdges(final List<Vertex> producers, final List<Vertex> consumers)
+ {
+ for (final Vertex producer : producers)
+ for (final Vertex consumer : consumers)
+ {
+ producer.addConsumer(consumer);
+ consumer.incrementDegree();
+ }
+ }
+
+ private List<Vertex> getRoots()
+ {
+ final LinkedList<Vertex> retVal = new LinkedList<Vertex>();
+
+ for (final Vertex current : this.vertices)
+ if (!current.hasProducers())
+ retVal.add(current);
+
+ for (final Vertex root : retVal)
+ this.remove(root);
+
+ return retVal;
+ }
+
+ private void remove(final Vertex v)
+ {
+ this.vertices.remove(v);
+ }
+
+ private static class Vertex implements Ordered
+ {
+ // Wrapped deployer
+ private Deployer deployer;
+ // Incoming edges
+ private int inDegree = 0;
+ // Outgoing edges
+ private List<Vertex> consumers = new LinkedList<Vertex>();
+
+ public Vertex(final Deployer deployer)
+ {
+ if (deployer == null)
+ throw new IllegalArgumentException();
+
+ this.deployer = deployer;
+ }
+
+ public void incrementDegree()
+ {
+ this.inDegree++;
+ }
+
+ public void decrementDegree()
+ {
+ this.inDegree--;
+ }
+
+ public void addConsumer(final Vertex v)
+ {
+ this.consumers.add(v);
+ }
+
+ public boolean hasProducers()
+ {
+ return this.inDegree > 0;
+ }
+
+ public boolean hasConsumers()
+ {
+ return this.consumers.size() > 0;
+ }
+
+ public Deployer getDeployer()
+ {
+ return this.deployer;
+ }
+
+ public int getRelativeOrder()
+ {
+ return this.deployer.getRelativeOrder();
+ }
+
+ public void setRelativeOrder(final int order)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String toString()
+ {
+ return this.deployer.toString();
+ }
+ }
+
+ private static class Dependency
+ {
+ // deployers creating this dependency
+ private List<Vertex> producers = new LinkedList<Vertex>();
+ // deployers modifying this dependency
+ private List<Vertex> modifiers = new LinkedList<Vertex>();
+ // deployers consuming this dependency
+ private List<Vertex> consumers= new LinkedList<Vertex>();
+ }
+
+ }
+
+}
Modified: projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/AbstractDeployerFlowUnitTest.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/AbstractDeployerFlowUnitTest.java 2010-01-07 12:46:43 UTC (rev 99111)
+++ projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/AbstractDeployerFlowUnitTest.java 2010-01-07 12:58:21 UTC (rev 99112)
@@ -21,6 +21,9 @@
*/
package org.jboss.test.deployers.deployer.test;
+import java.util.LinkedList;
+import java.util.List;
+
import org.jboss.deployers.client.spi.DeployerClient;
import org.jboss.deployers.client.spi.Deployment;
import org.jboss.deployers.plugins.deployers.DeployersImpl;
@@ -1233,7 +1236,36 @@
main.removeDeployment(deployment);
main.process();
}
+
+ public void testAlgorithmPerformance() throws Exception
+ {
+ DeployerClient main = createMainDeployer();
+ AbstractDeployer deployer;
+ final int COUNT_OF_DEPLOYERS = 500;
+ List<AbstractDeployer> deployers = new LinkedList<AbstractDeployer>();
+
+ for (int i = 0; i < COUNT_OF_DEPLOYERS; i++)
+ {
+ deployer = new TestDeployerAdapter( String.valueOf(i) );
+ deployer.setOutputs( String.valueOf(i) );
+ for (int j = 0; j < i; j++) deployer.addInput( String.valueOf(j) );
+ deployer.setStage(DeploymentStages.REAL);
+ deployers.add(deployer);
+ }
+
+ long start = System.currentTimeMillis();
+ for (AbstractDeployer d : deployers)
+ {
+ addDeployer(main, d);
+ }
+ long end = System.currentTimeMillis();
+
+ System.out.println("------------------------------------------------------------------------");
+ System.out.println("Exhaustive deployer sorting (" + getClass().getSimpleName() + ") took: " + (end - start) + " milliseconds");
+ System.out.println("------------------------------------------------------------------------");
+ }
+
public void testRealWorldAS6DeployersScenario() throws Exception
{
// THIS IS REAL WORLD SCENARIO - AS deployers with their dependencies
Modified: projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/DominoOrderingUnitTestCase.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/DominoOrderingUnitTestCase.java 2010-01-07 12:46:43 UTC (rev 99111)
+++ projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/DominoOrderingUnitTestCase.java 2010-01-07 12:58:21 UTC (rev 99112)
@@ -49,4 +49,11 @@
{
return new DominoDeployerSorter();
}
+
+ public void testAlgorithmPerformance()
+ {
+ System.out.println("------------------------------------------------------------------------");
+ System.out.println("Exhaustive deployer sorting (" + getClass().getSimpleName() + ") took: NOT MEASURED (too slow)");
+ System.out.println("------------------------------------------------------------------------");
+ }
}
\ No newline at end of file
Modified: projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/KahnOrderingUnitTestCase.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/KahnOrderingUnitTestCase.java 2010-01-07 12:46:43 UTC (rev 99111)
+++ projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/KahnOrderingUnitTestCase.java 2010-01-07 12:58:21 UTC (rev 99112)
@@ -49,4 +49,11 @@
{
return new KahnDeployerSorter();
}
+
+ public void testAlgorithmPerformance()
+ {
+ System.out.println("------------------------------------------------------------------------");
+ System.out.println("Exhaustive deployer sorting (" + getClass().getSimpleName() + ") took: NOT MEASURED (too slow)");
+ System.out.println("------------------------------------------------------------------------");
+ }
}
\ No newline at end of file
Added: projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/OptimizedTopologicalOrderingUnitTestCase.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/OptimizedTopologicalOrderingUnitTestCase.java (rev 0)
+++ projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/OptimizedTopologicalOrderingUnitTestCase.java 2010-01-07 12:58:21 UTC (rev 99112)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright (c) 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.deployers.deployer.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.jboss.deployers.plugins.sort.DeployerSorter;
+import org.jboss.deployers.plugins.sort.TopologicalOrderingDeployerSorter;
+
+/**
+ * Tests topological sorting.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+public class OptimizedTopologicalOrderingUnitTestCase extends AbstractSorterOrderingUnitTest
+{
+ public OptimizedTopologicalOrderingUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(OptimizedTopologicalOrderingUnitTestCase.class);
+ }
+
+ @Override
+ protected DeployerSorter createSorter()
+ {
+ return new TopologicalOrderingDeployerSorter();
+ }
+}
Modified: projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/TopologicalOrderingUnitTestCase.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/TopologicalOrderingUnitTestCase.java 2010-01-07 12:46:43 UTC (rev 99111)
+++ projects/jboss-deployers/trunk/deployers-impl/src/test/java/org/jboss/test/deployers/deployer/test/TopologicalOrderingUnitTestCase.java 2010-01-07 12:58:21 UTC (rev 99112)
@@ -55,4 +55,11 @@
{
// TODO - how much do we allow pass-through to participate in ordering?
}
+
+ public void testAlgorithmPerformance()
+ {
+ System.out.println("------------------------------------------------------------------------");
+ System.out.println("Exhaustive deployer sorting (" + getClass().getSimpleName() + ") took: NOT MEASURED (too slow)");
+ System.out.println("------------------------------------------------------------------------");
+ }
}
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list