All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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