mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs-log-graph] include only important branch heads into GraphLayout
Layout indexes for branch heads are saved in the GraphLayoutImpl#startLayoutIndexForHead field, and binary search is used to find a head commit by layout index. Since all branch heads are used for building graph layout, some branch heads are contained in other branches. If a less important branch is contained in a more important branch, the less important branch does not receive its own layout index and is assigned a layout index from the more important branch. This means that GraphLayoutImpl#startLayoutIndexForHead is no longer sorted, and binary search may return incorrect results on it. This commit includes only important branch heads with own layout index into the GraphLayout. follow-up: 1cd228ff6107d0ca03d5f3172f9940e0d55d9e4f GitOrigin-RevId: f3d5bf4cc85b6b8dbea81895a650e4eca8985cad
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1153085450
commit
3655c29472
+5
-1
@@ -55,10 +55,14 @@ object GraphLayoutBuilder {
|
||||
|
||||
private fun build(graph: LinearGraph, sortedHeads: IntList): GraphLayoutImpl {
|
||||
val layoutIndex = IntArray(graph.nodesCount())
|
||||
val importantHeads = IntArrayList()
|
||||
|
||||
var currentLayoutIndex = 1
|
||||
for (i in sortedHeads.indices) {
|
||||
val head = sortedHeads.getInt(i)
|
||||
if (layoutIndex[head] != 0) continue
|
||||
|
||||
importantHeads.add(head)
|
||||
|
||||
walk(head) { currentNode: Int ->
|
||||
val firstVisit = layoutIndex[currentNode] == 0
|
||||
@@ -73,6 +77,6 @@ object GraphLayoutBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
return GraphLayoutImpl(layoutIndex, sortedHeads)
|
||||
return GraphLayoutImpl(layoutIndex, importantHeads)
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.vcs.log.graph.impl.permanent
|
||||
|
||||
import com.intellij.vcs.log.graph.api.LinearGraph
|
||||
import com.intellij.vcs.log.graph.graph
|
||||
import it.unimi.dsi.fastutil.ints.IntComparator
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class GraphLayoutBuilderHeadOrderTest {
|
||||
@Test
|
||||
fun linearGraph() {
|
||||
val graph = graph {
|
||||
0(1)
|
||||
1(2)
|
||||
2(3)
|
||||
3()
|
||||
}
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(0, 2), expectedHeads = listOf(0, 0, 0, 0))
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(2, 0), expectedHeads = listOf(0, 0, 2, 2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun branchingGraph() {
|
||||
val graph = graph {
|
||||
0(2)
|
||||
1(3)
|
||||
2(3)
|
||||
3(4)
|
||||
4()
|
||||
}
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(0, 1, 2), expectedHeads = listOf(0, 1, 0, 0, 0))
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(0, 2, 1), expectedHeads = listOf(0, 1, 0, 0, 0))
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(1, 0, 2), expectedHeads = listOf(0, 1, 0, 1, 1))
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(1, 2, 0), expectedHeads = listOf(0, 1, 2, 1, 1))
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(2, 0, 1), expectedHeads = listOf(0, 1, 2, 2, 2))
|
||||
graph.assertHeadsForCommits(branchHeads = setOf(0, 2), headComparator = order(2, 1, 0), expectedHeads = listOf(0, 1, 2, 2, 2))
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that [com.intellij.vcs.log.graph.api.GraphLayout] built for this graph has correct head commits for each commit in the graph.
|
||||
*/
|
||||
private fun LinearGraph.assertHeadsForCommits(branchHeads: Set<Int>, headComparator: IntComparator, expectedHeads: List<Int>) {
|
||||
val graphLayout = GraphLayoutBuilder.build(this, branchHeads, headComparator)
|
||||
assertEquals(expectedHeads, getHeadNodeIndices(this, graphLayout))
|
||||
}
|
||||
|
||||
/**
|
||||
* For each commit in the graph, computes corresponding head node.
|
||||
*/
|
||||
private fun getHeadNodeIndices(graph: LinearGraph, graphLayout: GraphLayoutImpl): List<Int> {
|
||||
return List(graph.nodesCount()) { graphLayout.getOneOfHeadNodeIndex(it) }
|
||||
}
|
||||
|
||||
private fun order(vararg list: Int): IntComparator {
|
||||
return IntComparator { i, j -> list.indexOf(i) - list.indexOf(j) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user