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:
parent
9a52793738
commit
b43d449738
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue