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