All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
soot.toolkits.graph.HashMutableEdgeLabelledDirectedGraph Maven / Gradle / Ivy
/* Soot - a J*va Optimization Framework
* Copyright (C) 1999 Patrice Pominville, Raja Vallee-Rai, Patrick Lam
* Copyright (C) 2007 Richard L. Halpert
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the Sable Research Group and others 1997-1999.
* See the 'credits' file distributed with Soot for the complete list of
* contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
*/
package soot.toolkits.graph;
import java.util.*;
import soot.*;
import soot.util.*;
/**
* HashMap based implementation of a MutableEdgeLabelledDirectedGraph.
*/
class DGEdge
{
Object from;
Object to;
public DGEdge(Object from, Object to)
{
this.from = from;
this.to = to;
}
public Object from()
{
return from;
}
public Object to()
{
return to;
}
public boolean equals(Object o)
{
if(o instanceof DGEdge)
{
DGEdge other = (DGEdge) o;
return from.equals(other.from) && to.equals(other.to);
}
return false;
}
public int hashCode()
{
return from.hashCode() + to.hashCode();
}
}
public class HashMutableEdgeLabelledDirectedGraph implements MutableEdgeLabelledDirectedGraph
{
protected HashMap nodeToPreds = new HashMap();
protected HashMap nodeToSuccs = new HashMap();
protected HashMap> edgeToLabels = new HashMap();
protected HashMap> labelToEdges = new HashMap();
protected Chain heads = new HashChain();
protected Chain tails = new HashChain();
public HashMutableEdgeLabelledDirectedGraph()
{
}
/** Removes all nodes and edges. */
public void clearAll() {
nodeToPreds = new HashMap();
nodeToSuccs = new HashMap();
edgeToLabels = new HashMap();
labelToEdges = new HashMap();
heads = new HashChain();
tails = new HashChain();
}
public Object clone() {
HashMutableEdgeLabelledDirectedGraph g = new HashMutableEdgeLabelledDirectedGraph();
g.nodeToPreds = (HashMap)nodeToPreds.clone();
g.nodeToSuccs = (HashMap)nodeToSuccs.clone();
g.edgeToLabels = (HashMap)edgeToLabels.clone();
g.labelToEdges = (HashMap)labelToEdges.clone();
g.heads = HashChain.listToHashChain(HashChain.toList(heads));
g.tails = HashChain.listToHashChain(HashChain.toList(tails));
return g;
}
/* Returns an unbacked list of heads for this graph. */
public List getHeads()
{
ArrayList l = new ArrayList(); l.addAll(heads);
return Collections.unmodifiableList(l);
}
/* Returns an unbacked list of tails for this graph. */
public List getTails()
{
ArrayList l = new ArrayList(); l.addAll(tails);
return Collections.unmodifiableList(l);
}
public List getPredsOf(Object s)
{
List l = nodeToPreds.get(s);
if (l != null)
return Collections.unmodifiableList(l);
else
throw new RuntimeException(s+"not in graph!");
}
public List getSuccsOf(Object s)
{
List l = nodeToSuccs.get(s);
if (l != null)
return Collections.unmodifiableList(l);
else
throw new RuntimeException(s+"not in graph!");
}
public int size()
{
return nodeToPreds.keySet().size();
}
public Iterator iterator()
{
return nodeToPreds.keySet().iterator();
}
public void addEdge(Object from, Object to, Object label)
{
if (from == null || to == null)
throw new RuntimeException("edge from or to null");
if (label == null)
throw new RuntimeException("edge with null label");
if (containsEdge(from, to, label))
return;
List succsList = nodeToSuccs.get(from);
if (succsList == null)
throw new RuntimeException(from + " not in graph!");
List predsList = nodeToPreds.get(to);
if (predsList == null)
throw new RuntimeException(to + " not in graph!");
if (heads.contains(to))
heads.remove(to);
if (tails.contains(from))
tails.remove(from);
if(!succsList.contains(to))
succsList.add(to);
if(!predsList.contains(from))
predsList.add(from);
DGEdge edge = new DGEdge(from, to);
if(!edgeToLabels.containsKey(edge))
edgeToLabels.put(edge, new ArrayList());
List labels = edgeToLabels.get(edge);
if(!labelToEdges.containsKey(label))
labelToEdges.put(label, new ArrayList());
List edges = labelToEdges.get(label);
// if(!labels.contains(label))
labels.add(label);
// if(!edges.contains(edge))
edges.add(edge);
}
public List getLabelsForEdges(Object from, Object to)
{
DGEdge edge = new DGEdge(from, to);
return edgeToLabels.get(edge);
}
public MutableDirectedGraph getEdgesForLabel(Object label)
{
List edges = labelToEdges.get(label);
MutableDirectedGraph ret = new HashMutableDirectedGraph();
if(edges == null)
return ret;
for(DGEdge edge : edges)
{
if(!ret.containsNode(edge.from()))
ret.addNode(edge.from());
if(!ret.containsNode(edge.to()))
ret.addNode(edge.to());
ret.addEdge(edge.from(), edge.to());
}
return ret;
}
public void removeEdge(Object from, Object to, Object label)
{
if (!containsEdge(from, to, label))
return;
DGEdge edge = new DGEdge(from, to);
List labels = edgeToLabels.get(edge);
if( labels == null )
throw new RuntimeException("edge " + edge + " not in graph!");
List edges = labelToEdges.get(label);
if( edges == null )
throw new RuntimeException("label " + label + " not in graph!");
labels.remove(label);
edges.remove(edge);
// if this edge has no more labels, then it's gone!
if(labels.isEmpty())
{
edgeToLabels.remove(edge);
List succsList = nodeToSuccs.get(from);
if (succsList == null)
throw new RuntimeException(from + " not in graph!");
List predsList = nodeToPreds.get(to);
if (predsList == null)
throw new RuntimeException(to + " not in graph!");
succsList.remove(to);
predsList.remove(from);
if (succsList.isEmpty())
tails.add(from);
if (predsList.isEmpty())
heads.add(to);
}
// if this label has no more edges, then who cares?
if(edges.isEmpty())
labelToEdges.remove(label);
}
public void removeAllEdges(Object from, Object to)
{
if (!containsAnyEdge(from, to))
return;
DGEdge edge = new DGEdge(from, to);
List labels = edgeToLabels.get(edge);
if( labels == null )
throw new RuntimeException("edge " + edge + " not in graph!");
for(Object label : labels)
{
removeEdge(from, to, label);
}
}
public void removeAllEdges(Object label)
{
if( !containsAnyEdge(label) )
return;
List edges = labelToEdges.get(label);
if( edges == null )
throw new RuntimeException("label " + label + " not in graph!");
for(DGEdge edge : edges)
{
removeEdge(edge.from(), edge.to(), label);
}
}
public boolean containsEdge(Object from, Object to, Object label)
{
DGEdge edge = new DGEdge(from, to);
if(edgeToLabels.get(edge) != null && edgeToLabels.get(edge).contains(label))
return true;
return false;
}
public boolean containsAnyEdge(Object from, Object to)
{
DGEdge edge = new DGEdge(from, to);
if(edgeToLabels.get(edge) != null && edgeToLabels.get(edge).isEmpty())
return false;
return true;
}
public boolean containsAnyEdge(Object label)
{
if(labelToEdges.get(label) != null && labelToEdges.get(label).isEmpty())
return false;
return true;
}
public boolean containsNode(Object node)
{
return nodeToPreds.keySet().contains(node);
}
public List getNodes()
{
return Arrays.asList(nodeToPreds.keySet().toArray());
}
public void addNode(Object node)
{
if (containsNode(node))
throw new RuntimeException("Node already in graph");
nodeToSuccs.put(node, new ArrayList());
nodeToPreds.put(node, new ArrayList());
heads.add(node);
tails.add(node);
}
public void removeNode(Object node)
{
List succs = (List)nodeToSuccs.get(node).clone();
for (Iterator succsIt = succs.iterator(); succsIt.hasNext(); )
removeAllEdges(node, succsIt.next());
nodeToSuccs.remove(node);
List preds = (List)nodeToPreds.get(node).clone();
for (Iterator predsIt = preds.iterator(); predsIt.hasNext(); )
removeAllEdges(predsIt.next(), node);
nodeToPreds.remove(node);
if (heads.contains(node))
heads.remove(node);
if (tails.contains(node))
tails.remove(node);
}
public void printGraph()
{
for (Iterator it = iterator(); it.hasNext(); )
{
Object node = it.next();
G.v().out.println("Node = "+node);
G.v().out.println("Preds:");
for (Iterator predsIt = getPredsOf(node).iterator(); predsIt.hasNext(); )
{
Object pred = predsIt.next();
DGEdge edge = new DGEdge(pred, node);
List labels = edgeToLabels.get(edge);
G.v().out.println(" " + pred + " [" + labels + "]");
}
G.v().out.println("Succs:");
for (Iterator succsIt = getSuccsOf(node).iterator(); succsIt.hasNext(); )
{
Object succ = succsIt.next();
DGEdge edge = new DGEdge(node, succ);
List labels = edgeToLabels.get(edge);
G.v().out.println(" " + succ + " [" + labels + "]");
}
}
}
}