[vcs-log] remove BranchMatchedNodesGenerator since its functionality is duplicated by ReachableNodes (former ContainingBranchesGetter)

This commit is contained in:
Julia Beliaeva
2015-06-09 17:13:08 +03:00
parent 741c5ce5db
commit 08ebe31371
11 changed files with 148 additions and 193 deletions
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.Condition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -46,7 +47,7 @@ public interface PermanentGraph<CommitId> {
Set<CommitId> getContainingBranches(@NotNull CommitId commit);
@NotNull
Condition<CommitId> getContainedInBranchCondition(@NotNull CommitId currentBranchHead);
Condition<CommitId> getContainedInBranchCondition(@NotNull Collection<CommitId> currentBranchHead);
enum SortType {
Normal("Off", "Sort commits topologically and by date"),
@@ -19,6 +19,7 @@ import com.intellij.vcs.log.graph.api.LinearGraph;
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.ReachableNodes;
import com.intellij.vcs.log.graph.utils.UnsignedBitSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,7 +40,7 @@ public class BranchFilterController extends CascadeController {
private void updateCollapsedGraph() {
UnsignedBitSet initVisibility =
BranchMatchedNodesGenerator.generateVisibleNodes(myPermanentGraphInfo.getPermanentLinearGraph(), myIdsOfVisibleBranches);
ReachableNodes.getReachableNodes(myPermanentGraphInfo.getPermanentLinearGraph(), myIdsOfVisibleBranches);
myCollapsedGraph = CollapsedGraph.newInstance(getDelegateController().getCompiledGraph(), initVisibility);
}
@@ -1,74 +0,0 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.vcs.log.graph.collapsing;
import com.intellij.vcs.log.graph.api.LiteLinearGraph;
import com.intellij.vcs.log.graph.impl.permanent.PermanentLinearGraphImpl;
import com.intellij.vcs.log.graph.utils.DfsUtil;
import com.intellij.vcs.log.graph.utils.LinearGraphUtils;
import com.intellij.vcs.log.graph.utils.UnsignedBitSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public class BranchMatchedNodesGenerator {
@NotNull
public static UnsignedBitSet generateVisibleNodes(@NotNull PermanentLinearGraphImpl permanentGraph,
@Nullable Set<Integer> headNodeIndexes) {
if (headNodeIndexes == null) {
UnsignedBitSet nodesVisibility = new UnsignedBitSet();
nodesVisibility.set(0, permanentGraph.nodesCount() - 1, true);
return nodesVisibility;
}
assert !headNodeIndexes.isEmpty();
BranchMatchedNodesGenerator generator = new BranchMatchedNodesGenerator(LinearGraphUtils.asLiteLinearGraph(permanentGraph));
generator.generate(headNodeIndexes);
return generator.myNodesVisibility;
}
@NotNull private final LiteLinearGraph myGraph;
@NotNull private final UnsignedBitSet myNodesVisibility;
@NotNull private final DfsUtil myDfsUtil = new DfsUtil();
BranchMatchedNodesGenerator(@NotNull LiteLinearGraph graph) {
myGraph = graph;
myNodesVisibility = new UnsignedBitSet();
}
private void generate(@NotNull Set<Integer> startedNodes) {
for (int startNode : startedNodes) {
myNodesVisibility.set(startNode, true);
if (startNode < 0) continue;
myDfsUtil.nodeDfsIterator(startNode, new DfsUtil.NextNode() {
@Override
public int fun(int currentNode) {
for (int downNode : myGraph.getNodes(currentNode, LiteLinearGraph.NodeFilter.DOWN)) {
if (!myNodesVisibility.get(downNode)) {
myNodesVisibility.set(downNode, true);
return downNode;
}
}
return NODE_NOT_FOUND;
}
});
}
}
}
@@ -23,6 +23,7 @@ import com.intellij.vcs.log.graph.api.elements.GraphNode;
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.ReachableNodes;
import com.intellij.vcs.log.graph.utils.UnsignedBitSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,7 +38,7 @@ public class CollapsedController extends CascadeController {
@Nullable Set<Integer> IdsOfVisibleBranches) {
super(delegateLinearGraphController, permanentGraphInfo);
UnsignedBitSet initVisibility =
BranchMatchedNodesGenerator.generateVisibleNodes(permanentGraphInfo.getPermanentLinearGraph(), IdsOfVisibleBranches);
ReachableNodes.getReachableNodes(permanentGraphInfo.getPermanentLinearGraph(), IdsOfVisibleBranches);
myCollapsedGraph = CollapsedGraph.newInstance(getDelegateController().getCompiledGraph(), initVisibility);
}
@@ -1,92 +0,0 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.vcs.log.graph.impl.facade;
import com.intellij.util.Consumer;
import com.intellij.vcs.log.graph.api.LiteLinearGraph;
import com.intellij.vcs.log.graph.utils.DfsUtil;
import com.intellij.vcs.log.graph.utils.Flags;
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
public class ContainingBranchesGetter {
@NotNull private final LiteLinearGraph myGraph;
@NotNull private final Set<Integer> myBranchNodeIndexes;
@NotNull private final DfsUtil myDfsUtil = new DfsUtil();
@NotNull private final Flags myTempFlags;
public ContainingBranchesGetter(@NotNull LiteLinearGraph graph, @NotNull Set<Integer> branchNodeIndexes) {
myGraph = graph;
myBranchNodeIndexes = branchNodeIndexes;
myTempFlags = new BitSetFlags(graph.nodesCount());
}
public Set<Integer> getBranchNodeIndexes(int nodeIndex) {
final Set<Integer> result = new HashSet<Integer>();
myTempFlags.setAll(false);
myTempFlags.set(nodeIndex, true);
checkAndAdd(nodeIndex, result);
myDfsUtil.nodeDfsIterator(nodeIndex, new DfsUtil.NextNode() {
@Override
public int fun(int currentNode) {
for (int upNode : myGraph.getNodes(currentNode, LiteLinearGraph.NodeFilter.UP)) {
if (!myTempFlags.get(upNode)) {
myTempFlags.set(upNode, true);
checkAndAdd(upNode, result);
return upNode;
}
}
return NODE_NOT_FOUND;
}
});
return result;
}
private void checkAndAdd(int nodeIndex, Set<Integer> result) {
if (myBranchNodeIndexes.contains(nodeIndex)) result.add(nodeIndex);
}
public void walkBranch(int branchHead, @NotNull final Consumer<Integer> consumer) {
myTempFlags.setAll(false);
myTempFlags.set(branchHead, true);
consumer.consume(branchHead);
myDfsUtil.nodeDfsIterator(branchHead, new DfsUtil.NextNode() {
@Override
public int fun(int currentNode) {
for (int downNode : myGraph.getNodes(currentNode, LiteLinearGraph.NodeFilter.DOWN)) {
if (!myTempFlags.get(downNode)) {
myTempFlags.set(downNode, true);
consumer.consume(downNode);
return downNode;
}
}
return NODE_NOT_FOUND;
}
});
}
}
@@ -19,6 +19,7 @@ package com.intellij.vcs.log.graph.impl.facade;
import com.intellij.openapi.util.Condition;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.graph.*;
@@ -34,10 +35,7 @@ import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
public class PermanentGraphImpl<CommitId> implements PermanentGraph<CommitId>, PermanentGraphInfo<CommitId> {
@@ -79,7 +77,7 @@ public class PermanentGraphImpl<CommitId> implements PermanentGraph<CommitId>, P
@NotNull private final GraphColorManager<CommitId> myGraphColorManager;
@NotNull private final Set<CommitId> myBranchesCommitId;
@NotNull private final Set<Integer> myBranchNodeIds;
@NotNull private final ContainingBranchesGetter myBranchesGetter;
@NotNull private final ReachableNodes myReachableNodes;
@NotNull private final BekIntMap myBekIntMap;
public PermanentGraphImpl(@NotNull PermanentLinearGraphImpl permanentLinearGraph,
@@ -93,7 +91,7 @@ public class PermanentGraphImpl<CommitId> implements PermanentGraph<CommitId>, P
myGraphColorManager = graphColorManager;
myBranchesCommitId = branchesCommitId;
myBranchNodeIds = permanentCommitsInfo.convertToNodeIds(branchesCommitId);
myBranchesGetter = new ContainingBranchesGetter(LinearGraphUtils.asLiteLinearGraph(permanentLinearGraph), myBranchNodeIds);
myReachableNodes = new ReachableNodes(LinearGraphUtils.asLiteLinearGraph(permanentLinearGraph));
myBekIntMap = BekSorter.createBekMap(myPermanentLinearGraph, myPermanentGraphLayout, myPermanentCommitsInfo.getTimestampGetter());
}
@@ -163,15 +161,21 @@ public class PermanentGraphImpl<CommitId> implements PermanentGraph<CommitId>, P
@Override
public Set<CommitId> getContainingBranches(@NotNull CommitId commit) {
int commitIndex = myPermanentCommitsInfo.getNodeId(commit);
return myPermanentCommitsInfo.convertToCommitIdSet(myBranchesGetter.getBranchNodeIndexes(commitIndex));
return myPermanentCommitsInfo.convertToCommitIdSet(myReachableNodes.getContainingBranches(commitIndex, myBranchNodeIds));
}
@NotNull
@Override
public Condition<CommitId> getContainedInBranchCondition(@NotNull final CommitId head) {
if (head instanceof Integer) {
public Condition<CommitId> getContainedInBranchCondition(@NotNull final Collection<CommitId> heads) {
List<Integer> headIds = ContainerUtil.map(heads, new Function<CommitId, Integer>() {
@Override
public Integer fun(CommitId head) {
return myPermanentCommitsInfo.getNodeId(head);
}
});
if (!heads.isEmpty() && ContainerUtil.getFirstItem(heads) instanceof Integer) {
final TIntHashSet branchNodes = new TIntHashSet();
myBranchesGetter.walkBranch(myPermanentCommitsInfo.getNodeId(head), new Consumer<Integer>() {
myReachableNodes.walk(headIds, new Consumer<Integer>() {
@Override
public void consume(Integer node) {
branchNodes.add((Integer)myPermanentCommitsInfo.getCommitId(node));
@@ -186,7 +190,7 @@ public class PermanentGraphImpl<CommitId> implements PermanentGraph<CommitId>, P
}
else {
final Set<CommitId> branchNodes = ContainerUtil.newHashSet();
myBranchesGetter.walkBranch(myPermanentCommitsInfo.getNodeId(head), new Consumer<Integer>() {
myReachableNodes.walk(headIds, new Consumer<Integer>() {
@Override
public void consume(Integer node) {
branchNodes.add(myPermanentCommitsInfo.getCommitId(node));
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.vcs.log.graph.impl.facade;
import com.intellij.util.Consumer;
import com.intellij.vcs.log.graph.api.LiteLinearGraph;
import com.intellij.vcs.log.graph.impl.permanent.PermanentLinearGraphImpl;
import com.intellij.vcs.log.graph.utils.DfsUtil;
import com.intellij.vcs.log.graph.utils.Flags;
import com.intellij.vcs.log.graph.utils.LinearGraphUtils;
import com.intellij.vcs.log.graph.utils.UnsignedBitSet;
import com.intellij.vcs.log.graph.utils.impl.BitSetFlags;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class ReachableNodes {
@NotNull private final LiteLinearGraph myGraph;
@NotNull private final DfsUtil myDfsUtil = new DfsUtil();
@NotNull private final Flags myTempFlags;
public ReachableNodes(@NotNull LiteLinearGraph graph) {
myGraph = graph;
myTempFlags = new BitSetFlags(graph.nodesCount());
}
@NotNull
public static UnsignedBitSet getReachableNodes(@NotNull PermanentLinearGraphImpl permanentGraph, @Nullable Set<Integer> headNodeIndexes) {
if (headNodeIndexes == null) {
UnsignedBitSet nodesVisibility = new UnsignedBitSet();
nodesVisibility.set(0, permanentGraph.nodesCount() - 1, true);
return nodesVisibility;
}
assert !headNodeIndexes.isEmpty();
final UnsignedBitSet result = new UnsignedBitSet();
ReachableNodes getter = new ReachableNodes(LinearGraphUtils.asLiteLinearGraph(permanentGraph));
getter.walk(headNodeIndexes, new Consumer<Integer>() {
@Override
public void consume(Integer node) {
result.set(node, true);
}
});
return result;
}
public Set<Integer> getContainingBranches(int nodeIndex, @NotNull final Collection<Integer> branchNodeIndexes) {
final Set<Integer> result = new HashSet<Integer>();
walk(Collections.singletonList(nodeIndex), false, new Consumer<Integer>() {
@Override
public void consume(Integer integer) {
if (branchNodeIndexes.contains(integer)) result.add(integer);
}
});
return result;
}
public void walk(@NotNull Collection<Integer> headIds, @NotNull final Consumer<Integer> consumer) {
walk(headIds, true, consumer);
}
public void walk(@NotNull Collection<Integer> startNodes, final boolean goDown, @NotNull final Consumer<Integer> consumer) {
synchronized (myTempFlags) {
myTempFlags.setAll(false);
for (int start : startNodes) {
if (myTempFlags.get(start)) continue;
myTempFlags.set(start, true);
consumer.consume(start);
myDfsUtil.nodeDfsIterator(start, new DfsUtil.NextNode() {
@Override
public int fun(int currentNode) {
for (int downNode : myGraph.getNodes(currentNode, goDown ? LiteLinearGraph.NodeFilter.DOWN : LiteLinearGraph.NodeFilter.UP)) {
if (!myTempFlags.get(downNode)) {
myTempFlags.set(downNode, true);
consumer.consume(downNode);
return downNode;
}
}
return NODE_NOT_FOUND;
}
});
}
}
}
}
@@ -23,7 +23,7 @@ import com.intellij.vcs.log.graph.api.GraphLayout;
import com.intellij.vcs.log.graph.api.elements.GraphEdge;
import com.intellij.vcs.log.graph.api.elements.GraphElement;
import com.intellij.vcs.log.graph.api.permanent.PermanentCommitsInfo;
import com.intellij.vcs.log.graph.impl.facade.ContainingBranchesGetter;
import com.intellij.vcs.log.graph.impl.facade.ReachableNodes;
import com.intellij.vcs.log.graph.impl.print.EdgesInRowGenerator;
import com.intellij.vcs.log.graph.impl.print.GraphElementComparatorByLayoutIndex;
import com.intellij.vcs.log.graph.parser.CommitParser;
@@ -70,12 +70,12 @@ public class GraphStrUtils {
return s.toString();
}
public static String containingBranchesGetterToStr(ContainingBranchesGetter containingBranchesGetter, int nodesCount) {
public static String containingBranchesGetterToStr(ReachableNodes reachableNodes, Set<Integer> branches, int nodesCount) {
StringBuilder s = new StringBuilder();
for (int nodeIndex = 0; nodeIndex < nodesCount; nodeIndex++) {
if (nodeIndex != 0) s.append("\n");
List<Integer> branchNodeIndexes = new ArrayList<Integer>(containingBranchesGetter.getBranchNodeIndexes(nodeIndex));
List<Integer> branchNodeIndexes = new ArrayList<Integer>(reachableNodes.getContainingBranches(nodeIndex, branches));
if (branchNodeIndexes.isEmpty()) {
s.append("none");
continue;
@@ -20,7 +20,7 @@ import com.intellij.vcs.log.graph.AbstractTestWithTwoTextFile;
import com.intellij.vcs.log.graph.GraphCommit;
import com.intellij.vcs.log.graph.api.LinearGraph;
import com.intellij.vcs.log.graph.impl.CommitIdManager;
import com.intellij.vcs.log.graph.impl.facade.ContainingBranchesGetter;
import com.intellij.vcs.log.graph.impl.facade.ReachableNodes;
import com.intellij.vcs.log.graph.utils.LinearGraphUtils;
import org.junit.Test;
@@ -53,10 +53,11 @@ public abstract class ContainingBranchesTest<CommitId> extends AbstractTestWithT
List<GraphCommit<CommitId>> commits = getCommitIdManager().parseCommitList(in.substring(0, i));
LinearGraph graph = PermanentLinearGraphBuilder.newInstance(commits).build();
ContainingBranchesGetter containingBranchesGetter =
new ContainingBranchesGetter(LinearGraphUtils.asLiteLinearGraph(graph), parseBranchNodeIndex(in.substring(i + SEPARATOR.length())));
Set<Integer> branches = parseBranchNodeIndex(in.substring(i + SEPARATOR.length()));
ReachableNodes reachableNodes =
new ReachableNodes(LinearGraphUtils.asLiteLinearGraph(graph));
assertEquals(out, containingBranchesGetterToStr(containingBranchesGetter, graph.nodesCount()));
assertEquals(out, containingBranchesGetterToStr(reachableNodes, branches, graph.nodesCount()));
}
protected abstract CommitIdManager<CommitId> getCommitIdManager();
@@ -147,7 +147,8 @@ public class ContainingBranchesGetter implements VcsLogListener {
if (branchRef == null) return Conditions.alwaysFalse();
ContainedInBranchCondition condition = myConditions.get(Pair.create(root, branchName));
if (condition == null) {
condition = new ContainedInBranchCondition(myGraph.getContainedInBranchCondition(myDataHolder.getCommitIndex(branchRef.getCommitHash())));
condition = new ContainedInBranchCondition(myGraph.getContainedInBranchCondition(
Collections.singleton(myDataHolder.getCommitIndex(branchRef.getCommitHash()))));
myConditions.put(Pair.create(root, branchName), condition);
}
return condition;
@@ -212,17 +213,17 @@ public class ContainingBranchesGetter implements VcsLogListener {
}
private class ContainedInBranchCondition implements Condition<Hash> {
@NotNull private final Condition<Integer> myChecker;
@NotNull private final Condition<Integer> myCondition;
private volatile boolean isDisposed = false;
public ContainedInBranchCondition(@NotNull Condition<Integer> checker) {
myChecker = checker;
public ContainedInBranchCondition(@NotNull Condition<Integer> condition) {
myCondition = condition;
}
@Override
public boolean value(Hash hash) {
if (isDisposed) return false;
return myChecker.value(myDataHolder.getCommitIndex(hash));
return myCondition.value(myDataHolder.getCommitIndex(hash));
}
public void dispose() {
@@ -23,6 +23,7 @@ import com.intellij.vcs.log.graph.VisibleGraph;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -63,7 +64,7 @@ public class EmptyPermanentGraph implements PermanentGraph<Integer> {
@NotNull
@Override
public Condition<Integer> getContainedInBranchCondition(@NotNull Integer currentBranchHead) {
public Condition<Integer> getContainedInBranchCondition(@NotNull Collection<Integer> currentBranchHead) {
return Conditions.alwaysFalse();
}