From 67cb7a5360b382a63b40fb9a61e4df3a3cb52c63 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 28 Jul 2016 19:18:12 -0700 Subject: [PATCH] Add transitiveClosure() to DynamicGraph. --- .../com/beust/kobalt/internal/DynamicGraph.kt | 22 +++++++++++++++++++ .../beust/kobalt/internal/DynamicGraphTest.kt | 16 ++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt index 193d395d..06d4abde 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt @@ -30,6 +30,28 @@ class DynamicGraph { private val dependedUpon = HashMultimap.create, Node>() private val dependingOn = HashMultimap.create, Node>() + fun transitiveClosure(root: T): Set { + val result = hashSetOf() + val seen = hashSetOf() + val toProcess = arrayListOf().apply { + add(root) + } + while (toProcess.any()) { + val newToProcess = arrayListOf() + toProcess.forEach { + if (! seen.contains(it)) { + result.add(it) + newToProcess.addAll(dependedUpon[Node(it)].map { it.value }) + seen.add(it) + } + } + toProcess.clear() + toProcess.addAll(newToProcess) + } + + return result + } + fun addNode(t: T) = synchronized(nodes) { nodes.add(Node(t)) } diff --git a/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt b/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt index 6298c994..d988b52b 100644 --- a/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt +++ b/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt @@ -2,6 +2,7 @@ package com.beust.kobalt.internal import com.beust.kobalt.misc.Topological import com.beust.kobalt.misc.log +import org.assertj.core.api.Assertions.assertThat import org.testng.Assert import org.testng.annotations.Test import java.util.* @@ -48,6 +49,21 @@ class DynamicGraphTest { } } + @Test + fun transitive() { + DynamicGraph().apply { + addEdge(1, 2) + addEdge(1, 3) + addEdge(2, 4) + addEdge(6, 7) + assertThat(transitiveClosure(1)).isEqualTo(setOf(1, 2, 3, 4)) + assertThat(transitiveClosure(2)).isEqualTo(setOf(2, 4)) + assertThat(transitiveClosure(3)).isEqualTo(setOf(3)) + assertThat(transitiveClosure(6)).isEqualTo(setOf(6, 7)) + assertThat(transitiveClosure(7)).isEqualTo(setOf(7)) + println("done") + } + } @Test private fun testExecutorWithSkip() {