added code to 'project' a graph onto a subset of nodes, preserving transitive notions of connectivity

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3507 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2009-04-22 16:40:34 +00:00
parent 9a52793738
commit b43d449738
1 changed files with 157 additions and 1 deletions

View File

@ -10,15 +10,21 @@
*******************************************************************************/
package com.ibm.wala.util.graph;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import com.ibm.wala.util.collections.Filter;
import com.ibm.wala.util.collections.FilterIterator;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.Iterator2Collection;
import com.ibm.wala.util.collections.IteratorUtil;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.functions.Function;
import com.ibm.wala.util.graph.impl.GraphInverter;
import com.ibm.wala.util.graph.traverse.DFS;
import com.ibm.wala.util.warnings.WalaException;
@ -148,4 +154,154 @@ public class GraphSlicer {
return output;
}
}
public static <E> AbstractGraph<E> project(final Graph<E> G, final Filter<E> fmember) {
final NodeManager<E> nodeManager = new NodeManager<E>() {
private int count = -1;
public void addNode(E n) {
throw new UnsupportedOperationException();
}
public boolean containsNode(E N) {
return G.containsNode(N) && fmember.accepts(N);
}
public int getNumberOfNodes() {
if (count == -1) {
count = IteratorUtil.count(iterator());
}
return count;
}
public Iterator<E> iterator() {
return new FilterIterator<E>(G.iterator(), fmember);
}
public void removeNode(E n) {
throw new UnsupportedOperationException();
}
};
final EdgeManager<E> edgeManager = new EdgeManager<E>() {
private Map<E, Collection<E>> succs = new HashMap<E, Collection<E>>();
private Map<E, Collection<E>> preds = new HashMap<E, Collection<E>>();
private Set<E> getConnected(E inst, Function<E, Iterator<? extends E>> fconnected) {
Set<E> result = new LinkedHashSet<E>();
Set<E> seenInsts = new HashSet<E>();
Set<E> newInsts = Iterator2Collection.toSet(fconnected.apply(inst));
while (!newInsts.isEmpty()) {
Set<E> nextInsts = new HashSet<E>();
for (E s : newInsts) {
if (!seenInsts.contains(s)) {
seenInsts.add(s);
if (nodeManager.containsNode(s)) {
result.add(s);
} else {
Iterator<? extends E> ss = fconnected.apply(s);
while (ss.hasNext()) {
E n = ss.next();
if (!seenInsts.contains(n)) {
nextInsts.add(n);
}
}
}
}
}
newInsts = nextInsts;
}
return result;
}
private void setPredNodes(E N) {
preds.put(N, getConnected(N, new Function<E, Iterator<? extends E>>() {
public Iterator<? extends E> apply(E object) {
return G.getPredNodes(object);
}
}));
}
private void setSuccNodes(E N) {
succs.put(N, getConnected(N, new Function<E, Iterator<? extends E>>() {
public Iterator<? extends E> apply(E object) {
return G.getSuccNodes(object);
}
}));
}
public int getPredNodeCount(E N) {
if (!preds.containsKey(N)) {
setPredNodes(N);
}
return preds.get(N).size();
}
public Iterator<? extends E> getPredNodes(E N) {
if (!preds.containsKey(N)) {
setPredNodes(N);
}
return preds.get(N).iterator();
}
public int getSuccNodeCount(E N) {
if (!succs.containsKey(N)) {
setSuccNodes(N);
}
return succs.get(N).size();
}
public Iterator<? extends E> getSuccNodes(E N) {
if (!succs.containsKey(N)) {
setSuccNodes(N);
}
return succs.get(N).iterator();
}
public boolean hasEdge(E src, E dst) {
if (!preds.containsKey(dst)) {
setPredNodes(dst);
}
return preds.get(dst).contains(src);
}
public void addEdge(E src, E dst) {
throw new UnsupportedOperationException();
}
public void removeAllIncidentEdges(E node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeEdge(E src, E dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeIncomingEdges(E node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(E node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
};
return new AbstractGraph<E>() {
@Override
protected EdgeManager<E> getEdgeManager() {
return edgeManager;
}
@Override
protected NodeManager<E> getNodeManager() {
return nodeManager;
}
};
}
}