getNodeMapValues() {
+ return new HashSet<>(nodeMap.keySet());
}
}
diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/graph/DeterministicDependencyGraph.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/graph/DeterministicDependencyGraph.java
new file mode 100644
index 0000000000..2093576ac8
--- /dev/null
+++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/graph/DeterministicDependencyGraph.java
@@ -0,0 +1,84 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.util.graph;
+
+import java.util.*;
+
+import org.apache.commons.collections4.set.ListOrderedSet;
+
+/**
+ * Dependency Graph that uses {@link TreeMap}s and {@link ListOrderedSet}s to provide
+ * determinism in pulling ({@link #pop()}) from the graph. This class seems to consume more
+ * memory than {@link DependencyGraph}, and if memory is not an issue, it also seems to be
+ * slightly faster as well.
+ *
+ * This class was implemented to provide determinism while doing
+ * developmental debugging.
+ *
+ * @param the type of value.
+ *
+ * @see AbstractDependencyGraph
+ * @see DependencyGraph
+ */
+public class DeterministicDependencyGraph extends AbstractDependencyGraph {
+
+ public DeterministicDependencyGraph() {
+ super();
+ }
+
+ /**
+ * Copy constructor
+ * @param other the other DependencyGraph to copy
+ */
+ public DeterministicDependencyGraph(DeterministicDependencyGraph other) {
+ synchronized (other) {
+ for (DependencyNode node : other.nodeMap.values()) {
+ addValue(node.getValue());
+ if (node.getSetOfNodesThatDependOnMe() != null) {
+ for (DependencyNode child : node.getSetOfNodesThatDependOnMe()) {
+ addDependency(child.getValue(), node.getValue());
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public AbstractDependencyGraph copy() {
+ return new DeterministicDependencyGraph<>(this);
+ }
+
+ @Override
+ protected Map createNodeMap() {
+ return new TreeMap<>();
+ }
+
+ @Override
+ protected Set createNodeSet() {
+ return new ListOrderedSet<>();
+ }
+
+ @Override
+ protected Set createDependencyNodeSet() {
+ return new ListOrderedSet<>();
+ }
+
+ @Override
+ public synchronized Set getNodeMapValues() {
+ return ListOrderedSet.listOrderedSet(nodeMap.keySet());
+ }
+
+}
diff --git a/Ghidra/Framework/Generic/src/test/java/generic/concurrent/ConcurrentGraphQTest.java b/Ghidra/Framework/Generic/src/test/java/generic/concurrent/ConcurrentGraphQTest.java
index 756c5c3bfc..c623108325 100644
--- a/Ghidra/Framework/Generic/src/test/java/generic/concurrent/ConcurrentGraphQTest.java
+++ b/Ghidra/Framework/Generic/src/test/java/generic/concurrent/ConcurrentGraphQTest.java
@@ -23,6 +23,7 @@ import org.junit.Assert;
import org.junit.Test;
import generic.test.AbstractGenericTest;
+import ghidra.util.graph.AbstractDependencyGraph;
import ghidra.util.graph.DependencyGraph;
import ghidra.util.task.TaskMonitor;
@@ -32,11 +33,11 @@ public class ConcurrentGraphQTest extends AbstractGenericTest {
super();
}
-@Test
- public void test() throws InterruptedException, Exception {
- final ArrayList completionOrder = new ArrayList();
+ @Test
+ public void test() throws InterruptedException, Exception {
+ final ArrayList completionOrder = new ArrayList<>();
- DependencyGraph graph = new DependencyGraph();
+ AbstractDependencyGraph graph = new DependencyGraph<>();
graph.addDependency("@0", "A8");
graph.addDependency("@1", "A1");
graph.addDependency("@2", "A7");
@@ -71,10 +72,10 @@ public class ConcurrentGraphQTest extends AbstractGenericTest {
assertTrue(!graph.hasCycles());
- DependencyGraph savedGraph = graph.copy();
+ AbstractDependencyGraph savedGraph = graph.copy();
GThreadPool pool = GThreadPool.getPrivateThreadPool("ConcurrentGraphQ Test");
- QRunnable runnable = new QRunnable() {
+ QRunnable runnable = new QRunnable<>() {
@Override
public void run(String item, TaskMonitor monitor) throws Exception {
@@ -87,7 +88,7 @@ public class ConcurrentGraphQTest extends AbstractGenericTest {
}
};
- ConcurrentGraphQ queue = new ConcurrentGraphQ(runnable, graph, pool, null);
+ ConcurrentGraphQ queue = new ConcurrentGraphQ<>(runnable, graph, pool, null);
queue.execute();
checkOrderSatisfiesDependencies(savedGraph, completionOrder);
}
@@ -101,7 +102,7 @@ public class ConcurrentGraphQTest extends AbstractGenericTest {
* @param visitedOrder the actual execution order to be tested
* @return
*/
- public void checkOrderSatisfiesDependencies(DependencyGraph dependencyGraph,
+ public void checkOrderSatisfiesDependencies(AbstractDependencyGraph dependencyGraph,
List visitedOrder) {
if (visitedOrder.size() > dependencyGraph.size()) {
@@ -111,12 +112,12 @@ public class ConcurrentGraphQTest extends AbstractGenericTest {
Assert.fail("Not all items in the graph were visited");
}
- HashSet items = new HashSet(visitedOrder);
+ HashSet items = new HashSet<>(visitedOrder);
if (items.size() != visitedOrder.size()) {
Assert.fail("duplicate item(s) in linearOrder\n");
}
- HashMap visitedOrderMap = new HashMap();
+ HashMap visitedOrderMap = new HashMap<>();
for (int i = 0; i < visitedOrder.size(); i++) {
visitedOrderMap.put(visitedOrder.get(i), i);
}
diff --git a/Ghidra/Framework/Generic/src/test/java/ghidra/util/datastruct/DependencyGraphPerformanceTest.java b/Ghidra/Framework/Generic/src/test/java/ghidra/util/datastruct/DependencyGraphPerformanceTest.java
new file mode 100644
index 0000000000..71cd89bc00
--- /dev/null
+++ b/Ghidra/Framework/Generic/src/test/java/ghidra/util/datastruct/DependencyGraphPerformanceTest.java
@@ -0,0 +1,150 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.util.datastruct;
+
+import java.util.*;
+
+import ghidra.util.graph.DependencyGraph;
+import ghidra.util.graph.DeterministicDependencyGraph;
+
+/**
+ * Performs computation of dependency graph
+ * Does not test the accuracy/functionality of Dependency Graphs.
+ */
+public class DependencyGraphPerformanceTest {
+
+ // Specifying the graph edge density ratio: number of edges over the
+ // number of possible edges (|E|/P(|V|,2).
+ // For sparse graphs, where |E|=O(n), can do |E|/|V|.
+ // TODO: What is good for testing.
+ private static final long GRAPH_SEED = 12345L;
+ private static final double GRAPH_EDGE_DENSITY = 0.20;
+ private static final int NUM_DEPENDENCIES = 30000;
+ private static final int GRAPH_SIZE = (int) (NUM_DEPENDENCIES / GRAPH_EDGE_DENSITY);
+ private static final boolean GRAPH_ALLOW_CYCLES = false;
+
+ private final List testRelationships;
+
+ public DependencyGraphPerformanceTest() {
+ testRelationships = constructRandomRelationships(GRAPH_SEED, NUM_DEPENDENCIES, GRAPH_SIZE,
+ GRAPH_ALLOW_CYCLES);
+ }
+
+ // Not intended for nightly or continuous testing. Comment in when needed during development.
+// @Test
+ public void testLargeDependencyGraph() {
+ Timer timer = new Timer("DependencyGraph");
+ timer.mark();
+ DependencyGraph graph = new DependencyGraph<>();
+ for (DependencyRelation relation : testRelationships) {
+ graph.addDependency(relation.dependent, relation.dependee);
+ }
+ timer.mark();
+ while (!graph.isEmpty()) {
+ graph.pop();
+ }
+ timer.mark();
+ System.out.println(timer);
+ }
+
+ // Not intended for nightly or continuous testing. Comment in when needed during development.
+// @Test
+ public void testLargeDeterministicDependencyGraph() {
+ Timer timer = new Timer("DeterministicDependencyGraph");
+ timer.mark();
+ DeterministicDependencyGraph graph = new DeterministicDependencyGraph<>();
+ for (DependencyRelation relation : testRelationships) {
+ graph.addDependency(relation.dependent, relation.dependee);
+ }
+ timer.mark();
+ while (!graph.isEmpty()) {
+ graph.pop();
+ }
+ timer.mark();
+ System.out.println(timer);
+ }
+
+ private class Timer {
+ private String testName;
+ private List times = new ArrayList<>();
+
+ public Timer(String testName) {
+ this.testName = testName;
+ }
+
+ public void mark() {
+ times.add(System.currentTimeMillis());
+ }
+
+ @Override
+ public String toString() {
+ String report = testName + " (milliseconds)\n";
+ if (!times.isEmpty()) {
+ long prev = times.get(0);
+ long total = times.get(times.size() - 1) - prev;
+ for (int i = 1; i < times.size(); i++) {
+ long current = times.get(i);
+ long diff = current - prev;
+ report += String.format(" %03d: %d\n", i, diff);
+ prev = current;
+ }
+ report += String.format("total: %d\n", total);
+ }
+ return report;
+ }
+ }
+
+ private class DependencyRelation {
+ public String dependent;
+ public String dependee;
+
+ public DependencyRelation(int dependentId, int dependeeId) {
+ dependent = "V" + dependentId;
+ dependee = "V" + dependeeId;
+ }
+ }
+
+ private List constructRandomRelationships(long seed, int numDependencies,
+ int graphSize, boolean allowCycles) {
+ List relationships = new ArrayList<>();
+ Random generator = new Random(seed);
+
+ // Not taking a dependent beyond 90% of graph size; similar dependee only in latter
+ // 90%.
+ double factor = 0.90;
+ int limit = (int) (factor * graphSize);
+ int dependeeOffset = graphSize - limit;
+ assert limit != graphSize;
+
+ // TODO: currently ignoring allowCycles parameter.
+ // TODO: Do no cycles for now... ask if would need both types for performance testing.
+ // To disallow cycles, we simply are preventing the dependee number from being less than
+ // the dependent number. This weights the graph in an interesting way: dependents with
+ // smaller numbers will tend to have more dependees.
+ for (int i = 0; i < numDependencies; i++) {
+ int dependentId = generator.nextInt(limit);
+ int dependeeId;
+ do {
+ dependeeId = generator.nextInt(limit) + dependeeOffset;
+ }
+ while (dependeeId <= dependentId);
+ DependencyRelation relation = new DependencyRelation(dependentId, dependeeId);
+ relationships.add(relation);
+ }
+ return relationships;
+ }
+
+}
diff --git a/Ghidra/Framework/Generic/src/test/java/ghidra/util/datastruct/DependencyGraphTest.java b/Ghidra/Framework/Generic/src/test/java/ghidra/util/datastruct/DependencyGraphTest.java
index 81be5018c9..e353bbab4a 100644
--- a/Ghidra/Framework/Generic/src/test/java/ghidra/util/datastruct/DependencyGraphTest.java
+++ b/Ghidra/Framework/Generic/src/test/java/ghidra/util/datastruct/DependencyGraphTest.java
@@ -22,14 +22,95 @@ import java.util.*;
import org.junit.Assert;
import org.junit.Test;
-import ghidra.util.graph.DependencyGraph;
+import ghidra.util.graph.*;
public class DependencyGraphTest {
@Test
- public void testSimpleCase() {
- DependencyGraph graph = new DependencyGraph();
+ public void testSimpleCaseDependencyGraph() {
+ AbstractDependencyGraph graph = new DependencyGraph<>();
+ runSimpleCase(graph);
+ }
+ @Test
+ public void testSimpleCaseDeterministicDependencyGraph() {
+ AbstractDependencyGraph graph = new DeterministicDependencyGraph<>();
+ runSimpleCase(graph);
+ }
+
+ @Test
+ public void testMultipleDependencyCaseDependencyGraph() {
+ AbstractDependencyGraph graph = new DependencyGraph<>();
+ runMultipleDependencyCase(graph);
+ }
+
+ @Test
+ public void testMultipleDependencyCaseDeterministicDependencyGraph() {
+ AbstractDependencyGraph graph = new DeterministicDependencyGraph<>();
+ runMultipleDependencyCase(graph);
+ }
+
+ @Test
+ public void testPopDependencyGraph() {
+ AbstractDependencyGraph graph = new DependencyGraph<>();
+ runPop(graph);
+ }
+
+ @Test
+ public void testPopDeterministicDependencyGraph() {
+ AbstractDependencyGraph graph = new DeterministicDependencyGraph<>();
+ runPop(graph);
+ }
+
+ @Test
+ public void testPopWithCycleDependencyGraph() {
+ AbstractDependencyGraph graph = new DependencyGraph<>();
+ runPopWithCycle(graph);
+ }
+
+ @Test
+ public void testPopWithCycleDeterministicDependencyGraph() {
+ AbstractDependencyGraph graph = new DeterministicDependencyGraph<>();
+ runPopWithCycle(graph);
+ }
+
+ @Test
+ public void testCycleDetectionDependencyGraph() {
+ AbstractDependencyGraph graph = new DependencyGraph<>();
+ runCycleDetection(graph);
+ }
+
+ @Test
+ public void testCycleDetectionDeterministicDependencyGraph() {
+ AbstractDependencyGraph graph = new DeterministicDependencyGraph<>();
+ runCycleDetection(graph);
+ }
+
+ @Test
+ public void testCycleDetectionDoesNotCorruptGraphDependencyGraph() {
+ AbstractDependencyGraph graph = new DependencyGraph<>();
+ runCycleDetectionDoesNotCorruptGraph(graph);
+ }
+
+ @Test
+ public void testCycleDetectionDoesNotCorruptGraphDeterministicDependencyGraph() {
+ AbstractDependencyGraph graph = new DeterministicDependencyGraph<>();
+ runCycleDetectionDoesNotCorruptGraph(graph);
+ }
+
+ @Test
+ public void testRandomProcessingOfDependenciesSimulationDependencyGraph() {
+ AbstractDependencyGraph graph = new DependencyGraph<>();
+ runRandomProcessingOfDependenciesSimulation(graph);
+ }
+
+ @Test
+ public void testRandomProcessingOfDependenciesSimulationDeterministicDependencyGraph() {
+ AbstractDependencyGraph graph = new DeterministicDependencyGraph<>();
+ runRandomProcessingOfDependenciesSimulation(graph);
+ }
+
+ private void runSimpleCase(AbstractDependencyGraph graph) {
graph.addDependency(1, 2);
graph.addDependency(2, 3);
graph.addDependency(3, 4);
@@ -56,13 +137,9 @@ public class DependencyGraphTest {
graph.remove(1);
set = graph.getUnvisitedIndependentValues();
assertTrue(set.isEmpty());
-
}
- @Test
- public void testMultipleDependencyCase() {
- DependencyGraph graph = new DependencyGraph();
-
+ private void runMultipleDependencyCase(AbstractDependencyGraph graph) {
graph.addDependency(1, 2);
graph.addDependency(2, 3);
graph.addDependency(1, 3);
@@ -84,13 +161,9 @@ public class DependencyGraphTest {
graph.remove(1);
set = graph.getUnvisitedIndependentValues();
assertTrue(set.isEmpty());
-
}
- @Test
- public void testPop() {
- DependencyGraph graph = new DependencyGraph();
-
+ private void runPop(AbstractDependencyGraph graph) {
graph.addDependency(1, 2);
graph.addDependency(2, 3);
graph.addDependency(3, 4);
@@ -103,10 +176,7 @@ public class DependencyGraphTest {
assertNull(graph.pop());
}
- @Test
- public void testPopWithCycle() {
- DependencyGraph graph = new DependencyGraph();
-
+ private void runPopWithCycle(AbstractDependencyGraph graph) {
graph.addDependency(1, 2);
graph.addDependency(2, 3);
graph.addDependency(3, 4);
@@ -121,13 +191,9 @@ public class DependencyGraphTest {
catch (IllegalStateException e) {
// expected
}
-
}
- @Test
- public void testCycleDetection() {
- DependencyGraph graph = new DependencyGraph();
-
+ private void runCycleDetection(AbstractDependencyGraph graph) {
graph.addDependency(1, 2);
graph.addDependency(2, 3);
graph.addDependency(3, 4);
@@ -137,13 +203,9 @@ public class DependencyGraphTest {
graph.addDependency(4, 1);
assertTrue(graph.hasCycles());
-
}
- @Test
- public void testCycleDetectionDoesNotCorruptGraph() {
- DependencyGraph graph = new DependencyGraph();
-
+ private void runCycleDetectionDoesNotCorruptGraph(AbstractDependencyGraph graph) {
graph.addDependency(1, 2);
graph.addDependency(2, 3);
graph.addDependency(3, 4);
@@ -172,14 +234,12 @@ public class DependencyGraphTest {
graph.remove(1);
set = graph.getUnvisitedIndependentValues();
assertTrue(set.isEmpty());
-
}
- @Test
- public void testRandomProcessingOfDependenciesSimulation() {
- final ArrayList completionOrder = new ArrayList();
+ private void runRandomProcessingOfDependenciesSimulation(
+ AbstractDependencyGraph graph) {
+ final ArrayList completionOrder = new ArrayList<>();
- DependencyGraph graph = new DependencyGraph();
graph.addDependency("@0", "A8");
graph.addDependency("@1", "A1");
graph.addDependency("@2", "A7");
@@ -214,7 +274,7 @@ public class DependencyGraphTest {
assertTrue(!graph.hasCycles());
- DependencyGraph savedGraph = graph.copy();
+ AbstractDependencyGraph savedGraph = graph.copy();
while (!graph.isEmpty()) {
completionOrder.add(graph.pop());
@@ -231,7 +291,7 @@ public class DependencyGraphTest {
* @param visitedOrder the actual execution order to be tested
* @return
*/
- public void checkOrderSatisfiesDependencies(DependencyGraph dependencyGraph,
+ private void checkOrderSatisfiesDependencies(AbstractDependencyGraph dependencyGraph,
List visitedOrder) {
if (visitedOrder.size() > dependencyGraph.size()) {
@@ -241,12 +301,12 @@ public class DependencyGraphTest {
Assert.fail("Not all items in the graph were visited");
}
- HashSet items = new HashSet(visitedOrder);
+ HashSet items = new HashSet<>(visitedOrder);
if (items.size() != visitedOrder.size()) {
Assert.fail("duplicate item(s) in linearOrder\n");
}
- HashMap visitedOrderMap = new HashMap();
+ HashMap visitedOrderMap = new HashMap<>();
for (int i = 0; i < visitedOrder.size(); i++) {
visitedOrderMap.put(visitedOrder.get(i), i);
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/util/AcyclicCallGraphBuilder.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/util/AcyclicCallGraphBuilder.java
index da6ba36c77..3c1ed66c1c 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/util/AcyclicCallGraphBuilder.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/util/AcyclicCallGraphBuilder.java
@@ -22,6 +22,7 @@ import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceManager;
import ghidra.util.exception.CancelledException;
+import ghidra.util.graph.AbstractDependencyGraph;
import ghidra.util.graph.DependencyGraph;
import ghidra.util.task.TaskMonitor;
@@ -84,10 +85,10 @@ public class AcyclicCallGraphBuilder {
* @return the DependencyGraph for the acyclic call graph represented by this object.
* @throws CancelledException if the monitor was cancelled.
*/
- public DependencyGraph getDependencyGraph(TaskMonitor monitor)
+ public AbstractDependencyGraph getDependencyGraph(TaskMonitor monitor)
throws CancelledException {
- DependencyGraph graph = new DependencyGraph<>();
+ AbstractDependencyGraph graph = new DependencyGraph<>();
Deque startPoints = findStartPoints();
Set unprocessed = new TreeSet<>(functionSet); // reliable processing order
@@ -158,7 +159,7 @@ public class AcyclicCallGraphBuilder {
children.toArray(node.children);
}
- private void processForward(DependencyGraph graph, Set unprocessed,
+ private void processForward(AbstractDependencyGraph graph, Set unprocessed,
Address startFunction, TaskMonitor monitor) throws CancelledException {
VisitStack stack = new VisitStack(startFunction);
StackNode curnode = stack.peek();
diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/util/AcyclicCallGraphBuilderTest.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/util/AcyclicCallGraphBuilderTest.java
index d408719783..0fb88df8df 100644
--- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/util/AcyclicCallGraphBuilderTest.java
+++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/util/AcyclicCallGraphBuilderTest.java
@@ -27,7 +27,7 @@ import ghidra.program.model.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.ReferenceManager;
-import ghidra.util.graph.DependencyGraph;
+import ghidra.util.graph.AbstractDependencyGraph;
public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
@@ -102,7 +102,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
node(3, 4);
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(4, graph.size());
@@ -119,7 +119,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
node(2,3);
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program,functions,false);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(3, graph.size());
@@ -135,7 +135,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
node(3, 1);
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(3, graph.size());
@@ -152,7 +152,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
node(2, 2);
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(3, graph.size());
@@ -168,7 +168,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
node(3, 1);
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(3, graph.size());
@@ -197,7 +197,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
thunkNode(17, 18, false);
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(18, graph.size());
@@ -241,7 +241,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
thunkNode(17, 18, false);
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, true);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(8, graph.size());
@@ -265,7 +265,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
thunkNode(5, 3, true); // Thunk node hits recursion from different point
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, true);
- DependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
+ AbstractDependencyGraph graph = builder.getDependencyGraph(DUMMY_MONITOR);
Assert.assertEquals(4, graph.size());
assertDependents(graph, 2, 1);
@@ -274,7 +274,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
Assert.assertFalse(graph.hasCycles());
}
- private void assertDependents(DependencyGraph graph, int fromID, int... toIDs) {
+ private void assertDependents(AbstractDependencyGraph graph, int fromID, int... toIDs) {
Set expectedSet = new HashSet();
for (int toAddr : toIDs) {
expectedSet.add(functionAddress(toAddr));