package edu.ucla.cloud; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import com.mxgraph.analysis.mxGraphAnalysis; import com.mxgraph.analysis.mxICostFunction; import com.mxgraph.model.mxCell; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.view.mxCellState; import com.mxgraph.view.mxGraph; import edu.ucla.cloud.switches.AggregrateSwitch; import edu.ucla.cloud.switches.CoreSwitch; import edu.ucla.cloud.switches.EdgeSwitch; import edu.ucla.cloud.switches.Switch; /** * Represents top level tree defined with the help of Core level switches and * pods Servers are hidden inside edge switches * */ public class ExtElasticTree { private Display display = null; private final GraphUtil graphUtil = new GraphUtil(); private final List<CoreSwitch> coreSwitchesGlobal = new ArrayList<CoreSwitch>(); private final Set<Pod> pods = new HashSet<Pod>(); private final List<Server> serversGlobal = new ArrayList<Server>(); private final List<EdgeSwitch> edgeSwitchesGlobal = new ArrayList<EdgeSwitch>(); private final List<AggregrateSwitch> aggregrateSwitchesGlobal = new ArrayList<AggregrateSwitch>(); private final int numberOfPods; private final int aggregateSwitchesPerPod; private final int edgeSwitchesPerPod; private final int serversPerEdgeSwitch; private final int numberOfCoreSwitches; private final int UNIT_OF_WORK_PER_SERVER = 2; Map<String, Switch> switchMasterList = new HashMap<String, Switch>(); final Map<CoreSwitch, mxCell> coreNodes = new HashMap<CoreSwitch, mxCell>(); final Map<AggregrateSwitch, mxCell> aggregateNodes = new HashMap<AggregrateSwitch, mxCell>(); final Map<EdgeSwitch, mxCell> edgeNodes = new HashMap<EdgeSwitch, mxCell>(); final Map<Server, mxCell> serverNodes = new HashMap<Server, mxCell>(); public ExtElasticTree() { this(2, 2, 2, 2, 2); // this(2, 2, 2, 2, 2); } public ExtElasticTree(final int numPods, final int aggregateSwitchesPerPod, final int edgeSwitchesPerPod, final int serversPerEdgeSwitch, final int numberOfCoreSwitches) { this.numberOfCoreSwitches = numberOfCoreSwitches; this.serversPerEdgeSwitch = serversPerEdgeSwitch; this.edgeSwitchesPerPod = edgeSwitchesPerPod; this.aggregateSwitchesPerPod = aggregateSwitchesPerPod; numberOfPods = numPods; final int totalServers = numberOfPods * edgeSwitchesPerPod * serversPerEdgeSwitch; for (int c = 0; c < numberOfCoreSwitches; c++) { final CoreSwitch coreSwitch = new CoreSwitch(totalServers / 2); coreSwitchesGlobal.add(coreSwitch); } for (int p = 0; p < numPods; p++) { final Pod pod = createPod(p); pods.add(pod); for (int a = 0; a < pod.getAggregrateSwitchs().size(); a++) { final AggregrateSwitch aggregrateSwitch = pod .getAggregrateSwitchs().get(a); if (a % 2 == 0) { for (int c = 0; c < numberOfCoreSwitches / 2; c++) { final CoreSwitch coreSwitch = coreSwitchesGlobal.get(c); coreSwitch.getAggregrateSwitchs().add(aggregrateSwitch); aggregrateSwitch.getCoreSwitches().add(coreSwitch); } } else { for (int c = numberOfCoreSwitches / 2; c < numberOfCoreSwitches; c++) { final CoreSwitch coreSwitch = coreSwitchesGlobal.get(c); coreSwitch.getAggregrateSwitchs().add(aggregrateSwitch); aggregrateSwitch.getCoreSwitches().add(coreSwitch); } } } } } public int calculateRoutingThroughput() { return 0; } public void clearServerEdges() { graphUtil.removeAllServerEdges(serversGlobal); } private mxGraph getGraph() { final mxGraph graph = new mxGraph(); final Object parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); int x = 180; for (final CoreSwitch coreSwitch : coreSwitchesGlobal) { coreSwitch.reset(); final mxCell node = (mxCell) graph.insertVertex(parent, null, coreSwitch.getSwitchId(), x, 20, 80, 30); x += 250; coreNodes.put(coreSwitch, node); switchMasterList.put((String) node.getValue(), coreSwitch); } x = 80; for (final AggregrateSwitch aggregrateSwitch : aggregrateSwitchesGlobal) { aggregrateSwitch.reset(); final mxCell node = (mxCell) graph.insertVertex(parent, null, aggregrateSwitch.getSwitchId(), x, 150, 80, 30); x += 150; aggregateNodes.put(aggregrateSwitch, node); switchMasterList.put((String) node.getValue(), aggregrateSwitch); } x = 80; for (final EdgeSwitch edgeSwitch : edgeSwitchesGlobal) { edgeSwitch.reset(); final mxCell node = (mxCell) graph.insertVertex(parent, null, edgeSwitch.getSwitchId(), x, 250, 80, 30); x += 150; edgeNodes.put(edgeSwitch, node); switchMasterList.put((String) node.getValue(), edgeSwitch); } x = 10; int count = 0; int y = 350; for (final Server server : serversGlobal) { count++; if (count % 10 == 0) { y += 100; x = 10; } final mxCell node = (mxCell) graph.insertVertex(parent, null, server.getServerId(), x, y, 50, 10); x += 140; serverNodes.put(server, node); } for (final CoreSwitch coreSwitch : coreSwitchesGlobal) { final mxCell cNode = coreNodes.get(coreSwitch); for (final AggregrateSwitch aggregrateSwitch : coreSwitch .getAggregrateSwitchs()) { final mxCell aNode = aggregateNodes.get(aggregrateSwitch); if (aggregrateSwitch.isActive() && coreSwitch.isActive()) { graph.insertEdge(parent, null, coreSwitch.getSwitchId() + "+" + aggregrateSwitch.getSwitchId(), cNode, aNode); } // graph.insertEdge(parent, null, aggregrateSwitch // .getSwitchId() // + coreSwitch.getSwitchId(), aNode, cNode); for (final EdgeSwitch edgeSwitch : aggregrateSwitch .getEdgeSwitchs()) { final mxCell eNode = edgeNodes.get(edgeSwitch); if (edgeSwitch.isActive() && aggregrateSwitch.isActive()) { graph.insertEdge(parent, null, aggregrateSwitch .getSwitchId() + "+" + edgeSwitch.getSwitchId(), aNode, eNode); } // graph.insertEdge(parent, null, edgeSwitch // .getSwitchId() // + aggregrateSwitch.getSwitchId(), eNode, // aNode); for (final Server server : edgeSwitch.getServers()) { if (server.isActive() && edgeSwitch.isActive()) { final mxCell sNode = serverNodes.get(server); graph.insertEdge(parent, null, edgeSwitch .getSwitchId() + "+" + server.getServerId(), eNode, sNode); // graph.insertEdge(parent, null, server // .getServerId() // + edgeSwitch.getSwitchId(), sNode, // eNode); } } } } } graph.getModel().endUpdate(); return graph; } public double bruteForce(final int numberOfSwitchesToEliminate) { getGraph(); double cost = Double.MIN_VALUE; final Set<Entry<String, Switch>> entrySet = switchMasterList.entrySet(); for (final Entry<String, Switch> cur : entrySet) { final Switch node = cur.getValue(); node.setActive(false); final double runningCost = bruteForceRecurse(entrySet, 1, numberOfSwitchesToEliminate, cost); if (runningCost > cost) { cost = runningCost; display = new Display(print()); } node.setActive(true); } display.activate(); return cost; } private double bruteForceRecurse(final Set<Entry<String, Switch>> entrySet, final int currentDepth, final int numberOfSwitchesToEliminate, final double threshold) { final double highestCost = threshold; if (currentDepth >= numberOfSwitchesToEliminate) { final double topologyCost = topologyThroughput(); if (topologyCost == 908.0383116883118) { System.out.println("found"); } return topologyCost; } for (final Entry<String, Switch> cur : entrySet) { final Switch node = cur.getValue(); if (node.isActive()) { node.setActive(false); double iterationRunningCost = bruteForceRecurse(entrySet, currentDepth + 1, numberOfSwitchesToEliminate, threshold); node.setActive(true); if (iterationRunningCost > highestCost) { iterationRunningCost = highestCost; } } } return highestCost; } public double topologyThroughput() { final mxGraph graph = getGraph(); double effectiveThroughput = 0.0; final mxICostFunction cf = new mxICostFunction() { @Override public double getCost(final mxCellState state) { final mxCell node = (mxCell) state.getCell(); final String key = node.getValue().toString().split("\\+")[0]; final Switch switchNode = switchMasterList.get(key); final double throughput = switchNode.effectiveThroughputCost(); // System.out.println(key + "," + throughput); return throughput; } }; final mxGraphAnalysis mga = mxGraphAnalysis.getInstance(); final Set<EdgeSwitch> edgesToCheck = new HashSet<EdgeSwitch>(); edgesToCheck.addAll(edgeSwitchesGlobal); Iterator<EdgeSwitch> edgeIter = edgesToCheck.iterator(); // edgeIter.next(); // edgeIter.remove(); for (final EdgeSwitch edgeSwitch : edgeSwitchesGlobal) { while (edgeIter.hasNext()) { final EdgeSwitch compare = edgeIter.next(); // System.out.println(compare.getSwitchId()); final Iterator<Server> serverIter1 = edgeSwitch.getServers() .iterator(); while (serverIter1.hasNext()) { final Server server1 = serverIter1.next(); final Iterator<Server> serverIter2 = compare.getServers() .iterator(); while (serverIter2.hasNext()) { Server server2 = serverIter2.next(); while (server1.equals(server2) && serverIter2.hasNext()) { // System.out.println(server1.getServerId() + "," // + server2.getServerId()); server2 = serverIter2.next(); } final Object from = serverNodes.get(server1); final Object to = serverNodes.get(server2); final Iterator<Entry<EdgeSwitch, mxCell>> i = edgeNodes .entrySet().iterator(); final Object[] edges = mga.getShortestPath(graph, from, to, cf, 9999, false); if (edges == null || edges.length == 0) { // return Double.MIN_VALUE; } else { // System.out.print("Length=" + edges.length + "|"); for (final Object cur : edges) { final mxCell c = (mxCell) cur; final String key = c.getValue().toString() .split("\\+")[0]; final Switch switchNode = switchMasterList .get(key); if (switchNode != null) { switchNode.incrementCount(); effectiveThroughput += switchNode.getCost(); if (switchNode instanceof CoreSwitch) { // System.out // .println(switchNode.getCost()); } // System.out.println(switchNode.getSwitchId() // + "=" + switchNode.getCost()); // if (effectiveThroughput > 2000) { // System.out.println(server1.getServerId() // + "," + server2.getServerId()); // // System.out.println(effectiveThroughput); // } } else { // System.out.println(key); } // System.out.print(c.getValue() + "|"); } // System.out.println(""); } } } } // edgeIter.remove(); edgesToCheck.remove(edgeSwitch); edgeIter = edgesToCheck.iterator(); } // System.out.println(effectiveThroughput); return effectiveThroughput; } public mxGraphComponent print() { final mxGraph graph = getGraph(); final mxGraphComponent graphComponent = new mxGraphComponent(graph); return graphComponent; } public int calculateThroughput() { final int CORE_THROUGHPUT = 1000; final int AGGREGATE_THROUGHPUT = 100; final int EDGE_THROUGHPUT = 10; int throughputSum = 0; for (final CoreSwitch coreSwitch : coreSwitchesGlobal) { if (coreSwitch.isActive()) { for (final AggregrateSwitch aggregrateSwitch : coreSwitch .getAggregrateSwitchs()) { if (aggregrateSwitch.isActive()) { throughputSum += CORE_THROUGHPUT; for (final EdgeSwitch edgeSwitch : aggregrateSwitch .getEdgeSwitchs()) { if (edgeSwitch.isActive()) { throughputSum += AGGREGATE_THROUGHPUT; for (final Server server : edgeSwitch .getServers()) { if (server.isActive()) { throughputSum += EDGE_THROUGHPUT; } } } } } } } } return throughputSum; } private Pod createPod(final int num) { final Pod pod = new Pod(num); final Set<EdgeSwitch> edgeSwitchs = createEdgeSwitches(); for (int as = 0; as < aggregateSwitchesPerPod; as++) { final AggregrateSwitch aggregrateSwitch = new AggregrateSwitch( serversPerEdgeSwitch); aggregrateSwitch.getEdgeSwitchs().addAll(edgeSwitchs); pod.getAggregrateSwitchs().add(aggregrateSwitch); aggregrateSwitchesGlobal.add(aggregrateSwitch); } return pod; } private Set<EdgeSwitch> createEdgeSwitches() { final Set<EdgeSwitch> edgeSwitchs = new HashSet<EdgeSwitch>(); for (int es = 0; es < edgeSwitchesPerPod; es++) { final EdgeSwitch edgeSwitch = new EdgeSwitch(serversPerEdgeSwitch); final Set<Server> servers = createServers(edgeSwitch.getSwitchId()); edgeSwitch.getServers().addAll(servers); edgeSwitchs.add(edgeSwitch); edgeSwitchesGlobal.add(edgeSwitch); } return edgeSwitchs; } private Set<Server> createServers(final String edgeSwitchId) { final Set<Server> servers = new HashSet<Server>(); for (int s = 0; s < serversPerEdgeSwitch; s++) { final Server server = new Server(edgeSwitchId, s); servers.add(server); serversGlobal.add(server); } return servers; } public Map<String, Node> compute(final int targetTotalWork) { int currentWork = 0; for (final Server server : serversGlobal) { if (currentWork < targetTotalWork) { currentWork += UNIT_OF_WORK_PER_SERVER; server.setActive(true); } else { // System.out.println("Setting server to inactive. " // + server.getServerId()); server.setActive(false); } } for (final EdgeSwitch edgeSwitch : edgeSwitchesGlobal) { boolean disableEdge = true; for (final Server server : edgeSwitch.getServers()) { if (server.isActive()) { disableEdge = false; break; } } if (disableEdge) { // System.out.println("Setting edgeswitch to inactive." // + edgeSwitch.getSwitchId()); edgeSwitch.setActive(false); } } for (final AggregrateSwitch aggregrateSwitch : aggregrateSwitchesGlobal) { boolean disableAggregate = true; for (final EdgeSwitch edgeSwitch : aggregrateSwitch .getEdgeSwitchs()) { if (edgeSwitch.isActive()) { disableAggregate = false; break; } } if (disableAggregate) { // System.out.println("Setting aggregateswitch to inactive." // + aggregrateSwitch.getSwitchId()); aggregrateSwitch.setActive(false); } } for (final CoreSwitch coreSwitch : coreSwitchesGlobal) { boolean disableCore = true; for (final AggregrateSwitch aggregrateSwitch : coreSwitch .getAggregrateSwitchs()) { if (aggregrateSwitch.isActive()) { disableCore = false; break; } } if (disableCore) { // System.out.println("Setting coreswitch to inactive." // + coreSwitch.getSwitchId()); coreSwitch.setActive(false); } } return new HashMap<String, Node>(); } public void disableSwitch(final List<? extends Switch> switches) { } }