GraphAlgorithmsImpl#collectOutsRecursively: use non-recursive traversal

add tests for GraphAlgorithms#collectOutsRecursively

(cherry picked from commit 02398dc)

IDEA-CR-30465
This commit is contained in:
Vladimir Koshelev
2018-03-12 17:04:07 +03:00
parent e7391f7240
commit 96079e5c48
2 changed files with 83 additions and 4 deletions
@@ -3,6 +3,7 @@ package com.intellij.util.graph.impl;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.util.Chunk;
import com.intellij.util.containers.Stack;
import com.intellij.util.graph.*;
import org.jetbrains.annotations.NotNull;
@@ -96,10 +97,17 @@ public class GraphAlgorithmsImpl extends GraphAlgorithms {
if (!set.add(start)) {
return;
}
Iterator<Node> iterator = graph.getOut(start);
while (iterator.hasNext()) {
Node node = iterator.next();
collectOutsRecursively(graph, node, set);
final Stack<Node> stack = new Stack<>();
stack.push(start);
while (!stack.empty()) {
final Node currentNode = stack.pop();
final Iterator<Node> successorIterator = graph.getOut(currentNode);
while (successorIterator.hasNext()) {
Node successor = successorIterator.next();
if (set.add(successor)) {
stack.push(successor);
}
}
}
}
@@ -0,0 +1,71 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.graph;
import com.intellij.util.ArrayUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
public class CollectTest extends GraphTestCase {
@Test
public void testSimple() {
Map<String, String> graph = new THashMap<>();
graph.put("a", "b");
graph.put("b", "c");
graph.put("c", "c");
doTest(graph, "b", "b", "c");
}
@Test
public void testFull() {
Map<String, String> graph = new THashMap<>();
graph.put("a", "bcd");
graph.put("b", "acd");
graph.put("c", "abd");
graph.put("d", "abc");
doTest(graph, "a", "a", "b", "c", "d");
}
@Test
public void testVisitedNode() {
Map<String, String> graph = new THashMap<>();
graph.put("a", "bcd");
graph.put("b", "acd");
graph.put("c", "abd");
graph.put("d", "abc");
Set<String> nodes = new THashSet<>();
nodes.add("a");
getAlgorithmsInstance().collectOutsRecursively(initGraph(graph), "a", nodes);
assertThat(nodes.size()).isEqualTo(1);
}
@Test
public void testBigGraph() {
Map<String, String> graph = new THashMap<>();
List<String> answer = new ArrayList<>();
for (int i = 0; i < 10000; ++i) {
graph.put(String.valueOf((char)i), String.valueOf((char)(i + 1)));
answer.add(String.valueOf((char)i));
}
graph.put(String.valueOf((char)10000), String.valueOf((char)0));
answer.add(String.valueOf((char)10000));
doTest(graph, "0", ArrayUtil.toStringArray(answer));
}
private static void doTest(final @NotNull Map<String, String> graph,
final @NotNull String node,
final @NotNull String... expected) {
Set<String> nodes = new THashSet<>();
getAlgorithmsInstance().collectOutsRecursively(initGraph(graph), node, nodes);
assertThat(nodes).containsExactlyInAnyOrder(expected);
}
}