/* * 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.linearBek; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.graph.api.EdgeFilter; import com.intellij.vcs.log.graph.api.LinearGraph; import com.intellij.vcs.log.graph.api.elements.GraphEdge; import com.intellij.vcs.log.graph.api.elements.GraphEdgeType; import com.intellij.vcs.log.graph.api.elements.GraphNode; import com.intellij.vcs.log.graph.collapsing.EdgeStorageWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; public class LinearBekGraph implements LinearGraph { @NotNull protected final LinearGraph myGraph; @NotNull protected final EdgeStorageWrapper myHiddenEdges; @NotNull protected final EdgeStorageWrapper myDottedEdges; public LinearBekGraph(@NotNull LinearGraph graph) { myGraph = graph; myHiddenEdges = EdgeStorageWrapper.createSimpleEdgeStorage(); myDottedEdges = EdgeStorageWrapper.createSimpleEdgeStorage(); } @Override public int nodesCount() { return myGraph.nodesCount(); } @NotNull @Override public List<GraphEdge> getAdjacentEdges(int nodeIndex, @NotNull EdgeFilter filter) { List<GraphEdge> result = new ArrayList<>(); result.addAll(myDottedEdges.getAdjacentEdges(nodeIndex, filter)); result.addAll(myGraph.getAdjacentEdges(nodeIndex, filter)); result.removeAll(myHiddenEdges.getAdjacentEdges(nodeIndex, filter)); return result; } @NotNull @Override public GraphNode getGraphNode(int nodeIndex) { return myGraph.getGraphNode(nodeIndex); } @Override public int getNodeId(int nodeIndex) { return myGraph.getNodeId(nodeIndex); } @Nullable @Override public Integer getNodeIndex(int nodeId) { return myGraph.getNodeIndex(nodeId); } public Collection<GraphEdge> expandEdge(@NotNull final GraphEdge edge) { Set<GraphEdge> result = ContainerUtil.newHashSet(); assert edge.getType() == GraphEdgeType.DOTTED; myDottedEdges.removeEdge(edge); Integer tail = edge.getUpNodeIndex(); Integer firstChild = edge.getDownNodeIndex(); assert tail != null : "Collapsed from to an unloaded node"; assert firstChild != null : "Collapsed edge to an unloaded node"; List<GraphEdge> downDottedEdges = myHiddenEdges.getAdjacentEdges(tail, EdgeFilter.NORMAL_DOWN); List<GraphEdge> upDottedEdges = myHiddenEdges.getAdjacentEdges(firstChild, EdgeFilter.NORMAL_UP); for (GraphEdge e : ContainerUtil.concat(downDottedEdges, upDottedEdges)) { myHiddenEdges.removeEdge(e); if (e.getType() == GraphEdgeType.DOTTED) { result.addAll(expandEdge(e)); } else { result.add(e); } } return result; } public static class WorkingLinearBekGraph extends LinearBekGraph { private final LinearBekGraph myLinearGraph; public WorkingLinearBekGraph(@NotNull LinearBekGraph graph) { super(graph.myGraph); myLinearGraph = graph; } public Collection<GraphEdge> getAddedEdges() { Set<GraphEdge> result = myDottedEdges.getEdges(); result.removeAll(ContainerUtil.filter(myHiddenEdges.getEdges(), graphEdge -> graphEdge.getType() == GraphEdgeType.DOTTED)); result.removeAll(myLinearGraph.myDottedEdges.getEdges()); return result; } public Collection<GraphEdge> getRemovedEdges() { Set<GraphEdge> result = ContainerUtil.newHashSet(); Set<GraphEdge> hidden = myHiddenEdges.getEdges(); result.addAll(ContainerUtil.filter(hidden, graphEdge -> graphEdge.getType() != GraphEdgeType.DOTTED)); result.addAll(ContainerUtil.intersection(hidden, myLinearGraph.myDottedEdges.getEdges())); result.removeAll(myLinearGraph.myHiddenEdges.getEdges()); return result; } public void applyChanges() { myLinearGraph.myDottedEdges.removeAll(); myLinearGraph.myHiddenEdges.removeAll(); for (GraphEdge e : myDottedEdges.getEdges()) { myLinearGraph.myDottedEdges.createEdge(e); } for (GraphEdge e : myHiddenEdges.getEdges()) { myLinearGraph.myHiddenEdges.createEdge(e); } } } }