view visualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java @ 4512:015fb895586b

Moved visualizer to new directory.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 07 Feb 2012 22:41:09 +0100
parents
children
line wrap: on
line source

/*
 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */
package com.sun.hotspot.igv.graph;

import com.sun.hotspot.igv.data.InputEdge;
import com.sun.hotspot.igv.data.InputGraph;
import com.sun.hotspot.igv.data.InputNode;
import com.sun.hotspot.igv.data.Properties;
import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
import java.awt.Font;
import java.util.*;

/**
 *
 * @author Thomas Wuerthinger
 */
public class Diagram {

    private List<Figure> figures;
    private InputGraph graph;
    private int curId;
    private String nodeText;
    private Font font;
    private Font slotFont;

    public Font getFont() {
        return font;
    }

    public Font getSlotFont() {
        return slotFont;
    }
    
    private Diagram() {
        figures = new ArrayList<>();
        this.nodeText = "";
        this.font = new Font("Arial", Font.PLAIN, 13);
        this.slotFont = new Font("Arial", Font.PLAIN, 10);
    }

    public String getNodeText() {
        return nodeText;
    }

    public Diagram getNext() {
        return Diagram.createDiagram(graph.getNext(), nodeText);
    }

    public Diagram getPrev() {
        return Diagram.createDiagram(graph.getPrev(), nodeText);
    }

    public List<Figure> getFigures() {
        return Collections.unmodifiableList(figures);
    }

    public Figure createFigure() {
        Figure f = new Figure(this, curId);
        curId++;
        this.figures.add(f);
        return f;
    }

    public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot, String label) {
        assert inputSlot.getFigure().getDiagram() == this;
        assert outputSlot.getFigure().getDiagram() == this;
        return new Connection(inputSlot, outputSlot, label);
    }
    
    public Map<InputNode, Set<Figure>> calcSourceToFigureRelation() {
        Map<InputNode, Set<Figure>> map = new HashMap<>();
        
        for(InputNode node : this.getGraph().getNodes()) {
            map.put(node, new HashSet<Figure>());
        }
        
        for(Figure f : this.getFigures()) {
            for(InputNode node : f.getSource().getSourceNodes()) {
                map.get(node).add(f);
            }
        }
        
        return map;
    }

    public static Diagram createDiagram(InputGraph graph, String nodeText) {
        if (graph == null) {
            return null;
        }

        Diagram d = new Diagram();
        d.graph = graph;
        d.nodeText = nodeText;

        Collection<InputNode> nodes = graph.getNodes();
        Hashtable<Integer, Figure> figureHash = new Hashtable<>();
        for (InputNode n : nodes) {
            Figure f = d.createFigure();
            f.getSource().addSourceNode(n);
            f.getProperties().add(n.getProperties());
            figureHash.put(n.getId(), f);
        }

        for (InputEdge e : graph.getEdges()) {

            int from = e.getFrom();
            int to = e.getTo();
            Figure fromFigure = figureHash.get(from);
            Figure toFigure = figureHash.get(to);
            assert fromFigure != null && toFigure != null;
            
            if(fromFigure == null || toFigure == null) continue;

            int fromIndex = e.getFromIndex();
            while (fromFigure.getOutputSlots().size() <= fromIndex) {
                fromFigure.createOutputSlot();
            }
            OutputSlot outputSlot = fromFigure.getOutputSlots().get(fromIndex);

            int toIndex = e.getToIndex();
            while (toFigure.getInputSlots().size() <= toIndex) {
                toFigure.createInputSlot();
            }
            InputSlot inputSlot = toFigure.getInputSlots().get(toIndex);

            Connection c = d.createConnection(inputSlot, outputSlot, e.getLabel());

            if (e.getState() == InputEdge.State.NEW) {
                c.setStyle(Connection.ConnectionStyle.BOLD);
            } else if (e.getState() == InputEdge.State.DELETED) {
                c.setStyle(Connection.ConnectionStyle.DASHED);
            }
        }


        return d;
    }

    public void removeAllFigures(Set<Figure> figuresToRemove) {
        for (Figure f : figuresToRemove) {
            freeFigure(f);
        }

        ArrayList<Figure> newFigures = new ArrayList<>();
        for (Figure f : this.figures) {
            if (!figuresToRemove.contains(f)) {
                newFigures.add(f);
            }
        }
        figures = newFigures;
    }

    private void freeFigure(Figure succ) {

        List<InputSlot> inputSlots = new ArrayList<>(succ.getInputSlots());
        for (InputSlot s : inputSlots) {
            succ.removeInputSlot(s);
        }

        List<OutputSlot> outputSlots = new ArrayList<>(succ.getOutputSlots());
        for (OutputSlot s : outputSlots) {
            succ.removeOutputSlot(s);
        }

        assert succ.getInputSlots().size() == 0;
        assert succ.getOutputSlots().size() == 0;
        assert succ.getPredecessors().size() == 0;
        assert succ.getSuccessors().size() == 0;

    }

    public void removeFigure(Figure succ) {

        assert this.figures.contains(succ);
        freeFigure(succ);
        this.figures.remove(succ);
    }

    public String getName() {
        return graph.getName();
    }

    public InputGraph getGraph() {
        return graph;
    }

    public Set<Connection> getConnections() {

        Set<Connection> connections = new HashSet<>();
        for (Figure f : figures) {

            for (InputSlot s : f.getInputSlots()) {
                connections.addAll(s.getConnections());
            }
        }

        return connections;
    }

    public Figure getRootFigure() {
        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(figures);
        Figure root = selector.selectSingle(new StringPropertyMatcher("name", "Root"));
        if (root == null) {
            root = selector.selectSingle(new StringPropertyMatcher("name", "Start"));
        }
        if (root == null) {
            List<Figure> rootFigures = getRootFigures();
            if (rootFigures.size() > 0) {
                root = rootFigures.get(0);
            } else if (figures.size() > 0) {
                root = figures.get(0);
            }
        }

        return root;
    }

    public void printStatistics() {
        System.out.println("=============================================================");
        System.out.println("Diagram statistics");

        List<Figure> tmpFigures = getFigures();
        Set<Connection> connections = getConnections();

        System.out.println("Number of figures: " + tmpFigures.size());
        System.out.println("Number of connections: " + connections.size());

        List<Figure> figuresSorted = new ArrayList<>(tmpFigures);
        Collections.sort(figuresSorted, new Comparator<Figure>() {

            @Override
            public int compare(Figure a, Figure b) {
                return b.getPredecessors().size() + b.getSuccessors().size() - a.getPredecessors().size() - a.getSuccessors().size();
            }
        });

        final int COUNT = 10;
        int z = 0;
        for (Figure f : figuresSorted) {

            z++;
            int sum = f.getPredecessors().size() + f.getSuccessors().size();
            System.out.println("#" + z + ": " + f + ", predCount=" + f.getPredecessors().size() + " succCount=" + f.getSuccessors().size());
            if (sum < COUNT) {
                break;
            }

        }

        System.out.println("=============================================================");
    }

    public List<Figure> getRootFigures() {
        ArrayList<Figure> rootFigures = new ArrayList<>();
        for (Figure f : figures) {
            if (f.getPredecessors().size() == 0) {
                rootFigures.add(f);
            }
        }
        return rootFigures;
    }
}