[vcs-log] do not create Change instances for indexing paths when details have lazy changes

This commit is contained in:
Julia Beliaeva
2016-09-20 00:15:17 +03:00
parent 9d94c5a075
commit fe096a06ba
3 changed files with 91 additions and 9 deletions
@@ -27,6 +27,7 @@ import com.intellij.util.indexing.DataIndexer;
import com.intellij.util.indexing.StorageException;
import com.intellij.util.io.*;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.impl.VcsChangesLazilyParsedDetails;
import com.intellij.vcs.log.util.PersistentUtil;
import gnu.trove.THashMap;
import gnu.trove.TIntHashSet;
@@ -147,13 +148,21 @@ public class VcsLogPathsIndex extends VcsLogFullDetailsIndex<Integer> {
Map<Integer, Integer> result = new THashMap<>();
Collection<Couple<String>> moves = ContainerUtil.newHashSet();
Collection<String> changedPaths = ContainerUtil.newHashSet();
for (Change change : inputData.getChanges()) {
if (change.getAfterRevision() != null) changedPaths.add(change.getAfterRevision().getFile().getPath());
if (change.getBeforeRevision() != null) changedPaths.add(change.getBeforeRevision().getFile().getPath());
if (change.getType().equals(Change.Type.MOVED)) {
moves.add(Couple.of(change.getBeforeRevision().getFile().getPath(), change.getAfterRevision().getFile().getPath()));
Collection<Couple<String>> moves;
Collection<String> changedPaths;
if (inputData instanceof VcsChangesLazilyParsedDetails) {
changedPaths = ((VcsChangesLazilyParsedDetails)inputData).getModifiedPaths();
moves = ((VcsChangesLazilyParsedDetails)inputData).getRenamedPaths();
}
else {
moves = ContainerUtil.newHashSet();
changedPaths = ContainerUtil.newHashSet();
for (Change change : inputData.getChanges()) {
if (change.getAfterRevision() != null) changedPaths.add(change.getAfterRevision().getFile().getPath());
if (change.getBeforeRevision() != null) changedPaths.add(change.getBeforeRevision().getFile().getPath());
if (change.getType().equals(Change.Type.MOVED)) {
moves.add(Couple.of(change.getBeforeRevision().getFile().getPath(), change.getAfterRevision().getFile().getPath()));
}
}
}
@@ -16,10 +16,12 @@
package com.intellij.vcs.log.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.vcs.LocalFilePath;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.Hash;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.VcsUser;
@@ -28,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Allows to postpone changes parsing, which might take long for a large amount of commits,
@@ -37,7 +40,7 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme
private static final Logger LOG = Logger.getInstance(VcsChangesLazilyParsedDetails.class);
@NotNull private final ThrowableComputable<Collection<Change>, ? extends Exception> myChangesGetter;
@NotNull protected final ThrowableComputable<Collection<Change>, ? extends Exception> myChangesGetter;
public VcsChangesLazilyParsedDetails(@NotNull Hash hash, @NotNull List<Hash> parents, long commitTime, @NotNull VirtualFile root,
@NotNull String subject, @NotNull VcsUser author, @NotNull String message,
@@ -58,4 +61,27 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme
return Collections.emptyList();
}
}
@NotNull
public Collection<String> getModifiedPaths() {
Set<String> changedPaths = ContainerUtil.newHashSet();
for (Change change : getChanges()) {
if (change.getAfterRevision() != null) changedPaths.add(change.getAfterRevision().getFile().getPath());
if (change.getBeforeRevision() != null) changedPaths.add(change.getBeforeRevision().getFile().getPath());
}
return changedPaths;
}
@NotNull
public Collection<Couple<String>> getRenamedPaths() {
Set<Couple<String>> renames = ContainerUtil.newHashSet();
for (Change change : getChanges()) {
if (change.getType().equals(Change.Type.MOVED)) {
if (change.getAfterRevision() != null && change.getBeforeRevision() != null) {
renames.add(Couple.of(change.getBeforeRevision().getFile().getPath(), change.getAfterRevision().getFile().getPath()));
}
}
}
return renames;
}
}
+48 -1
View File
@@ -16,6 +16,7 @@
package git4idea;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
@@ -32,6 +33,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* Represents a Git commit with its meta information (hash, author, message, etc.), its parents and the {@link Change changes}.
@@ -45,7 +47,50 @@ public final class GitCommit extends VcsChangesLazilyParsedDetails {
long authorTime, @NotNull List<GitLogStatusInfo> reportedChanges) {
super(hash, parents, commitTime, root, subject, author, message, committer, authorTime,
new MyChangesComputable(new Data(project, root, reportedChanges, hash, commitTime, parents)));
}
@NotNull
@Override
public Collection<String> getModifiedPaths() {
Data data = ((MyChangesComputable)myChangesGetter).getData();
if (data != null) {
Set<String> changes = ContainerUtil.newHashSet();
for (GitLogStatusInfo status : data.changesOutput) {
changes.add(absolutePath(status.getFirstPath()));
String secondPath = status.getSecondPath();
if (secondPath != null) {
changes.add(absolutePath(secondPath));
}
}
return changes;
}
return super.getModifiedPaths();
}
@NotNull
@Override
public Collection<Couple<String>> getRenamedPaths() {
Data data = ((MyChangesComputable)myChangesGetter).getData();
if (data != null) {
Set<Couple<String>> changes = ContainerUtil.newHashSet();
for (GitLogStatusInfo status : data.changesOutput) {
if (status.getSecondPath() != null) {
changes.add(Couple.of(absolutePath(status.getFirstPath()), absolutePath(status.getSecondPath())));
}
}
return changes;
}
return super.getRenamedPaths();
}
@NotNull
private String absolutePath(@NotNull String path) {
try {
return getRoot().getPath() + "/" + GitUtil.unescapePath(path);
}
catch (VcsException e) {
return getRoot().getPath() + "/" + path;
}
}
private static class MyChangesComputable implements ThrowableComputable<Collection<Change>, VcsException> {
@@ -72,6 +117,9 @@ public final class GitCommit extends VcsChangesLazilyParsedDetails {
return myChanges;
}
public Data getData() {
return myData;
}
}
private static class Data {
@@ -91,5 +139,4 @@ public final class GitCommit extends VcsChangesLazilyParsedDetails {
this.parents = parents;
}
}
}