Diagram.java revision 1472:c18cbe5936b8
1/* 2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24package com.sun.hotspot.igv.graph; 25 26import com.sun.hotspot.igv.data.InputBlock; 27import com.sun.hotspot.igv.data.InputEdge; 28import com.sun.hotspot.igv.data.InputGraph; 29import com.sun.hotspot.igv.data.InputNode; 30import com.sun.hotspot.igv.data.Properties; 31import java.awt.Font; 32import java.util.ArrayList; 33import java.util.Collection; 34import java.util.Collections; 35import java.util.Comparator; 36import java.util.HashMap; 37import java.util.HashSet; 38import java.util.HashMap; 39import java.util.List; 40import java.util.Map; 41import java.util.Set; 42 43/** 44 * 45 * @author Thomas Wuerthinger 46 */ 47public class Diagram { 48 49 private List<Figure> figures; 50 private Map<InputBlock, Block> blocks; 51 private InputGraph graph; 52 private int curId; 53 private String nodeText; 54 private Font font; 55 56 public Font getFont() { 57 return font; 58 } 59 60 private Diagram() { 61 figures = new ArrayList<Figure>(); 62 blocks = new HashMap<InputBlock, Block>(); 63 this.nodeText = ""; 64 this.font = new Font("Serif", Font.PLAIN, 14); 65 } 66 67 public Block getBlock(InputBlock b) { 68 return blocks.get(b); 69 } 70 71 public String getNodeText() { 72 return nodeText; 73 } 74 75 public void schedule(Collection<InputBlock> newBlocks) { 76 graph.schedule(newBlocks); 77 updateBlocks(); 78 } 79 80 private void updateBlocks() { 81 blocks.clear(); 82 for (InputBlock b : graph.getBlocks()) { 83 Block curBlock = new Block(b, this); 84 blocks.put(b, curBlock); 85 } 86 } 87 88 public Diagram getNext() { 89 return Diagram.createDiagram(graph.getNext(), nodeText); 90 } 91 92 public Collection<Block> getBlocks() { 93 return Collections.unmodifiableCollection(blocks.values()); 94 } 95 96 public Diagram getPrev() { 97 return Diagram.createDiagram(graph.getPrev(), nodeText); 98 } 99 100 public List<Figure> getFigures() { 101 return Collections.unmodifiableList(figures); 102 } 103 104 public Figure createFigure() { 105 Figure f = new Figure(this, curId); 106 curId++; 107 this.figures.add(f); 108 return f; 109 } 110 111 public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot) { 112 assert inputSlot.getFigure().getDiagram() == this; 113 assert outputSlot.getFigure().getDiagram() == this; 114 return new Connection(inputSlot, outputSlot); 115 } 116 117 public static Diagram createDiagram(InputGraph graph, String nodeText) { 118 if (graph == null) { 119 return null; 120 } 121 122 Diagram d = new Diagram(); 123 d.graph = graph; 124 d.nodeText = nodeText; 125 126 d.updateBlocks(); 127 128 Collection<InputNode> nodes = graph.getNodes(); 129 HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>(); 130 for (InputNode n : nodes) { 131 Figure f = d.createFigure(); 132 f.getSource().addSourceNode(n); 133 f.getProperties().add(n.getProperties()); 134 figureHash.put(n.getId(), f); 135 } 136 137 for (InputEdge e : graph.getEdges()) { 138 139 int from = e.getFrom(); 140 int to = e.getTo(); 141 Figure fromFigure = figureHash.get(from); 142 Figure toFigure = figureHash.get(to); 143 assert fromFigure != null && toFigure != null; 144 145 int toIndex = e.getToIndex(); 146 147 while (fromFigure.getOutputSlots().size() <= 0) { 148 fromFigure.createOutputSlot(); 149 } 150 151 OutputSlot outputSlot = fromFigure.getOutputSlots().get(0); 152 153 while (toFigure.getInputSlots().size() <= toIndex) { 154 toFigure.createInputSlot(); 155 } 156 157 InputSlot inputSlot = toFigure.getInputSlots().get(toIndex); 158 159 Connection c = d.createConnection(inputSlot, outputSlot); 160 161 if (e.getState() == InputEdge.State.NEW) { 162 c.setStyle(Connection.ConnectionStyle.BOLD); 163 } else if (e.getState() == InputEdge.State.DELETED) { 164 c.setStyle(Connection.ConnectionStyle.DASHED); 165 } 166 } 167 168 169 return d; 170 } 171 172 public void removeAllFigures(Set<Figure> figuresToRemove) { 173 for (Figure f : figuresToRemove) { 174 freeFigure(f); 175 } 176 177 ArrayList<Figure> newFigures = new ArrayList<Figure>(); 178 for (Figure f : this.figures) { 179 if (!figuresToRemove.contains(f)) { 180 newFigures.add(f); 181 } 182 } 183 figures = newFigures; 184 } 185 186 private void freeFigure(Figure succ) { 187 188 List<InputSlot> inputSlots = new ArrayList<InputSlot>(succ.getInputSlots()); 189 for (InputSlot s : inputSlots) { 190 succ.removeInputSlot(s); 191 } 192 193 List<OutputSlot> outputSlots = new ArrayList<OutputSlot>(succ.getOutputSlots()); 194 for (OutputSlot s : outputSlots) { 195 succ.removeOutputSlot(s); 196 } 197 198 assert succ.getInputSlots().size() == 0; 199 assert succ.getOutputSlots().size() == 0; 200 assert succ.getPredecessors().size() == 0; 201 assert succ.getSuccessors().size() == 0; 202 203 } 204 205 public void removeFigure(Figure succ) { 206 207 assert this.figures.contains(succ); 208 freeFigure(succ); 209 this.figures.remove(succ); 210 } 211 212 public String getName() { 213 return graph.getName(); 214 } 215 216 public InputGraph getGraph() { 217 return graph; 218 } 219 220 public Set<Connection> getConnections() { 221 222 Set<Connection> connections = new HashSet<Connection>(); 223 for (Figure f : figures) { 224 225 for (InputSlot s : f.getInputSlots()) { 226 connections.addAll(s.getConnections()); 227 } 228 } 229 230 return connections; 231 } 232 233 public Figure getRootFigure() { 234 Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(figures); 235 Figure root = selector.selectSingle("name", "Root"); 236 if (root == null) { 237 root = selector.selectSingle("name", "Start"); 238 } 239 if (root == null) { 240 List<Figure> rootFigures = getRootFigures(); 241 if (rootFigures.size() > 0) { 242 root = rootFigures.get(0); 243 } else if (figures.size() > 0) { 244 root = figures.get(0); 245 } 246 } 247 248 return root; 249 } 250 251 public void printStatistics() { 252 System.out.println("============================================================="); 253 System.out.println("Diagram statistics"); 254 255 List<Figure> tmpFigures = getFigures(); 256 Set<Connection> connections = getConnections(); 257 258 System.out.println("Number of figures: " + tmpFigures.size()); 259 System.out.println("Number of connections: " + connections.size()); 260 261 List<Figure> figuresSorted = new ArrayList<Figure>(tmpFigures); 262 Collections.sort(figuresSorted, new Comparator<Figure>() { 263 264 public int compare(Figure a, Figure b) { 265 return b.getPredecessors().size() + b.getSuccessors().size() - a.getPredecessors().size() - a.getSuccessors().size(); 266 } 267 }); 268 269 final int COUNT = 10; 270 int z = 0; 271 for (Figure f : figuresSorted) { 272 273 z++; 274 int sum = f.getPredecessors().size() + f.getSuccessors().size(); 275 System.out.println("#" + z + ": " + f + ", predCount=" + f.getPredecessors().size() + " succCount=" + f.getSuccessors().size()); 276 if (sum < COUNT) { 277 break; 278 } 279 280 } 281 282 System.out.println("============================================================="); 283 } 284 285 public List<Figure> getRootFigures() { 286 ArrayList<Figure> rootFigures = new ArrayList<Figure>(); 287 for (Figure f : figures) { 288 if (f.getPredecessors().size() == 0) { 289 rootFigures.add(f); 290 } 291 } 292 return rootFigures; 293 } 294} 295