mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[file-history] move NodeVisitor and walk method to DfsUtil and add a comment for walk method
This commit is contained in:
@@ -16,7 +16,11 @@
|
||||
|
||||
package com.intellij.vcs.log.graph.utils;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.containers.IntStack;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import com.intellij.vcs.log.graph.api.LiteLinearGraph;
|
||||
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DfsUtil {
|
||||
@@ -27,6 +31,66 @@ public class DfsUtil {
|
||||
int fun(int currentNode);
|
||||
}
|
||||
|
||||
public interface NodeVisitor {
|
||||
void enterNode(int node);
|
||||
|
||||
void exitNode(int node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Depth-first walk for a graph. For each node, walks both into upward and downward siblings.
|
||||
* Tries to preserve direction of travel: when a node is entered from up-sibling, goes to the down-siblings first.
|
||||
* Then goes to the other up-siblings.
|
||||
* And when a node is entered from down-sibling, goes to the up-siblings first.
|
||||
* Then goes to the other down-siblings.
|
||||
* When a node is entered the first time, enterNode is called.
|
||||
* When a node is passes in the same direction, exitNode is called.
|
||||
* Nothing is called when a all the siblings of the node are visited.
|
||||
*/
|
||||
public static void walk(@NotNull LiteLinearGraph graph, int start, @NotNull NodeVisitor visitor) {
|
||||
BitSetFlags visited = new BitSetFlags(graph.nodesCount(), false);
|
||||
BitSetFlags visitedInSameDirection = new BitSetFlags(graph.nodesCount(), false);
|
||||
|
||||
Stack<Pair<Integer, Boolean>> stack = new Stack<>();
|
||||
stack.push(new Pair<>(start, true)); // commit + direction of travel
|
||||
|
||||
while (!stack.empty()) {
|
||||
int currentNode = stack.peek().first;
|
||||
boolean down = stack.peek().second;
|
||||
if (!visited.get(currentNode)) {
|
||||
visited.set(currentNode, true);
|
||||
visitor.enterNode(currentNode);
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (int nextNode : graph.getNodes(currentNode, down ? LiteLinearGraph.NodeFilter.DOWN : LiteLinearGraph.NodeFilter.UP)) {
|
||||
if (!visited.get(nextNode)) {
|
||||
stack.push(new Pair<>(nextNode, down));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (!visitedInSameDirection.get(currentNode)) {
|
||||
visitedInSameDirection.set(currentNode, true);
|
||||
visitor.exitNode(currentNode);
|
||||
}
|
||||
for (int nextNode : graph.getNodes(currentNode, down ? LiteLinearGraph.NodeFilter.UP : LiteLinearGraph.NodeFilter.DOWN)) {
|
||||
if (!visited.get(nextNode)) {
|
||||
stack.push(new Pair<>(nextNode, !down));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void walk(int startRowIndex, @NotNull NextNode nextNodeFun) {
|
||||
IntStack stack = new IntStack();
|
||||
stack.push(startRowIndex);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.vcs.log.ui.history;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -32,13 +31,12 @@ import com.intellij.vcs.log.data.index.IndexDataGetter;
|
||||
import com.intellij.vcs.log.graph.PermanentGraph;
|
||||
import com.intellij.vcs.log.graph.VisibleGraph;
|
||||
import com.intellij.vcs.log.graph.api.LinearGraph;
|
||||
import com.intellij.vcs.log.graph.api.LiteLinearGraph;
|
||||
import com.intellij.vcs.log.graph.impl.facade.PermanentGraphImpl;
|
||||
import com.intellij.vcs.log.graph.impl.facade.ReachableNodes;
|
||||
import com.intellij.vcs.log.graph.impl.facade.VisibleGraphImpl;
|
||||
import com.intellij.vcs.log.graph.impl.permanent.PermanentCommitsInfoImpl;
|
||||
import com.intellij.vcs.log.graph.utils.DfsUtil;
|
||||
import com.intellij.vcs.log.graph.utils.LinearGraphUtils;
|
||||
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags;
|
||||
import com.intellij.vcs.log.visible.VcsLogFilterer;
|
||||
import com.intellij.vcs.log.visible.VisiblePack;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
@@ -136,57 +134,7 @@ class FileHistoryFilterer extends VcsLogFilterer {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void walk(@NotNull LiteLinearGraph graph, int start, @NotNull NodeVisitor visitor) {
|
||||
BitSetFlags visited = new BitSetFlags(graph.nodesCount(), false);
|
||||
BitSetFlags visitedInSameDirection = new BitSetFlags(graph.nodesCount(), false);
|
||||
|
||||
Stack<Pair<Integer, Boolean>> stack = new Stack<>();
|
||||
stack.push(new Pair<>(start, true)); // commit + direction of travel
|
||||
|
||||
while (!stack.empty()) {
|
||||
int currentNode = stack.peek().first;
|
||||
boolean down = stack.peek().second;
|
||||
if (!visited.get(currentNode)) {
|
||||
visited.set(currentNode, true);
|
||||
visitor.enterNode(currentNode);
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (int nextNode : graph.getNodes(currentNode, down ? LiteLinearGraph.NodeFilter.DOWN : LiteLinearGraph.NodeFilter.UP)) {
|
||||
if (!visited.get(nextNode)) {
|
||||
stack.push(new Pair<>(nextNode, down));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (!visitedInSameDirection.get(currentNode)) {
|
||||
visitedInSameDirection.set(currentNode, true);
|
||||
visitor.exitNode(currentNode);
|
||||
}
|
||||
for (int nextNode : graph.getNodes(currentNode, down ? LiteLinearGraph.NodeFilter.UP : LiteLinearGraph.NodeFilter.DOWN)) {
|
||||
if (!visited.get(nextNode)) {
|
||||
stack.push(new Pair<>(nextNode, !down));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface NodeVisitor {
|
||||
void enterNode(int node);
|
||||
|
||||
void exitNode(int node);
|
||||
}
|
||||
|
||||
private static class FileHistoryRefiner implements NodeVisitor {
|
||||
private static class FileHistoryRefiner implements DfsUtil.NodeVisitor {
|
||||
@NotNull private final VisibleGraph<Integer> myVisibleGraph;
|
||||
@NotNull private final IndexDataGetter.FileNamesData myNamesData;
|
||||
@NotNull private final Stack<FilePath> myPaths;
|
||||
@@ -206,7 +154,7 @@ class FileHistoryFilterer extends VcsLogFilterer {
|
||||
|
||||
public boolean refine(@NotNull LinearGraph graph, int row, @NotNull FilePath startPath) {
|
||||
myPaths.push(startPath);
|
||||
walk(LinearGraphUtils.asLiteLinearGraph(graph), row, this);
|
||||
DfsUtil.walk(LinearGraphUtils.asLiteLinearGraph(graph), row, this);
|
||||
return myWasChanged;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user