package soot.jimple.toolkits.thread.mhp;
import soot.toolkits.graph.*;
import java.util.*;
// *** USE AT YOUR OWN RISK ***
// May Happen in Parallel (MHP) analysis by Lin Li.
// This code should be treated as beta-quality code.
// It was written in 2003, but not incorporated into Soot until 2006.
// As such, it may contain incorrect assumptions about the usage
// of certain Soot classes.
// Some portions of this MHP analysis have been quality-checked, and are
// now used by the Transactions toolkit.
//
// -Richard L. Halpert, 2006-11-30
public class SCC{
private Set<Object> gray;
// private int time;
private final LinkedList<Object> finishedOrder;
private final List<List<Object>> sccList;
// public SCC(Chain chain, DirectedGraph g){
public SCC(Iterator it, DirectedGraph g){
gray = new HashSet<Object>();
finishedOrder = new LinkedList<Object>();
sccList = new ArrayList<List<Object>>();
// Visit each node
{
while (it.hasNext()){
Object s =it.next();
if (!gray.contains(s)){
visitNode(g, s);
}
}
}
//Re-color all nodes white
gray = new HashSet<Object>();
//visit nodes via tranpose edges according decreasing order of finish time of nodes
{
Iterator<Object> revNodeIt = finishedOrder.iterator();
while (revNodeIt.hasNext()){
Object s =revNodeIt.next();
if (!gray.contains(s)){
List<Object> scc = new ArrayList<Object>();
visitRevNode(g, s, scc);
sccList.add(scc);
}
}
}
}
private void visitNode(DirectedGraph g, Object s ){
//System.out.println("visit "+s);
gray.add(s);
// time++; // begin visit time
Iterator it = g.getSuccsOf(s).iterator();
// System.out.println("succs are: "+g.getSuccsOf(s));
if (g.getSuccsOf(s).size()>0){
while (it.hasNext()){
Object succ = it.next();
if (!gray.contains(succ)){
visitNode(g, succ);
}
}
}
// time++;//end time
finishedOrder.addFirst(s);
//System.out.println("add "+s+ " to finished order ");
}
private void visitRevNode(DirectedGraph g, Object s, List<Object> scc){
scc.add(s);
gray.add(s);
if (g.getPredsOf(s) != null){
Iterator predsIt = g.getPredsOf(s).iterator();
if (g.getPredsOf(s).size()>0){
while (predsIt.hasNext()){
Object pred = predsIt.next();
if (!gray.contains(pred)){
visitRevNode(g, pred, scc);
}
}
}
}
}
public List<List<Object>> getSccList(){
return sccList;
}
public LinkedList<Object> getFinishedOrder(){
return finishedOrder;
}
}