All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.vcs.log.graph.impl.facade.PermanentGraphImpl Maven / Gradle / Ivy

/*
 * 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.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.*;
import com.intellij.vcs.log.graph.api.permanent.PermanentGraphInfo;
import com.intellij.vcs.log.graph.collapsing.BranchFilterController;
import com.intellij.vcs.log.graph.collapsing.CollapsedController;
import com.intellij.vcs.log.graph.impl.facade.bek.BekIntMap;
import com.intellij.vcs.log.graph.impl.facade.bek.BekSorter;
import com.intellij.vcs.log.graph.impl.permanent.*;
import com.intellij.vcs.log.graph.linearBek.LinearBekController;
import com.intellij.vcs.log.graph.utils.LinearGraphUtils;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

public class PermanentGraphImpl implements PermanentGraph, PermanentGraphInfo {

  @NotNull
  public static  PermanentGraphImpl newInstance(@NotNull List> graphCommits,
                                                                    @NotNull final GraphColorManager graphColorManager,
                                                                    @NotNull Set branchesCommitId) {
    PermanentLinearGraphBuilder permanentLinearGraphBuilder = PermanentLinearGraphBuilder.newInstance(graphCommits);
    final Map notLoadCommits = ContainerUtil.newHashMap();
    PermanentLinearGraphImpl linearGraph = permanentLinearGraphBuilder.build(new NotNullFunction() {
      @NotNull
      @Override
      public Integer fun(CommitId dom) {
        int nodeId = -(notLoadCommits.size() + 2);
        notLoadCommits.put(nodeId, dom);
        return nodeId;
      }
    });

    final PermanentCommitsInfoIml commitIdPermanentCommitsInfo =
      PermanentCommitsInfoIml.newInstance(graphCommits, notLoadCommits);

    GraphLayoutImpl permanentGraphLayout = GraphLayoutBuilder.build(linearGraph, new Comparator() {
      @Override
      public int compare(@NotNull Integer nodeIndex1, @NotNull Integer nodeIndex2) {
        CommitId commitId1 = commitIdPermanentCommitsInfo.getCommitId(nodeIndex1);
        CommitId commitId2 = commitIdPermanentCommitsInfo.getCommitId(nodeIndex2);
        return graphColorManager.compareHeads(commitId2, commitId1);
      }
    });

    return new PermanentGraphImpl(linearGraph, permanentGraphLayout, commitIdPermanentCommitsInfo, graphColorManager,
                                            branchesCommitId);
  }

  @NotNull private final PermanentCommitsInfoIml myPermanentCommitsInfo;
  @NotNull private final PermanentLinearGraphImpl myPermanentLinearGraph;
  @NotNull private final GraphLayoutImpl myPermanentGraphLayout;
  @NotNull private final GraphColorManager myGraphColorManager;
  @NotNull private final Set myBranchesCommitId;
  @NotNull private final Set myBranchNodeIds;
  @NotNull private final ReachableNodes myReachableNodes;
  @NotNull private final BekIntMap myBekIntMap;

  public PermanentGraphImpl(@NotNull PermanentLinearGraphImpl permanentLinearGraph,
                            @NotNull GraphLayoutImpl permanentGraphLayout,
                            @NotNull PermanentCommitsInfoIml permanentCommitsInfo,
                            @NotNull GraphColorManager graphColorManager,
                            @NotNull Set branchesCommitId) {
    myPermanentGraphLayout = permanentGraphLayout;
    myPermanentCommitsInfo = permanentCommitsInfo;
    myPermanentLinearGraph = permanentLinearGraph;
    myGraphColorManager = graphColorManager;
    myBranchesCommitId = branchesCommitId;
    myBranchNodeIds = permanentCommitsInfo.convertToNodeIds(branchesCommitId);
    myReachableNodes = new ReachableNodes(LinearGraphUtils.asLiteLinearGraph(permanentLinearGraph));
    myBekIntMap = BekSorter.createBekMap(myPermanentLinearGraph, myPermanentGraphLayout, myPermanentCommitsInfo.getTimestampGetter());
  }

  @NotNull
  @Override
  public VisibleGraph createVisibleGraph(@NotNull SortType sortType,
                                                   @Nullable Set visibleHeads,
                                                   @Nullable Set matchingCommits) {
    CascadeController baseController;
    if (sortType == SortType.Normal) {
      baseController = new BaseController(this);
    }
    else if (sortType == SortType.LinearBek) {
      baseController = new LinearBekController(new BekBaseController(this, myBekIntMap), this);
    }
    else {
      baseController = new BekBaseController(this, myBekIntMap);
    }

    LinearGraphController controller;
    if (matchingCommits != null) {
      controller = new FilteredController(baseController, this, myPermanentCommitsInfo.convertToNodeIds(matchingCommits));
    }
    else if (sortType == SortType.LinearBek) {
      if (visibleHeads != null) {
        controller = new BranchFilterController(baseController, this, myPermanentCommitsInfo.convertToNodeIds(visibleHeads));
      }
      else {
        controller = baseController;
      }
    }
    else {
      Set idOfVisibleBranches = null;
      if (visibleHeads != null) {
        idOfVisibleBranches = myPermanentCommitsInfo.convertToNodeIds(visibleHeads);
      }
      controller = new CollapsedController(baseController, this, idOfVisibleBranches);
    }

    return new VisibleGraphImpl(controller, this);
  }

  @NotNull
  @Override
  public List> getAllCommits() {
    List> result = ContainerUtil.newArrayList();
    for (int index = 0; index < myPermanentLinearGraph.nodesCount(); index++) {
      CommitId commitId = myPermanentCommitsInfo.getCommitId(index);
      List downNodes = LinearGraphUtils.getDownNodesIncludeNotLoad(myPermanentLinearGraph, index);
      List parentsCommitIds = myPermanentCommitsInfo.convertToCommitIdList(downNodes);
      GraphCommit graphCommit =
        new GraphCommitImpl(commitId, parentsCommitIds, myPermanentCommitsInfo.getTimestamp(index));
      result.add(graphCommit);
    }

    return result;
  }

  @NotNull
  @Override
  public List getChildren(@NotNull CommitId commit) {
    int commitIndex = myPermanentCommitsInfo.getNodeId(commit);
    return myPermanentCommitsInfo.convertToCommitIdList(LinearGraphUtils.getUpNodes(myPermanentLinearGraph, commitIndex));
  }

  @NotNull
  @Override
  public Set getContainingBranches(@NotNull CommitId commit) {
    int commitIndex = myPermanentCommitsInfo.getNodeId(commit);
    return myPermanentCommitsInfo.convertToCommitIdSet(myReachableNodes.getContainingBranches(commitIndex, myBranchNodeIds));
  }

  @NotNull
  @Override
  public Condition getContainedInBranchCondition(@NotNull final Collection heads) {
    List headIds = ContainerUtil.map(heads, new Function() {
      @Override
      public Integer fun(CommitId head) {
        return myPermanentCommitsInfo.getNodeId(head);
      }
    });
    if (!heads.isEmpty() && ContainerUtil.getFirstItem(heads) instanceof Integer) {
      final TIntHashSet branchNodes = new TIntHashSet();
      myReachableNodes.walk(headIds, new Consumer() {
        @Override
        public void consume(Integer node) {
          branchNodes.add((Integer)myPermanentCommitsInfo.getCommitId(node));
        }
      });
      return new Condition() {
        @Override
        public boolean value(CommitId commitId) {
          return branchNodes.contains((Integer)commitId);
        }
      };
    }
    else {
      final Set branchNodes = ContainerUtil.newHashSet();
      myReachableNodes.walk(headIds, new Consumer() {
        @Override
        public void consume(Integer node) {
          branchNodes.add(myPermanentCommitsInfo.getCommitId(node));
        }
      });
      return new Condition() {
        @Override
        public boolean value(CommitId commitId) {
          return branchNodes.contains(commitId);
        }
      };
    }
  }

  @NotNull
  public PermanentCommitsInfoIml getPermanentCommitsInfo() {
    return myPermanentCommitsInfo;
  }

  @NotNull
  public PermanentLinearGraphImpl getPermanentLinearGraph() {
    return myPermanentLinearGraph;
  }

  @NotNull
  public GraphLayoutImpl getPermanentGraphLayout() {
    return myPermanentGraphLayout;
  }

  @NotNull
  public GraphColorManager getGraphColorManager() {
    return myGraphColorManager;
  }

  @NotNull
  public Set getBranchesCommitId() {
    return myBranchesCommitId;
  }

  @NotNull
  public Set getBranchNodeIds() {
    return myBranchNodeIds;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy