mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs-log] check for progress indicator being cancelled while processing arguments by chunks
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.openapi.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface ThrowableNotNullFunction<T, R, E extends Throwable> {
|
||||
@NotNull
|
||||
R fun(@NotNull T t) throws E;
|
||||
}
|
||||
@@ -15,13 +15,17 @@
|
||||
*/
|
||||
package com.intellij.vcsUtil;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.ThrowableNotNullFunction;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -41,25 +45,54 @@ public class VcsFileUtil {
|
||||
public static final int FILE_PATH_LIMIT = 7600;
|
||||
|
||||
/**
|
||||
* Chunk paths on the command line
|
||||
* Execute function for each chunk of arguments. Check for being cancelled in process.
|
||||
*
|
||||
* @param files the paths to chunk
|
||||
* @return the a list of list of relative paths
|
||||
* @param arguments the arguments to chunk
|
||||
* @param processor function to execute on each chunk
|
||||
* @param <T> type of result value
|
||||
* @return list of result values
|
||||
* @throws VcsException
|
||||
*/
|
||||
public static List<List<String>> chunkRelativePaths(List<String> files) {
|
||||
@NotNull
|
||||
public static <T> List<T> foreachChunk(@NotNull List<String> arguments,
|
||||
@NotNull ThrowableNotNullFunction<List<String>, List<? extends T>, VcsException> processor)
|
||||
throws VcsException {
|
||||
List<T> result = ContainerUtil.newArrayList();
|
||||
List<List<String>> chunks = chunkArguments(arguments);
|
||||
|
||||
for (List<String> chunk : chunks) {
|
||||
if (ProgressManager.getInstance().getProgressIndicator() != null &&
|
||||
ProgressManager.getInstance().getProgressIndicator().isCanceled()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.addAll(processor.fun(chunk));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunk arguments on the command line
|
||||
*
|
||||
* @param arguments the arguments to chunk
|
||||
* @return a list of lists of arguments
|
||||
*/
|
||||
@NotNull
|
||||
public static List<List<String>> chunkArguments(@NotNull List<String> arguments) {
|
||||
ArrayList<List<String>> rc = new ArrayList<List<String>>();
|
||||
int start = 0;
|
||||
int size = 0;
|
||||
int i = 0;
|
||||
for (; i < files.size(); i++) {
|
||||
String p = files.get(i);
|
||||
for (; i < arguments.size(); i++) {
|
||||
String p = arguments.get(i);
|
||||
if (size + p.length() > FILE_PATH_LIMIT) {
|
||||
if (start == i) {
|
||||
rc.add(files.subList(i, i + 1));
|
||||
rc.add(arguments.subList(i, i + 1));
|
||||
start = i + 1;
|
||||
}
|
||||
else {
|
||||
rc.add(files.subList(start, i));
|
||||
rc.add(arguments.subList(start, i));
|
||||
start = i;
|
||||
}
|
||||
size = 0;
|
||||
@@ -68,8 +101,8 @@ public class VcsFileUtil {
|
||||
size += p.length();
|
||||
}
|
||||
}
|
||||
if (start != files.size()) {
|
||||
rc.add(files.subList(start, i));
|
||||
if (start != arguments.size()) {
|
||||
rc.add(arguments.subList(start, i));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -82,7 +115,7 @@ public class VcsFileUtil {
|
||||
* @return chunked relative paths
|
||||
*/
|
||||
public static List<List<String>> chunkPaths(VirtualFile root, Collection<FilePath> files) {
|
||||
return chunkRelativePaths(toRelativePaths(root, files));
|
||||
return chunkArguments(toRelativePaths(root, files));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +126,7 @@ public class VcsFileUtil {
|
||||
* @return chunked relative paths
|
||||
*/
|
||||
public static List<List<String>> chunkFiles(@NotNull VirtualFile root, @NotNull Collection<VirtualFile> files) {
|
||||
return chunkRelativePaths(toRelativeFiles(root, files));
|
||||
return chunkArguments(toRelativeFiles(root, files));
|
||||
}
|
||||
|
||||
public static String getRelativeFilePath(VirtualFile file, @NotNull final VirtualFile baseDir) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package git4idea.log;
|
||||
import com.intellij.openapi.diagnostic.Attachment;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ThrowableNotNullFunction;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.VcsKey;
|
||||
@@ -333,34 +334,35 @@ public class GitLogProvider implements VcsLogProvider {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends VcsShortCommitDetails> readShortDetails(@NotNull VirtualFile root, @NotNull List<String> hashes)
|
||||
public List<? extends VcsShortCommitDetails> readShortDetails(@NotNull final VirtualFile root, @NotNull List<String> hashes)
|
||||
throws VcsException {
|
||||
List<VcsShortCommitDetails> result = ContainerUtil.newArrayList();
|
||||
List<List<String>> hashesChunks = VcsFileUtil.chunkRelativePaths(hashes);
|
||||
|
||||
for (List<String> hashesChunk : hashesChunks) {
|
||||
result.addAll(GitHistoryUtils.readMiniDetails(myProject, root, hashesChunk));
|
||||
}
|
||||
|
||||
return result;
|
||||
return VcsFileUtil
|
||||
.foreachChunk(hashes, new ThrowableNotNullFunction<List<String>, List<? extends VcsShortCommitDetails>, VcsException>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends VcsShortCommitDetails> fun(@NotNull List<String> hashes) throws VcsException {
|
||||
return GitHistoryUtils.readMiniDetails(myProject, root, hashes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends VcsFullCommitDetails> readFullDetails(@NotNull VirtualFile root, @NotNull List<String> hashes) throws VcsException {
|
||||
List<VcsFullCommitDetails> result = ContainerUtil.newArrayList();
|
||||
List<List<String>> hashesChunks = VcsFileUtil.chunkRelativePaths(hashes);
|
||||
public List<? extends VcsFullCommitDetails> readFullDetails(@NotNull final VirtualFile root, @NotNull List<String> hashes)
|
||||
throws VcsException {
|
||||
return VcsFileUtil
|
||||
.foreachChunk(hashes, new ThrowableNotNullFunction<List<String>, List<? extends VcsFullCommitDetails>, VcsException>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends VcsFullCommitDetails> fun(@NotNull List<String> hashes) throws VcsException {
|
||||
String noWalk = GitVersionSpecialty.NO_WALK_UNSORTED.existsIn(myVcs.getVersion()) ? "--no-walk=unsorted" : "--no-walk";
|
||||
List<String> params = new ArrayList<String>();
|
||||
params.add(noWalk);
|
||||
params.addAll(hashes);
|
||||
|
||||
for (List<String> hashesChunk : hashesChunks) {
|
||||
String noWalk = GitVersionSpecialty.NO_WALK_UNSORTED.existsIn(myVcs.getVersion()) ? "--no-walk=unsorted" : "--no-walk";
|
||||
List<String> params = new ArrayList<String>();
|
||||
params.add(noWalk);
|
||||
params.addAll(hashesChunk);
|
||||
|
||||
result.addAll(GitHistoryUtils.history(myProject, root, ArrayUtil.toStringArray(params)));
|
||||
}
|
||||
|
||||
return result;
|
||||
return GitHistoryUtils.history(myProject, root, ArrayUtil.toStringArray(params));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -90,7 +90,7 @@ public abstract class HgCommitTypeCommand {
|
||||
return file.getRelativePath();
|
||||
}
|
||||
});
|
||||
List<List<String>> chunkedCommits = VcsFileUtil.chunkRelativePaths(relativePaths);
|
||||
List<List<String>> chunkedCommits = VcsFileUtil.chunkArguments(relativePaths);
|
||||
executeChunked(chunkedCommits);
|
||||
}
|
||||
myRepository.update();
|
||||
|
||||
@@ -48,7 +48,7 @@ public class HgRemoveCommand {
|
||||
public void execute(@NotNull Collection<HgFile> hgFiles) {
|
||||
for( Map.Entry<VirtualFile, List<String>> entry : HgUtil.getRelativePathsByRepository(hgFiles).entrySet()) {
|
||||
List<String> filePaths = entry.getValue();
|
||||
for (List<String> chunkFiles : VcsFileUtil.chunkRelativePaths(filePaths)) {
|
||||
for (List<String> chunkFiles : VcsFileUtil.chunkArguments(filePaths)) {
|
||||
List<String> parameters = new LinkedList<String>();
|
||||
parameters.addAll(chunkFiles);
|
||||
parameters.add(0, "--after");
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.ThrowableNotNullFunction;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
@@ -112,24 +113,23 @@ public class HgHistoryUtil {
|
||||
*/
|
||||
@NotNull
|
||||
public static List<? extends VcsFullCommitDetails> history(@NotNull final Project project,
|
||||
@NotNull final VirtualFile root,
|
||||
int limit,
|
||||
@NotNull List<String> hashParameters,
|
||||
boolean silent) throws VcsException {
|
||||
@NotNull final VirtualFile root, final int limit,
|
||||
@NotNull List<String> hashParameters, final boolean silent)
|
||||
throws VcsException {
|
||||
HgVcs hgvcs = HgVcs.getInstance(project);
|
||||
assert hgvcs != null;
|
||||
final HgVersion version = hgvcs.getVersion();
|
||||
String[] templates = HgBaseLogParser.constructFullTemplateArgument(true, version);
|
||||
final String[] templates = HgBaseLogParser.constructFullTemplateArgument(true, version);
|
||||
|
||||
List<VcsFullCommitDetails> result = ContainerUtil.newArrayList();
|
||||
List<List<String>> hashesChunks = VcsFileUtil.chunkRelativePaths(hashParameters);
|
||||
|
||||
for (List<String> hashesChunk : hashesChunks) {
|
||||
HgCommandResult logResult = getLogResult(project, root, version, limit, hashesChunk, HgChangesetUtil.makeTemplate(templates));
|
||||
result.addAll(createFullCommitsFromResult(project, root, logResult, version, silent));
|
||||
}
|
||||
|
||||
return result;
|
||||
return VcsFileUtil
|
||||
.foreachChunk(hashParameters, new ThrowableNotNullFunction<List<String>, List<? extends VcsFullCommitDetails>, VcsException>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends VcsFullCommitDetails> fun(@NotNull List<String> strings) throws VcsException {
|
||||
HgCommandResult logResult = getLogResult(project, root, version, limit, strings, HgChangesetUtil.makeTemplate(templates));
|
||||
return createFullCommitsFromResult(project, root, logResult, version, silent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static List<? extends VcsFullCommitDetails> createFullCommitsFromResult(@NotNull Project project,
|
||||
@@ -244,7 +244,7 @@ public class HgHistoryUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<? extends VcsShortCommitDetails> readMiniDetails(@NotNull Project project,
|
||||
public static List<? extends VcsShortCommitDetails> readMiniDetails(@NotNull final Project project,
|
||||
@NotNull final VirtualFile root,
|
||||
@NotNull List<String> hashes)
|
||||
throws VcsException {
|
||||
@@ -255,41 +255,41 @@ public class HgHistoryUtil {
|
||||
|
||||
HgVcs hgvcs = HgVcs.getInstance(project);
|
||||
assert hgvcs != null;
|
||||
HgVersion version = hgvcs.getVersion();
|
||||
final HgVersion version = hgvcs.getVersion();
|
||||
List<String> templateList = HgBaseLogParser.constructDefaultTemplate(version);
|
||||
templateList.add("{desc}");
|
||||
String[] templates = ArrayUtil.toStringArray(templateList);
|
||||
final String[] templates = ArrayUtil.toStringArray(templateList);
|
||||
|
||||
List<VcsShortCommitDetails> result = ContainerUtil.newArrayList();
|
||||
List<List<String>> hashesChunks = VcsFileUtil.chunkRelativePaths(hashes);
|
||||
return VcsFileUtil.foreachChunk(prepareHashes(hashes),
|
||||
new ThrowableNotNullFunction<List<String>, List<? extends VcsShortCommitDetails>, VcsException>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends VcsShortCommitDetails> fun(@NotNull List<String> strings) throws VcsException {
|
||||
HgCommandResult logResult =
|
||||
getLogResult(project, root, version, -1, strings, HgChangesetUtil.makeTemplate(templates));
|
||||
|
||||
for (List<String> hashesChunk : hashesChunks) {
|
||||
HgCommandResult logResult =
|
||||
getLogResult(project, root, version, -1, prepareHashes(hashesChunk), HgChangesetUtil.makeTemplate(templates));
|
||||
|
||||
result.addAll(getCommitRecords(project, logResult, new HgBaseLogParser<VcsShortCommitDetails>() {
|
||||
@Override
|
||||
protected VcsShortCommitDetails convertDetails(@NotNull String rev,
|
||||
@NotNull String changeset,
|
||||
@NotNull SmartList<HgRevisionNumber> parents,
|
||||
@NotNull Date revisionDate,
|
||||
@NotNull String author,
|
||||
@NotNull String email,
|
||||
@NotNull List<String> attributes) {
|
||||
String message = parseAdditionalStringAttribute(attributes, MESSAGE_INDEX);
|
||||
String subject = extractSubject(message);
|
||||
List<Hash> parentsHash = new SmartList<Hash>();
|
||||
for (HgRevisionNumber parent : parents) {
|
||||
parentsHash.add(factory.createHash(parent.getChangeset()));
|
||||
}
|
||||
return factory
|
||||
.createShortDetails(factory.createHash(changeset), parentsHash, revisionDate.getTime(), root, subject, author, email, author,
|
||||
email, revisionDate.getTime());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
return result;
|
||||
return getCommitRecords(project, logResult, new HgBaseLogParser<VcsShortCommitDetails>() {
|
||||
@Override
|
||||
protected VcsShortCommitDetails convertDetails(@NotNull String rev,
|
||||
@NotNull String changeset,
|
||||
@NotNull SmartList<HgRevisionNumber> parents,
|
||||
@NotNull Date revisionDate,
|
||||
@NotNull String author,
|
||||
@NotNull String email,
|
||||
@NotNull List<String> attributes) {
|
||||
String message = parseAdditionalStringAttribute(attributes, MESSAGE_INDEX);
|
||||
String subject = extractSubject(message);
|
||||
List<Hash> parentsHash = new SmartList<Hash>();
|
||||
for (HgRevisionNumber parent : parents) {
|
||||
parentsHash.add(factory.createHash(parent.getChangeset()));
|
||||
}
|
||||
return factory
|
||||
.createShortDetails(factory.createHash(changeset), parentsHash, revisionDate.getTime(), root,
|
||||
subject, author, email, author, email, revisionDate.getTime());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user