
commonMain.TopologicalSort.kt Maven / Gradle / Ivy
package com.amplitude.experiment.evaluation
class CycleException(val cycle: Set) : RuntimeException() {
override val message: String
get() = "Detected a cycle between flags $cycle"
}
@Throws(CycleException::class)
fun topologicalSort(
flagConfigs: List,
flagKeys: Set = setOf()
): List {
return topologicalSort(flagConfigs.associateBy { it.key }, flagKeys)
}
@Throws(CycleException::class)
fun topologicalSort(
flagConfigs: Map,
flagKeys: Set = setOf()
): List {
val available = flagConfigs.toMutableMap()
val result = mutableListOf()
val startingKeys = flagKeys.ifEmpty {
available.keys.toSet()
}
for (flagKey in startingKeys) {
val traversal = parentTraversal(flagKey, available) ?: continue
result.addAll(traversal)
}
return result
}
private fun parentTraversal(
flagKey: String,
available: MutableMap,
path: MutableSet = mutableSetOf(),
): List? {
val flag = available[flagKey] ?: return null
if (flag.dependencies.isNullOrEmpty()) {
available.remove(flag.key)
return listOf(flag)
}
path.add(flag.key)
val result = mutableListOf()
for (parentKey in flag.dependencies) {
if (path.contains(parentKey)) {
throw CycleException(path)
}
val traversal = parentTraversal(parentKey, available, path) ?: continue
result.addAll(traversal)
}
result.add(flag)
path.remove(flag.key)
available.remove(flag.key)
return result
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy