1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 08:27:12 -07:00

Add transitiveClosure() to DynamicGraph.

This commit is contained in:
Cedric Beust 2016-07-28 19:18:12 -07:00
parent c2441f939a
commit 67cb7a5360
2 changed files with 38 additions and 0 deletions

View file

@ -30,6 +30,28 @@ class DynamicGraph<T> {
private val dependedUpon = HashMultimap.create<Node<T>, Node<T>>() private val dependedUpon = HashMultimap.create<Node<T>, Node<T>>()
private val dependingOn = HashMultimap.create<Node<T>, Node<T>>() private val dependingOn = HashMultimap.create<Node<T>, Node<T>>()
fun transitiveClosure(root: T): Set<T> {
val result = hashSetOf<T>()
val seen = hashSetOf<T>()
val toProcess = arrayListOf<T>().apply {
add(root)
}
while (toProcess.any()) {
val newToProcess = arrayListOf<T>()
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) { fun addNode(t: T) = synchronized(nodes) {
nodes.add(Node(t)) nodes.add(Node(t))
} }

View file

@ -2,6 +2,7 @@ package com.beust.kobalt.internal
import com.beust.kobalt.misc.Topological import com.beust.kobalt.misc.Topological
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import org.assertj.core.api.Assertions.assertThat
import org.testng.Assert import org.testng.Assert
import org.testng.annotations.Test import org.testng.annotations.Test
import java.util.* import java.util.*
@ -48,6 +49,21 @@ class DynamicGraphTest {
} }
} }
@Test
fun transitive() {
DynamicGraph<Int>().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 @Test
private fun testExecutorWithSkip() { private fun testExecutorWithSkip() {