From 0fe79a37006cb7c66199565a9398dd6fc5be8ee7 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Fri, 9 Nov 2018 20:34:17 +0300 Subject: [PATCH] [vcs-log-graph] introduce GraphUtil and move methods there --- .../collapsing/BranchFilterController.java | 4 +- .../graph/collapsing/CollapsedController.java | 4 +- .../log/graph/impl/facade/ReachableNodes.kt | 20 ------ .../intellij/vcs/log/graph/utils/BfsUtil.kt | 26 +------ .../intellij/vcs/log/graph/utils/DfsUtil.kt | 28 +------- .../intellij/vcs/log/graph/utils/GraphUtil.kt | 68 +++++++++++++++++++ .../intellij/vcs/log/graph/impl/BfsTests.kt | 6 +- .../intellij/vcs/log/history/FileHistory.kt | 6 +- 8 files changed, 78 insertions(+), 84 deletions(-) create mode 100644 platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/GraphUtil.kt diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/BranchFilterController.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/BranchFilterController.java index 6311a96081b0..b27506cfb533 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/BranchFilterController.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/BranchFilterController.java @@ -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 idsOfVisibleBranches) { super(delegateLinearGraphController, permanentGraphInfo); - myVisibility = ReachableNodes.getReachableNodes(myPermanentGraphInfo.getLinearGraph(), idsOfVisibleBranches); + myVisibility = GraphUtilKt.getReachableNodes(myPermanentGraphInfo.getLinearGraph(), idsOfVisibleBranches); myCollapsedGraph = update(); } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedController.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedController.java index cac8f4c1b984..dabf2f2fa6c0 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedController.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedController.java @@ -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 idsOfVisibleBranches) { super(delegateLinearGraphController, permanentGraphInfo); - UnsignedBitSet initVisibility = ReachableNodes.getReachableNodes(permanentGraphInfo.getLinearGraph(), idsOfVisibleBranches); + UnsignedBitSet initVisibility = GraphUtilKt.getReachableNodes(permanentGraphInfo.getLinearGraph(), idsOfVisibleBranches); myCollapsedGraph = CollapsedGraph.newInstance(getDelegateController().getCompiledGraph(), initVisibility); } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.kt b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.kt index 6190cad58591..c80b31b42400 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.kt +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.kt @@ -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?): 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 - } - } } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/BfsUtil.kt b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/BfsUtil.kt index fbb014dded29..2a3903ae63d4 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/BfsUtil.kt +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/BfsUtil.kt @@ -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] - } - -} +} \ No newline at end of file diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/DfsUtil.kt b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/DfsUtil.kt index 75d25af10436..6f1c517ac54b 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/DfsUtil.kt +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/DfsUtil.kt @@ -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() -} +} \ No newline at end of file diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/GraphUtil.kt b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/GraphUtil.kt new file mode 100644 index 000000000000..d7aa40fc1d0d --- /dev/null +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/GraphUtil.kt @@ -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?): 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] +} \ No newline at end of file diff --git a/platform/vcs-log/graph/test/com/intellij/vcs/log/graph/impl/BfsTests.kt b/platform/vcs-log/graph/test/com/intellij/vcs/log/graph/impl/BfsTests.kt index 649b25adae0a..540dcdbe0f52 100644 --- a/platform/vcs-log/graph/test/com/intellij/vcs/log/graph/impl/BfsTests.kt +++ b/platform/vcs-log/graph/test/com/intellij/vcs/log/graph/impl/BfsTests.kt @@ -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)}") } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistory.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistory.kt index 60b1405add61..a705fdab489d 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistory.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistory.kt @@ -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