# HG changeset patch # User Tom Rodriguez # Date 1390865186 28800 # Node ID 6187b0862ba064dc593de561128942cb4d94ac6d # Parent af344056124f1293040cd41a3f7633d0e3be2926 Add duplicate detection to IGV binary graphs diff -r af344056124f -r 6187b0862ba0 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Wed Jan 22 11:10:09 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Mon Jan 27 15:26:26 2014 -0800 @@ -35,6 +35,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.SwingUtilities; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; public class BinaryParser implements GraphParser { private static final int BEGIN_GROUP = 0x00; @@ -72,7 +74,10 @@ private final ReadableByteChannel channel; private final GraphDocument rootDocument; private final Deque folderStack; + private final Deque hashStack; private final ParseMonitor monitor; + + private MessageDigest digest; private enum Length { S, @@ -259,7 +264,12 @@ this.channel = channel; this.rootDocument = rootDocument; folderStack = new LinkedList<>(); + hashStack = new LinkedList<>(); this.monitor = monitor; + try { + this.digest = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException e) { + } } private void fill() throws IOException { @@ -274,6 +284,11 @@ while (buffer.remaining() < i) { fill(); } + buffer.mark(); + byte[] result = new byte[i]; + buffer.get(result); + digest.update(result); + buffer.reset(); } private int readByte() throws IOException { @@ -547,6 +562,7 @@ @Override public GraphDocument parse() throws IOException { folderStack.push(rootDocument); + hashStack.push(null); if (monitor != null) { monitor.setState("Starting parsing"); } @@ -589,6 +605,7 @@ }); } folderStack.push(group); + hashStack.push(null); if (callback != null && parent instanceof GraphDocument) { callback.started(group); } @@ -599,6 +616,7 @@ throw new IOException("Unbalanced groups"); } folderStack.pop(); + hashStack.pop(); break; } default: @@ -629,7 +647,17 @@ monitor.updateProgress(); } String title = readPoolObject(String.class); - return parseGraph(title); + digest.reset(); + InputGraph graph = parseGraph(title); + byte[] d = digest.digest(); + byte[] hash = hashStack.peek(); + if (hash != null && Arrays.equals(hash, d)) { + graph.getProperties().setProperty("_isDuplicate", "true"); + } else { + hashStack.pop(); + hashStack.push(d); + } + return graph; } private InputGraph parseGraph(String title) throws IOException { diff -r af344056124f -r 6187b0862ba0 src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Wed Jan 22 11:10:09 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Mon Jan 27 15:26:26 2014 -0800 @@ -43,6 +43,7 @@ // Warning: Update setData method if fields are added private Group group; + private ArrayList graphs; private Set hiddenNodes; private Set onScreenNodes; private Set selectedNodes; @@ -56,6 +57,7 @@ private ChangedEvent hiddenNodesChangedEvent; private ChangedEvent viewPropertiesChangedEvent; private boolean showNodeHull; + private boolean hideDuplicates; private ChangedListener filterChainChangedListener = new ChangedListener() { @Override @@ -83,6 +85,10 @@ boolean groupChanged = (group == newModel.group); this.group = newModel.group; + if (groupChanged) { + filterGraphs(); + } + diagramChanged |= (filterChain != newModel.filterChain); this.filterChain = newModel.filterChain; diagramChanged |= (sequenceFilterChain != newModel.sequenceFilterChain); @@ -122,11 +128,33 @@ viewPropertiesChangedEvent.fire(); } + public boolean getHideDuplicates() { + return hideDuplicates; + } + + public void setHideDuplicates(boolean b) { + System.err.println("setHideDuplicates: " + b); + hideDuplicates = b; + InputGraph currentGraph = getFirstGraph(); + if (hideDuplicates) { + // Back up to the unhidden equivalent graph + int index = graphs.indexOf(currentGraph); + while (graphs.get(index).getProperties().get("_isDuplicate") != null) { + index--; + } + currentGraph = graphs.get(index); + } + filterGraphs(); + selectGraph(currentGraph); + viewPropertiesChangedEvent.fire(); + } + public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFilterChain) { - super(calculateStringList(g)); + super(Arrays.asList("default")); this.showNodeHull = true; this.group = g; + filterGraphs(); assert filterChain != null; this.filterChain = filterChain; assert sequenceFilterChain != null; @@ -165,7 +193,7 @@ @Override public void changed(Group source) { assert source == group; - setPositions(calculateStringList(source)); + filterGraphs(); setSelectedNodes(selectedNodes); } }; @@ -211,7 +239,7 @@ } InputNode last = null; int index = 0; - for (InputGraph g : group.getGraphs()) { + for (InputGraph g : graphs) { Color curColor = colors.get(index); InputNode cur = g.getNode(id); if (cur != null) { @@ -316,16 +344,24 @@ diagramChanged(); } - private static List calculateStringList(Group g) { - List result = new ArrayList<>(); - for (InputGraph graph : g.getGraphs()) { - result.add(graph.getName()); + /* + * Select the set of graphs to be presented. + */ + private void filterGraphs() { + ArrayList result = new ArrayList<>(); + List positions = new ArrayList<>(); + for (InputGraph graph : group.getGraphs()) { + String duplicate = graph.getProperties().get("_isDuplicate"); + if (duplicate == null || !hideDuplicates) { + result.add(graph); + positions.add(graph.getName()); + } } - return result; + this.graphs = result; + setPositions(positions); } public InputGraph getFirstGraph() { - List graphs = group.getGraphs(); if (getFirstPosition() < graphs.size()) { return graphs.get(getFirstPosition()); } @@ -333,7 +369,6 @@ } public InputGraph getSecondGraph() { - List graphs = group.getGraphs(); if (getSecondPosition() < graphs.size()) { return graphs.get(getSecondPosition()); } @@ -341,7 +376,12 @@ } public void selectGraph(InputGraph g) { - int index = group.getGraphs().indexOf(g); + int index = graphs.indexOf(g); + if (index == -1 && hideDuplicates) { + // A graph was selected that's currently hidden, so unhide and select it. + setHideDuplicates(false); + index = graphs.indexOf(g); + } assert index != -1; setPositions(index, index); } diff -r af344056124f -r 6187b0862ba0 src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Wed Jan 22 11:10:09 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Mon Jan 27 15:26:26 2014 -0800 @@ -78,6 +78,7 @@ private InstanceContent content; private InstanceContent graphContent; private OverviewAction overviewAction; + private HideDuplicatesAction hideDuplicatesAction; private PredSuccAction predSuccAction; private SelectionModeAction selectionModeAction; private PanModeAction panModeAction; @@ -87,6 +88,7 @@ private CardLayout cardLayout; private RangeSlider rangeSlider; private JToggleButton overviewButton; + private JToggleButton hideDuplicatesButton; private static final String PREFERRED_ID = "EditorTopComponent"; private static final String SATELLITE_STRING = "satellite"; private static final String SCENE_STRING = "scene"; @@ -207,6 +209,14 @@ rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener); rangeSliderModel.selectGraph(diagram.getGraph()); + rangeSliderModel.getViewPropertiesChangedEvent().addListener(new ChangedListener() { + @Override + public void changed(DiagramViewModel source) { + hideDuplicatesButton.setSelected(getModel().getHideDuplicates()); + hideDuplicatesAction.setState(getModel().getHideDuplicates()); + } + }); + toolBar.add(NextDiagramAction.get(NextDiagramAction.class)); toolBar.add(PrevDiagramAction.get(PrevDiagramAction.class)); @@ -230,6 +240,12 @@ toolBar.add(button); predSuccAction.addPropertyChangeListener(this); + hideDuplicatesAction = new HideDuplicatesAction(); + hideDuplicatesButton = new JToggleButton(hideDuplicatesAction); + hideDuplicatesButton.setSelected(false); + toolBar.add(hideDuplicatesButton); + hideDuplicatesAction.addPropertyChangeListener(this); + toolBar.addSeparator(); toolBar.add(UndoAction.get(UndoAction.class)); toolBar.add(RedoAction.get(RedoAction.class)); @@ -477,6 +493,9 @@ } else { showScene(); } + } else if (evt.getSource() == this.hideDuplicatesAction) { + boolean b = (Boolean) hideDuplicatesAction.getValue(HideDuplicatesAction.STATE); + this.getModel().setHideDuplicates(b); } else if (evt.getSource() == this.selectionModeAction || evt.getSource() == this.panModeAction) { if (panModeAction.isSelected()) { scene.setInteractionMode(DiagramViewer.InteractionMode.PANNING); diff -r af344056124f -r 6187b0862ba0 src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java Mon Jan 27 15:26:26 2014 -0800 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, 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.view.actions; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; +import org.openide.util.ImageUtilities; + +/** + * + * @author Tom Rodriguez + */ +public class HideDuplicatesAction extends AbstractAction { + + private boolean state; + public static final String STATE = "state"; + + public HideDuplicatesAction() { + putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource()))); + putValue(Action.SHORT_DESCRIPTION, "Hide graphs which are the same as the previous graph"); + setState(false); + } + + @Override + public void actionPerformed(ActionEvent ev) { + setState(!state); + } + + public void setState(boolean b) { + this.putValue(STATE, b); + this.state = b; + } + + protected String iconResource() { + return "com/sun/hotspot/igv/view/images/hideDuplicates.png"; + } +} diff -r af344056124f -r 6187b0862ba0 src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/hideDuplicates.png Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/hideDuplicates.png has changed