Skip to content

Commit ea53982

Browse files
committed
Minor Code tweaks
* Made some minor refactoring to graph implementation for better readability of code. * Leveraged streams wherever possible in graphs * Avoid code duplication
1 parent 7357104 commit ea53982

File tree

4 files changed

+39
-50
lines changed

4 files changed

+39
-50
lines changed

testng-core/src/main/java/org/testng/internal/BaseTestMethod.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -190,25 +190,23 @@ public Set<ITestNGMethod> upstreamDependencies() {
190190
}
191191

192192
public void setDownstreamDependencies(Set<ITestNGMethod> methods) {
193-
if (!downstreamDependencies.isEmpty()) {
194-
downstreamDependencies.clear();
195-
}
196-
Set<ITestNGMethod> toAdd = methods;
197-
if (RuntimeBehavior.isMemoryFriendlyMode()) {
198-
toAdd = methods.stream().map(LiteWeightTestNGMethod::new).collect(Collectors.toSet());
199-
}
200-
downstreamDependencies.addAll(toAdd);
193+
setupDependencies(downstreamDependencies, methods);
201194
}
202195

203196
public void setUpstreamDependencies(Set<ITestNGMethod> methods) {
204-
if (!upstreamDependencies.isEmpty()) {
205-
upstreamDependencies.clear();
197+
setupDependencies(upstreamDependencies, methods);
198+
}
199+
200+
private static void setupDependencies(
201+
Set<ITestNGMethod> dependencies, Set<ITestNGMethod> methods) {
202+
if (!dependencies.isEmpty()) {
203+
dependencies.clear();
206204
}
207205
Set<ITestNGMethod> toAdd = methods;
208206
if (RuntimeBehavior.isMemoryFriendlyMode()) {
209207
toAdd = methods.stream().map(LiteWeightTestNGMethod::new).collect(Collectors.toSet());
210208
}
211-
upstreamDependencies.addAll(toAdd);
209+
dependencies.addAll(toAdd);
212210
}
213211

214212
/** {@inheritDoc} */

testng-core/src/main/java/org/testng/internal/Graph.java

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.List;
88
import java.util.Map;
99
import java.util.Set;
10+
import java.util.function.Function;
1011
import java.util.function.Supplier;
1112
import java.util.stream.Collectors;
1213
import org.testng.TestNGException;
@@ -113,6 +114,7 @@ public void topologicalSort() {
113114
//
114115
Node<T> node = findNodeWithNoPredecessors(nodes2);
115116
if (null == node) {
117+
// We found a cycle. Time to use the Tarjan's algorithm to get the cycle.
116118
List<T> cycle = new Tarjan<>(this, nodes2.get(0).getObject()).getCycle();
117119
StringBuilder sb = new StringBuilder();
118120
sb.append("The following methods have cyclic dependencies:\n");
@@ -132,16 +134,12 @@ public void topologicalSort() {
132134

133135
private void initializeIndependentNodes() {
134136
if (null == m_independentNodes) {
135-
List<Node<T>> list = Lists.newArrayList(m_nodes.values());
136-
// Ideally, we should not have to sort this. However, due to a bug where it treats all the
137-
// methods as
138-
// dependent nodes.
139-
list.sort(comparator);
140-
141-
m_independentNodes = Maps.newLinkedHashMap();
142-
for (Node<T> node : list) {
143-
m_independentNodes.put(node.getObject(), node);
144-
}
137+
m_independentNodes =
138+
Lists.newArrayList(m_nodes.values()).stream()
139+
.sorted(comparator)
140+
.collect(
141+
Collectors.toMap(
142+
Node::getObject, Function.identity(), (a, b) -> a, Maps::newLinkedHashMap));
145143
}
146144
}
147145

@@ -159,9 +157,7 @@ private void dumpSortedNodes() {
159157
*/
160158
private void removeFromNodes(List<Node<T>> nodes, Node<T> node) {
161159
nodes.remove(node);
162-
for (Node<T> n : nodes) {
163-
n.removePredecessor(node.getObject());
164-
}
160+
nodes.parallelStream().forEach(it -> it.removePredecessor(node.getObject()));
165161
}
166162

167163
private static void log(String s) {
@@ -173,13 +169,7 @@ private static void log(Supplier<String> s) {
173169
}
174170

175171
private Node<T> findNodeWithNoPredecessors(List<Node<T>> nodes) {
176-
for (Node<T> n : nodes) {
177-
if (!n.hasPredecessors()) {
178-
return n;
179-
}
180-
}
181-
182-
return null;
172+
return nodes.parallelStream().filter(it -> !it.hasPredecessors()).findFirst().orElse(null);
183173
}
184174

185175
/**
@@ -295,7 +285,7 @@ public void addPredecessor(T tm) {
295285
}
296286

297287
public boolean hasPredecessors() {
298-
return m_predecessors.size() > 0;
288+
return !m_predecessors.isEmpty();
299289
}
300290
}
301291
}

testng-core/src/main/java/org/testng/internal/MethodGroupsHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ protected static void findGroupTransitiveClosure(
205205
//
206206
// Only keep going if new methods have been added
207207
//
208-
keepGoing = newMethods.size() > 0;
208+
keepGoing = !newMethods.isEmpty();
209209
includedMethods = Lists.newArrayList();
210210
includedMethods.addAll(newMethods.keySet());
211211
newMethods = Maps.newHashMap();

testng-core/src/main/java/org/testng/internal/Tarjan.java

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,40 @@
1414
*/
1515
public class Tarjan<T> {
1616
int m_index = 0;
17-
private final Stack<T> m_s;
18-
Map<T, Integer> m_indices = Maps.newHashMap();
17+
private final Stack<T> stack;
18+
Map<T, Integer> visitedNodes = Maps.newHashMap();
1919
Map<T, Integer> m_lowlinks = Maps.newHashMap();
2020
private List<T> m_cycle;
2121

2222
public Tarjan(Graph<T> graph, T start) {
23-
m_s = new Stack<>();
23+
stack = new Stack<>();
2424
run(graph, start);
2525
}
2626

27-
private void run(Graph<T> graph, T v) {
28-
m_indices.put(v, m_index);
29-
m_lowlinks.put(v, m_index);
27+
private void run(Graph<T> graph, T start) {
28+
visitedNodes.put(start, m_index);
29+
m_lowlinks.put(start, m_index);
3030
m_index++;
31-
m_s.push(v);
31+
stack.push(start);
3232

33-
for (T vprime : graph.getPredecessors(v)) {
34-
if (!m_indices.containsKey(vprime)) {
35-
run(graph, vprime);
36-
int min = Math.min(m_lowlinks.get(v), m_lowlinks.get(vprime));
37-
m_lowlinks.put(v, min);
38-
} else if (m_s.contains(vprime)) {
39-
m_lowlinks.put(v, Math.min(m_lowlinks.get(v), m_indices.get(vprime)));
33+
for (T predecessor : graph.getPredecessors(start)) {
34+
if (!visitedNodes.containsKey(predecessor)) {
35+
run(graph, predecessor);
36+
int min = Math.min(m_lowlinks.get(start), m_lowlinks.get(predecessor));
37+
m_lowlinks.put(start, min);
38+
} else if (stack.contains(predecessor)) {
39+
int min = Math.min(m_lowlinks.get(start), visitedNodes.get(predecessor));
40+
m_lowlinks.put(start, min);
4041
}
4142
}
4243

43-
if (Objects.equals(m_lowlinks.get(v), m_indices.get(v))) {
44+
if (Objects.equals(m_lowlinks.get(start), visitedNodes.get(start))) {
4445
m_cycle = Lists.newArrayList();
4546
T n;
4647
do {
47-
n = m_s.pop();
48+
n = stack.pop();
4849
m_cycle.add(n);
49-
} while (!n.equals(v));
50+
} while (!n.equals(start));
5051
}
5152
}
5253

0 commit comments

Comments
 (0)