Оптимизировать расчет дерева зависимостей.- Котлин - PullRequest
0 голосов
/ 23 июня 2019

следующий фрагмент сортирует список Table на основе его dependencies друг на друга.Table(s) без dependencies должно идти первым, за которым следует Table(s), что зависит от его предшественников.

data class Table(

    var name: String = "",
    var dependencies: ArrayList<Table> = ArrayList(),
    var dependencyTree: ArrayList<Table> = ArrayList(),
    var syncOrder: Int = -1

) : Comparable<Table> {

    override fun compareTo(other: Table): Int {
        val thisHasNoDependencies = this.dependencyTree.isEmpty()
        val otherHasNoDependencies = other.dependencyTree.isEmpty()
        when {
            thisHasNoDependencies && otherHasNoDependencies -> {
                return 0
            }
            thisHasNoDependencies -> {
                return -1
            }
            otherHasNoDependencies -> {
                return 1
            }
        }

        val thisDependsOnOther = this.name in other.dependencyTree.map { it.name }
        val otherDependsOnThis = other.name in this.dependencyTree.map { it.name }
        when {
            thisDependsOnOther && otherDependsOnThis -> {
                return 0
            }
            thisDependsOnOther -> {
                return -1
            }
            otherDependsOnThis -> {
                return 1
            }
        }

        return 0
    }

    var dependencyTreeCalculated = 0
        private set

    fun calculateDependencyTree(): ArrayList<Table> {
        val dependencies = dependencies
        dependencyTreeCalculated++
        return if (dependencies.isNotEmpty()) {
            val treeDependencies = ArrayList<Table>()
            for (i in 0 until dependencies.size) {
                val table = dependencies[i]
                treeDependencies.add(table)
                treeDependencies.addAll(table.calculateDependencyTree())
            }
            treeDependencies
        } else {
            arrayListOf()
        }
    }
}
fun main() {

    val states = Table(
        name = "res.states"
    )
    val currency = Table(
        name = "res.currency"
    )
    val countries = Table(
        name = "res.countries"
    )
    val rawMaterials = Table(
        name = "res.raw_materials",
        dependencies = arrayListOf(currency)
    )
    val products = Table(
        name = "res.products",
        dependencies = arrayListOf(rawMaterials)
        // indirectly `products` depends on `currency` too.
    )
    val suppliers = Table(
        name = "res.suppliers",
        dependencies = arrayListOf(products, countries)
        // indirectly `suppliers` depends on `rawMaterials` and `currency` too.
    )
    val partners = Table(
        name = "res.partners",
        dependencies = arrayListOf(states, suppliers)
        // indirectly `partners` depends on `products`, `countries`, `rawMaterials` and `currency` too.
    )

    val tables = listOf(
        partners,
        states,
        currency,
        products,
        suppliers,
        rawMaterials,
        countries
    )

    for (i in 0 until tables.size) {
        val table = tables[i]
        table.dependencyTree.addAll(table.calculateDependencyTree())
    }

    println()
    println("Before sorting")
    println(tables.map { it.name })

    val sortedTables = tables.sorted()

    for (i in 0 until sortedTables.size) {
        val table = sortedTables[i]
        println()
        println(table.name)
        println("Dependency Tree Calculated ${table.dependencyTreeCalculated} times")
        println(table.dependencyTree.map { it.name })
    }

    println()
    println("After sorting:")
    println(sortedTables.map { it.name })
}

Вывод приведенного выше фрагмента следующий:

Before sorting
[res.partners, res.states, res.currency, res.products, res.suppliers, res.raw_materials, res.countries]

res.states
Dependency Tree Calculated 2 times
[]

res.currency
Dependency Tree Calculated 5 times
[]

res.countries
Dependency Tree Calculated 3 times
[]

res.raw_materials
Dependency Tree Calculated 4 times
[res.currency]

res.products
Dependency Tree Calculated 3 times
[res.raw_materials, res.currency]

res.suppliers
Dependency Tree Calculated 2 times
[res.products, res.raw_materials, res.currency, res.countries]

res.partners
Dependency Tree Calculated 1 times
[res.states, res.suppliers, res.products, res.raw_materials, res.currency, res.countries]

After sorting:
[res.states, res.currency, res.countries, res.raw_materials, res.products, res.suppliers, res.partners]

В выводе, ненужное повторяющееся вычисление происходит количество времени, например,

res.countries
Dependency Tree Calculated 3 times
res.currency
Dependency Tree Calculated 5 times

Как оптимизировать это?

...