diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/DependencyGraph.kt b/plugin/src/main/kotlin/com/jraska/module/graph/DependencyGraph.kt index 5edd981..2426a81 100644 --- a/plugin/src/main/kotlin/com/jraska/module/graph/DependencyGraph.kt +++ b/plugin/src/main/kotlin/com/jraska/module/graph/DependencyGraph.kt @@ -62,7 +62,7 @@ class DependencyGraph private constructor() { require(nodes.contains(key)) { "Dependency Tree doesn't contain module: $key" } val connections = mutableListOf>() - addConnections(nodes.getValue(key), connections, mutableSetOf()) + addConnections(nodes.getValue(key), connections, mutableSetOf(), mutableSetOf()) return if (connections.isEmpty()) { createSingular(key) @@ -79,9 +79,17 @@ class DependencyGraph private constructor() { } private fun addConnections( - node: Node, into: MutableList>, - path: MutableSet + node: Node, + into: MutableList>, + path: MutableSet, + visited: MutableSet, ) { + if (visited.contains(node)) { + return + } else { + visited.add(node) + } + path.add(node) node.dependsOn.forEach { dependant -> into.add(node.key to dependant.key) @@ -91,7 +99,7 @@ class DependencyGraph private constructor() { val pathText = path.joinToString(separator = ", ") { it.key } throw IllegalStateException("Dependency cycle detected! Cycle in nodes: '${pathText}'.") } - addConnections(dependant, into, path) + addConnections(dependant, into, path, visited) } path.remove(node) diff --git a/plugin/src/test/kotlin/com/jraska/module/graph/DependencyGraphPerformanceTest.kt b/plugin/src/test/kotlin/com/jraska/module/graph/DependencyGraphPerformanceTest.kt index 048a3d2..d90c71a 100644 --- a/plugin/src/test/kotlin/com/jraska/module/graph/DependencyGraphPerformanceTest.kt +++ b/plugin/src/test/kotlin/com/jraska/module/graph/DependencyGraphPerformanceTest.kt @@ -29,9 +29,27 @@ class DependencyGraphPerformanceTest { assert(statistics.longestPath.pathString().startsWith("23 -> 31 -> 36 -> 57 -> 61 -> 72 -> 74 -> 75")) } - @Test(timeout = 10000) - fun whenTheGraphIsLarge_statisticsSubGraphCreatedFast() { + @Test(timeout = 1_000) + fun whenTheGraphIsLarge_statisticsOfSubgraphMatchFast() { + val subGraphStatistics = dependencyGraph.subTree("31").statistics() + + assert(subGraphStatistics.height == 58) + assert(subGraphStatistics.longestPath.pathString().startsWith("31 -> 36 -> 57 -> 61 -> 72 -> 74 -> 75")) + } + + @Test(timeout = 1_000) + fun whenTheGraphIsLarge_statisticsCreatedFast() { val subGraphStatistics = dependencyGraph.subTree("500").statistics() assert(subGraphStatistics.modulesCount == 281) } + + @Test(timeout = 1_000) // was running out of heap before optimisation + fun whenTheGraphIsLarge_statisticsLargeCreatedFast() { + val subGraphStatistics = dependencyGraph.subTree("2").statistics() + + assert(subGraphStatistics.modulesCount == 870) + assert(subGraphStatistics.edgesCount == 11650) + assert(subGraphStatistics.height == 55) + assert(subGraphStatistics.longestPath.pathString().startsWith("2 -> 30 -> 76 -> 105 -> 119 -> ")) + } }