mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs-log-graph] introduce GraphUtil and move methods there
This commit is contained in:
+2
-2
@@ -20,7 +20,7 @@ import com.intellij.vcs.log.graph.api.elements.GraphElement;
|
||||
import com.intellij.vcs.log.graph.api.permanent.PermanentGraphInfo;
|
||||
import com.intellij.vcs.log.graph.impl.facade.CascadeController;
|
||||
import com.intellij.vcs.log.graph.impl.facade.LinearGraphController;
|
||||
import com.intellij.vcs.log.graph.impl.facade.ReachableNodes;
|
||||
import com.intellij.vcs.log.graph.utils.GraphUtilKt;
|
||||
import com.intellij.vcs.log.graph.utils.UnsignedBitSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -35,7 +35,7 @@ public class BranchFilterController extends CascadeController {
|
||||
@NotNull PermanentGraphInfo<?> permanentGraphInfo,
|
||||
@Nullable Set<Integer> idsOfVisibleBranches) {
|
||||
super(delegateLinearGraphController, permanentGraphInfo);
|
||||
myVisibility = ReachableNodes.getReachableNodes(myPermanentGraphInfo.getLinearGraph(), idsOfVisibleBranches);
|
||||
myVisibility = GraphUtilKt.getReachableNodes(myPermanentGraphInfo.getLinearGraph(), idsOfVisibleBranches);
|
||||
myCollapsedGraph = update();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import com.intellij.vcs.log.graph.api.permanent.PermanentGraphInfo;
|
||||
import com.intellij.vcs.log.graph.impl.facade.CascadeController;
|
||||
import com.intellij.vcs.log.graph.impl.facade.GraphChanges;
|
||||
import com.intellij.vcs.log.graph.impl.facade.LinearGraphController;
|
||||
import com.intellij.vcs.log.graph.impl.facade.ReachableNodes;
|
||||
import com.intellij.vcs.log.graph.utils.GraphUtilKt;
|
||||
import com.intellij.vcs.log.graph.utils.UnsignedBitSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -38,7 +38,7 @@ public class CollapsedController extends CascadeController {
|
||||
@NotNull final PermanentGraphInfo<?> permanentGraphInfo,
|
||||
@Nullable Set<Integer> idsOfVisibleBranches) {
|
||||
super(delegateLinearGraphController, permanentGraphInfo);
|
||||
UnsignedBitSet initVisibility = ReachableNodes.getReachableNodes(permanentGraphInfo.getLinearGraph(), idsOfVisibleBranches);
|
||||
UnsignedBitSet initVisibility = GraphUtilKt.getReachableNodes(permanentGraphInfo.getLinearGraph(), idsOfVisibleBranches);
|
||||
myCollapsedGraph = CollapsedGraph.newInstance(getDelegateController().getCompiledGraph(), initVisibility);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
package com.intellij.vcs.log.graph.impl.facade
|
||||
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.vcs.log.graph.api.LinearGraph
|
||||
import com.intellij.vcs.log.graph.api.LiteLinearGraph
|
||||
import com.intellij.vcs.log.graph.utils.DfsWalk
|
||||
import com.intellij.vcs.log.graph.utils.Flags
|
||||
import com.intellij.vcs.log.graph.utils.UnsignedBitSet
|
||||
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags
|
||||
import java.util.*
|
||||
|
||||
@@ -52,22 +50,4 @@ class ReachableNodes(private val graph: LiteLinearGraph) {
|
||||
DfsWalk(startNodes, graph, visited).walk(goDown, consumer)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getReachableNodes(graph: LinearGraph, headNodeIndexes: Set<Int>?): UnsignedBitSet {
|
||||
if (headNodeIndexes == null) {
|
||||
val nodesVisibility = UnsignedBitSet()
|
||||
nodesVisibility.set(0, graph.nodesCount() - 1, true)
|
||||
return nodesVisibility
|
||||
}
|
||||
|
||||
val result = UnsignedBitSet()
|
||||
DfsWalk(headNodeIndexes, graph).walk(true) { node: Int ->
|
||||
result.set(node, true)
|
||||
true
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,28 +41,4 @@ class BfsWalk(val start: Int, private val graph: LiteLinearGraph, private val vi
|
||||
step()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object BfsUtil {
|
||||
fun getCorrespondingParent(graph: LiteLinearGraph, startNode: Int, endNode: Int, visited: Flags): Int {
|
||||
val candidates = graph.getNodes(startNode, LiteLinearGraph.NodeFilter.DOWN)
|
||||
if (candidates.size == 1) return candidates[0]
|
||||
if (candidates.contains(endNode)) return endNode
|
||||
|
||||
val bfsWalks = candidates.mapTo(mutableListOf()) { BfsWalk(it, graph, visited) }
|
||||
|
||||
visited.setAll(false)
|
||||
do {
|
||||
for (walk in bfsWalks) {
|
||||
if (walk.step().contains(endNode)) {
|
||||
return walk.start
|
||||
}
|
||||
}
|
||||
bfsWalks.removeIf { it.isFinished() }
|
||||
}
|
||||
while (bfsWalks.isNotEmpty())
|
||||
|
||||
return candidates[0]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.intellij.vcs.log.graph.utils
|
||||
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.util.containers.IntStack
|
||||
import com.intellij.vcs.log.graph.api.LinearGraph
|
||||
import com.intellij.vcs.log.graph.api.LiteLinearGraph
|
||||
@@ -136,29 +135,4 @@ private fun isDown(stack: IntStack): Boolean {
|
||||
val previousNode = getPreviousNode(stack)
|
||||
if (previousNode == Dfs.NextNode.NODE_NOT_FOUND) return true
|
||||
return previousNode < currentNode
|
||||
}
|
||||
|
||||
fun LiteLinearGraph.isAncestor(lowerNode: Int, upperNode: Int): Boolean {
|
||||
val visited = BitSetFlags(nodesCount(), false)
|
||||
|
||||
val result = Ref.create(false)
|
||||
walk(lowerNode) { currentNode ->
|
||||
visited.set(currentNode, true)
|
||||
|
||||
if (currentNode == upperNode) {
|
||||
result.set(true)
|
||||
return@walk Dfs.NextNode.EXIT
|
||||
}
|
||||
if (currentNode > upperNode) {
|
||||
for (nextNode in getNodes(currentNode, LiteLinearGraph.NodeFilter.UP)) {
|
||||
if (!visited.get(nextNode)) {
|
||||
return@walk nextNode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dfs.NextNode.NODE_NOT_FOUND
|
||||
}
|
||||
|
||||
return result.get()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.vcs.log.graph.utils
|
||||
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.vcs.log.graph.api.LinearGraph
|
||||
import com.intellij.vcs.log.graph.api.LiteLinearGraph
|
||||
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags
|
||||
|
||||
fun getReachableNodes(graph: LinearGraph, headNodes: Set<Int>?): UnsignedBitSet {
|
||||
if (headNodes == null) {
|
||||
val nodesVisibility = UnsignedBitSet()
|
||||
nodesVisibility.set(0, graph.nodesCount() - 1, true)
|
||||
return nodesVisibility
|
||||
}
|
||||
|
||||
val result = UnsignedBitSet()
|
||||
DfsWalk(headNodes, graph).walk(true) { node: Int ->
|
||||
result.set(node, true)
|
||||
true
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun LiteLinearGraph.isAncestor(lowerNode: Int, upperNode: Int): Boolean {
|
||||
val visited = BitSetFlags(nodesCount(), false)
|
||||
|
||||
val result = Ref.create(false)
|
||||
walk(lowerNode) { currentNode ->
|
||||
visited.set(currentNode, true)
|
||||
|
||||
if (currentNode == upperNode) {
|
||||
result.set(true)
|
||||
return@walk Dfs.NextNode.EXIT
|
||||
}
|
||||
if (currentNode > upperNode) {
|
||||
for (nextNode in getNodes(currentNode, LiteLinearGraph.NodeFilter.UP)) {
|
||||
if (!visited.get(nextNode)) {
|
||||
return@walk nextNode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dfs.NextNode.NODE_NOT_FOUND
|
||||
}
|
||||
|
||||
return result.get()
|
||||
}
|
||||
|
||||
fun getCorrespondingParent(graph: LiteLinearGraph, startNode: Int, endNode: Int, visited: Flags): Int {
|
||||
val candidates = graph.getNodes(startNode, LiteLinearGraph.NodeFilter.DOWN)
|
||||
if (candidates.size == 1) return candidates[0]
|
||||
if (candidates.contains(endNode)) return endNode
|
||||
|
||||
val bfsWalks = candidates.mapTo(mutableListOf()) { BfsWalk(it, graph, visited) }
|
||||
|
||||
visited.setAll(false)
|
||||
do {
|
||||
for (walk in bfsWalks) {
|
||||
if (walk.step().contains(endNode)) {
|
||||
return walk.start
|
||||
}
|
||||
}
|
||||
bfsWalks.removeIf { it.isFinished() }
|
||||
}
|
||||
while (bfsWalks.isNotEmpty())
|
||||
|
||||
return candidates[0]
|
||||
}
|
||||
@@ -4,9 +4,9 @@ package com.intellij.vcs.log.graph.impl
|
||||
import com.intellij.vcs.log.graph.TestGraphBuilder
|
||||
import com.intellij.vcs.log.graph.asString
|
||||
import com.intellij.vcs.log.graph.graph
|
||||
import com.intellij.vcs.log.graph.utils.BfsUtil
|
||||
import com.intellij.vcs.log.graph.utils.BfsWalk
|
||||
import com.intellij.vcs.log.graph.utils.LinearGraphUtils
|
||||
import com.intellij.vcs.log.graph.utils.getCorrespondingParent
|
||||
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
@@ -15,8 +15,8 @@ class BfsTests {
|
||||
|
||||
private fun assertCorrespondingParent(startNode: Int, endNode: Int, expectedParent: Int, graphBuilder: TestGraphBuilder.() -> Unit) {
|
||||
val graph = graph(graphBuilder)
|
||||
val actualParent = BfsUtil.getCorrespondingParent(LinearGraphUtils.asLiteLinearGraph(graph), startNode, endNode,
|
||||
BitSetFlags(graph.nodesCount()))
|
||||
val actualParent = getCorrespondingParent(LinearGraphUtils.asLiteLinearGraph(graph), startNode, endNode,
|
||||
BitSetFlags(graph.nodesCount()))
|
||||
assertEquals(expectedParent, actualParent,
|
||||
"Incorrect parent found when walking from ${startNode} to ${endNode} in ${graph.asString(true)}")
|
||||
}
|
||||
|
||||
@@ -19,12 +19,8 @@ import com.intellij.vcs.log.graph.api.permanent.PermanentCommitsInfo
|
||||
import com.intellij.vcs.log.graph.api.permanent.PermanentGraphInfo
|
||||
import com.intellij.vcs.log.graph.collapsing.CollapsedGraph
|
||||
import com.intellij.vcs.log.graph.impl.facade.*
|
||||
import com.intellij.vcs.log.graph.utils.BfsUtil.getCorrespondingParent
|
||||
import com.intellij.vcs.log.graph.utils.Dfs
|
||||
import com.intellij.vcs.log.graph.utils.LinearGraphUtils
|
||||
import com.intellij.vcs.log.graph.utils.*
|
||||
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags
|
||||
import com.intellij.vcs.log.graph.utils.isAncestor
|
||||
import com.intellij.vcs.log.graph.utils.walk
|
||||
import gnu.trove.*
|
||||
import java.util.*
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
Reference in New Issue
Block a user