1 19 20 25 26 package soot.toolkits.graph; 27 import soot.options.*; 28 29 import soot.*; 30 import soot.util.*; 31 import java.util.*; 32 33 34 35 40 41 public class StronglyConnectedComponents 42 { 43 private HashMap nodeToColor; 44 private static final Object Visited=new Object (); 45 private static final Object Black=new Object (); 46 private LinkedList finishingOrder; 47 private List componentList = new ArrayList(); 48 private HashMap nodeToComponent = new HashMap(); 49 MutableDirectedGraph sccGraph = new HashMutableDirectedGraph(); 50 private int[] indexStack; 51 private Object [] nodeStack; 52 private int last; 53 54 59 public StronglyConnectedComponents(DirectedGraph g) 60 { 61 nodeToColor = new HashMap((3*g.size())/2,0.7f); 62 indexStack = new int[g.size()]; 63 nodeStack = new Object [g.size()]; 64 finishingOrder = new LinkedList(); 65 66 { 68 Iterator nodeIt = g.iterator(); 69 70 while(nodeIt.hasNext()) 71 { 72 Object s = nodeIt.next(); 73 74 if(nodeToColor.get(s) == null) 75 visitNode(g, s); 76 } 77 } 78 79 80 nodeToColor = new HashMap((3*g.size()),0.7f); 82 83 { 85 Iterator revNodeIt = finishingOrder.iterator(); 86 while (revNodeIt.hasNext()) 87 { 88 Object s = revNodeIt.next(); 89 90 if(nodeToColor.get(s) == null) 91 { 92 List currentComponent = null; 93 94 currentComponent = new StationaryArrayList(); 95 nodeToComponent.put(s, currentComponent); 96 sccGraph.addNode(currentComponent); 97 componentList.add(currentComponent); 98 99 visitRevNode(g, s, currentComponent); 100 } 101 } 102 } 103 componentList = Collections.unmodifiableList(componentList); 104 105 if (Options.v().verbose()) 106 { 107 G.v().out.println("Done computing scc components"); 108 G.v().out.println("number of nodes in underlying graph: "+g.size()); 109 G.v().out.println("number of components: "+sccGraph.size()); 110 } 111 } 112 113 private void visitNode(DirectedGraph graph, Object startNode) 114 { 115 last=0; 116 nodeToColor.put(startNode, Visited); 117 118 nodeStack[last]=startNode; 119 indexStack[last++]= -1; 120 121 while(last>0) 122 { 123 int toVisitIndex = ++indexStack[last-1]; 124 Object toVisitNode = nodeStack[last-1]; 125 126 if(toVisitIndex >= graph.getSuccsOf(toVisitNode).size()) 127 { 128 finishingOrder.addFirst(toVisitNode); 130 131 last--; 133 } 134 else 135 { 136 Object childNode = graph.getSuccsOf(toVisitNode).get(toVisitIndex); 137 138 if(nodeToColor.get(childNode) == null) 140 { 141 nodeToColor.put(childNode, Visited); 142 143 nodeStack[last]=childNode; 144 indexStack[last++]=-1; 145 } 146 } 147 } 148 } 149 150 private void visitRevNode(DirectedGraph graph, Object startNode, List currentComponent) 151 { 152 last=0; 153 154 nodeToColor.put(startNode, Visited); 155 156 nodeStack[last]=startNode; 157 indexStack[last++]= -1; 158 159 while(last>0) 160 { 161 int toVisitIndex = ++indexStack[last-1]; 162 Object toVisitNode = nodeStack[last-1]; 163 164 if(toVisitIndex >= graph.getPredsOf(toVisitNode).size()) 165 { 166 currentComponent.add(toVisitNode); 168 nodeToComponent.put(toVisitNode, currentComponent); 169 nodeToColor.put(toVisitNode, Black); 170 last--; 172 } 173 else 174 { 175 Object childNode = graph.getPredsOf(toVisitNode).get(toVisitIndex); 176 177 if(nodeToColor.get(childNode) == null) 179 { 180 nodeToColor.put(childNode, Visited); 181 182 nodeStack[last]=childNode; 183 indexStack[last++]=-1; 184 } 185 186 else if (nodeToColor.get(childNode) == Black) 187 { 188 189 if (nodeToComponent.get(childNode) != currentComponent) 190 sccGraph.addEdge(nodeToComponent.get(childNode), currentComponent); 191 } 192 } 193 } 194 } 195 196 197 204 public boolean equivalent(Object a, Object b) 205 { 206 return nodeToComponent.get(a) == nodeToComponent.get(b); 207 } 208 209 210 214 public List getComponents() 215 { 216 return componentList; 217 } 218 219 224 public List getComponentOf(Object a) 225 { 226 return (List)nodeToComponent.get(a); 227 } 228 229 233 public DirectedGraph getSuperGraph() 234 { 235 236 return sccGraph; 237 } 238 } 239 | Popular Tags |