[vcs-log] pass PermanentGraph.Options to the VcsLogProvider to speed up filtering

GitOrigin-RevId: e3806bad92b53af1be0e77e0868099af0f11c978
This commit is contained in:
Julia Beliaeva
2024-03-26 02:32:03 +01:00
committed by intellij-monorepo-bot
parent bbaf4f9f4d
commit f3cf33a514
10 changed files with 62 additions and 30 deletions

View File

@@ -10,6 +10,7 @@ import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.messages.MessageBus;
import com.intellij.vcs.log.graph.PermanentGraph;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -87,13 +88,28 @@ public interface VcsLogProvider {
Disposable subscribeToRootRefreshEvents(@NotNull Collection<? extends VirtualFile> roots, @NotNull VcsLogRefresher refresher);
/**
* <p>Return commits, which correspond to the given filters.</p>
*
* @param maxCount maximum number of commits to request from the VCS, or -1 for unlimited.
* @deprecated implement {@link VcsLogProvider#getCommitsMatchingFilter(VirtualFile, VcsLogFilterCollection, PermanentGraph.Options, int)} instead
*/
@NotNull
List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection, int maxCount)
throws VcsException;
default List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection,
int maxCount)
throws VcsException {
return getCommitsMatchingFilter(root, filterCollection, PermanentGraph.Options.Default, maxCount);
}
/**
* Return commits, which correspond to the given filters.
*
* @param root repository root
* @param filterCollection filters to use
* @param graphOptions additional options, such as "--first-parent", see {@link PermanentGraph.Options}
* @param maxCount maximum number of commits to request from the VCS, or -1 for unlimited.
*/
@NotNull
default List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection,
@NotNull PermanentGraph.Options graphOptions, int maxCount) throws VcsException {
throw new UnsupportedOperationException("Method getCommitsMatchingFilter is not implemented the class " + this.getClass().getName());
}
/**
* Returns the name of current user as specified for the given root,
@@ -115,7 +131,8 @@ public interface VcsLogProvider {
* @param <T> Type of property value.
* @return Property value or null if unset.
*/
@Nullable <T> T getPropertyValue(VcsLogProperties.VcsLogProperty<T> property);
@Nullable
<T> T getPropertyValue(VcsLogProperties.VcsLogProperty<T> property);
/**
* Returns currently checked out branch in given root, or null if not on any branch or provided root is not under version control.

View File

@@ -41,11 +41,12 @@ private fun VcsLogFiltererImpl.filter(dataPack: DataPack,
val visibleRoots = VcsLogUtil.getAllVisibleRoots(dataPack.logProviders.keys, filters)
if (!dataPack.isFull || visibleRoots.none { index.isIndexed(it) }) {
return filterWithVcs(filters, commitCount.count)
return filterWithVcs(filters, PermanentGraph.Options.Default, commitCount.count)
}
if (filters.filters.all { it is VcsLogDetailsFilter || it is VcsLogRootFilter } && structureFilter == null) {
val filterByDetailsResult = filterByDetails(dataPack, filters, commitCount, visibleRoots, null, null, false)
val filterByDetailsResult = filterByDetails(dataPack, filters, commitCount, visibleRoots, null, null,
PermanentGraph.Options.Default, false)
val matchingCommits = filterByDetailsResult.matchingCommits
if (matchingCommits != null) return matchingCommits

View File

@@ -113,7 +113,7 @@ class VcsLogFiltererImpl(private val logProviders: Map<VirtualFile, VcsLogProvid
}
try {
val filterResult = filterByDetails(dataPack, filters, commitCount, visibleRoots, matchingHeads, commitCandidates, forceFilterByVcs)
val filterResult = filterByDetails(dataPack, filters, commitCount, visibleRoots, matchingHeads, commitCandidates, graphOptions, forceFilterByVcs)
val visibleGraph = createVisibleGraph(dataPack, graphOptions, matchingHeads, filterResult.matchingCommits, filterResult.fileHistoryData)
val visiblePack = VisiblePack(dataPack, visibleGraph, filterResult.canRequestMore, filters)
@@ -179,6 +179,7 @@ class VcsLogFiltererImpl(private val logProviders: Map<VirtualFile, VcsLogProvid
visibleRoots: Collection<VirtualFile>,
matchingHeads: Set<Int>?,
commitCandidates: IntSet?,
graphOptions: PermanentGraph.Options,
forceFilterByVcs: Boolean): FilterByDetailsResult {
val detailsFilters = filters.detailsFilters
if (!forceFilterByVcs && detailsFilters.isEmpty()) {
@@ -202,7 +203,7 @@ class VcsLogFiltererImpl(private val logProviders: Map<VirtualFile, VcsLogProvid
val filterAllWithVcs = rootsForVcs.containsAll(visibleRoots)
val filtersForVcs = if (filterAllWithVcs) filters else filters.with(VcsLogFilterObject.fromRoots(rootsForVcs))
val headsForVcs = if (filterAllWithVcs) matchingHeads else getMatchingHeads(dataPack.refsModel, rootsForVcs, filtersForVcs)
val filteredWithVcs = filterWithVcs(dataPack.permanentGraph, filtersForVcs, headsForVcs, commitCount, commitCandidates)
val filteredWithVcs = filterWithVcs(dataPack.permanentGraph, filtersForVcs, headsForVcs, graphOptions, commitCount, commitCandidates)
val filteredCommits = union(filteredWithIndex, filteredWithVcs.matchingCommits)
return FilterByDetailsResult(filteredCommits, filteredWithVcs.canRequestMore, filteredWithVcs.commitCount,
@@ -230,6 +231,7 @@ class VcsLogFiltererImpl(private val logProviders: Map<VirtualFile, VcsLogProvid
private fun filterWithVcs(graph: PermanentGraph<Int>,
filters: VcsLogFilterCollection,
matchingHeads: Set<Int>?,
graphOptions: PermanentGraph.Options,
commitCount: CommitCountStage,
commitCandidates: IntSet?): FilterByDetailsResult {
var commitCountToTry = commitCount
@@ -243,12 +245,12 @@ class VcsLogFiltererImpl(private val logProviders: Map<VirtualFile, VcsLogProvid
commitCountToTry = commitCountToTry.next()
}
val commitsFromVcs = filterWithVcs(filters, commitCountToTry.count)
val commitsFromVcs = filterWithVcs(filters, graphOptions, commitCountToTry.count)
return FilterByDetailsResult(commitsFromVcs, commitsFromVcs.size >= commitCountToTry.count, commitCountToTry, FilterKind.Vcs)
}
@Throws(VcsException::class)
internal fun filterWithVcs(filterCollection: VcsLogFilterCollection, maxCount: Int): IntSet {
internal fun filterWithVcs(filterCollection: VcsLogFilterCollection, graphOptions: PermanentGraph.Options, maxCount: Int): IntSet {
val commits = IntOpenHashSet()
val visibleRoots = VcsLogUtil.getAllVisibleRoots(logProviders.keys, filterCollection)
@@ -290,7 +292,7 @@ class VcsLogFiltererImpl(private val logProviders: Map<VirtualFile, VcsLogProvid
.with(VcsLogFilterObject.fromRange(resolvedRanges))
}
provider.getCommitsMatchingFilter(root, actualFilterCollection, maxCount).forEach { commit ->
provider.getCommitsMatchingFilter(root, actualFilterCollection, graphOptions, maxCount).forEach { commit ->
commits.add(storage.getCommitIndex(commit.id, root))
}
}
@@ -329,7 +331,7 @@ class VcsLogFiltererImpl(private val logProviders: Map<VirtualFile, VcsLogProvid
val textFilter = hashFilter.toTextFilter()
val textFilterResult = filterByDetails(dataPack, VcsLogFilterObject.collection(textFilter),
commitCount, dataPack.logProviders.keys, null, null, false)
commitCount, dataPack.logProviders.keys, null, null, graphOptions, false)
if (hashFilterResult.isEmpty() && textFilterResult.matchingCommits.matchesNothing()) return null
val filterResult = union(textFilterResult.matchingCommits, hashFilterResult)

View File

@@ -8,6 +8,7 @@ import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.impl.HashImpl;
import com.intellij.vcs.log.util.UserNameRegex;
import com.intellij.vcs.log.visible.filters.VcsLogFilterObject;
@@ -236,7 +237,8 @@ public abstract class VcsLogUserFilterTest {
private @NotNull List<String> getFilteredHashes(@NotNull VcsLogUserFilter filter) throws VcsException {
VcsLogFilterCollection filters = VcsLogFilterObject.collection(filter);
List<TimedVcsCommit> commits = myLogProvider.getCommitsMatchingFilter(PlatformTestUtil.getOrCreateProjectBaseDir(myProject), filters, -1);
List<TimedVcsCommit> commits = myLogProvider.getCommitsMatchingFilter(PlatformTestUtil.getOrCreateProjectBaseDir(myProject), filters,
PermanentGraph.Options.Default, -1);
return ContainerUtil.map(commits, commit -> commit.getId().asString());
}

View File

@@ -11,6 +11,7 @@ import com.intellij.ui.JBColor;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.graph.PermanentGraph;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -126,7 +127,8 @@ public class TestVcsLogProvider implements VcsLogProvider {
@Override
public @NotNull List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root,
@NotNull VcsLogFilterCollection filterCollection,
int maxCount) throws VcsException {
@NotNull PermanentGraph.Options graphOptions,
int maxCount) {
throw new UnsupportedOperationException();
}

View File

@@ -93,8 +93,7 @@ class VcsLogFiltererTest {
}
val provider = object : TestVcsLogProvider() {
override fun getCommitsMatchingFilter(root: VirtualFile,
filterCollection: VcsLogFilterCollection,
override fun getCommitsMatchingFilter(root: VirtualFile, filterCollection: VcsLogFilterCollection, graphOptions: PermanentGraph.Options,
maxCount: Int): List<TimedVcsCommit> {
return listOf(2, 3, 4).map { commitId ->
graph.allCommits.first { it.id == commitId }.toVcsCommit(graph.hashMap)
@@ -158,8 +157,7 @@ class VcsLogFiltererTest {
VcsLogFilterObject.fromPaths(listOf(filePath)))
val provider = object : TestVcsLogProvider() {
override fun getCommitsMatchingFilter(root: VirtualFile,
filterCollection: VcsLogFilterCollection,
override fun getCommitsMatchingFilter(root: VirtualFile, filterCollection: VcsLogFilterCollection, graphOptions: PermanentGraph.Options,
maxCount: Int): List<TimedVcsCommit> {
return listOf(graph.allCommits.first { it.id == 2 }.toVcsCommit(graph.hashMap))
}

View File

@@ -22,6 +22,7 @@ import com.intellij.util.messages.MessageBusConnection;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.VcsLogSorter;
import com.intellij.vcs.log.graph.GraphCommit;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.graph.impl.facade.PermanentGraphImpl;
import com.intellij.vcs.log.graph.impl.print.GraphColorGetterByNodeFactory;
import com.intellij.vcs.log.impl.*;
@@ -394,10 +395,10 @@ public final class GitLogProvider implements VcsLogProvider, VcsIndexableLogProv
@Override
public @NotNull List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection,
int maxCount) throws VcsException {
@NotNull PermanentGraph.Options graphOptions, int maxCount) throws VcsException {
VcsLogRangeFilter rangeFilter = filterCollection.get(RANGE_FILTER);
if (rangeFilter == null) {
return getCommitsMatchingFilter(root, filterCollection, null, maxCount);
return getCommitsMatchingFilter(root, filterCollection, null, graphOptions, maxCount);
}
/*
@@ -407,17 +408,19 @@ public final class GitLogProvider implements VcsLogProvider, VcsIndexableLogProv
*/
Set<TimedVcsCommit> commits = new LinkedHashSet<>();
if (filterCollection.get(BRANCH_FILTER) != null || filterCollection.get(REVISION_FILTER) != null) {
commits.addAll(getCommitsMatchingFilter(root, filterCollection, null, maxCount));
commits.addAll(getCommitsMatchingFilter(root, filterCollection, null, graphOptions, maxCount));
filterCollection = VcsLogFiltersKt.without(VcsLogFiltersKt.without(filterCollection, BRANCH_FILTER), REVISION_FILTER);
}
for (VcsLogRangeFilter.RefRange range : rangeFilter.getRanges()) {
commits.addAll(getCommitsMatchingFilter(root, filterCollection, range, maxCount));
commits.addAll(getCommitsMatchingFilter(root, filterCollection, range, graphOptions, maxCount));
}
return new ArrayList<>(commits);
}
private @NotNull List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection,
@Nullable VcsLogRangeFilter.RefRange range, int maxCount) throws VcsException {
@Nullable VcsLogRangeFilter.RefRange range,
@NotNull PermanentGraph.Options options,
int maxCount) throws VcsException {
GitRepository repository = getRepository(root);
if (repository == null) {
@@ -472,6 +475,10 @@ public final class GitLogProvider implements VcsLogProvider, VcsIndexableLogProv
filterParameters.add(prepareParameter("max-count", String.valueOf(maxCount)));
}
if (options.equals(PermanentGraph.Options.FirstParent.INSTANCE)) {
filterParameters.add("--first-parent");
}
// note: structure filter must be the last parameter, because it uses "--" which separates parameters from paths
VcsLogStructureFilter structureFilter = filterCollection.get(STRUCTURE_FILTER);
if (structureFilter != null) {

View File

@@ -8,6 +8,7 @@ import com.intellij.util.CollectConsumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.impl.HashImpl;
import com.intellij.vcs.log.impl.RequirementsImpl;
import com.intellij.vcs.log.impl.VcsCommitMetadataImpl;
@@ -326,7 +327,7 @@ public class GitLogProviderTest extends GitSingleRepoTest {
@NotNull
private List<String> getFilteredHashes(@NotNull VcsLogFilterCollection filters) throws VcsException {
List<TimedVcsCommit> commits = myLogProvider.getCommitsMatchingFilter(getProjectRoot(), filters, -1);
List<TimedVcsCommit> commits = myLogProvider.getCommitsMatchingFilter(getProjectRoot(), filters, PermanentGraph.Options.Default, -1);
return ContainerUtil.map(commits, commit -> commit.getId().asString());
}

View File

@@ -16,6 +16,7 @@ import com.intellij.util.EmptyConsumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.impl.LogDataImpl;
import com.intellij.vcs.log.util.UserNameRegex;
import com.intellij.vcs.log.util.VcsUserUtil;
@@ -186,9 +187,8 @@ public final class HgLogProvider implements VcsLogProvider {
}
@Override
public @NotNull List<TimedVcsCommit> getCommitsMatchingFilter(final @NotNull VirtualFile root,
@NotNull VcsLogFilterCollection filterCollection,
int maxCount) {
public @NotNull List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection,
@NotNull PermanentGraph.Options graphOptions, int maxCount) {
List<String> filterParameters = new ArrayList<>();
// branch filter and user filter may be used several times without delimiter

View File

@@ -6,6 +6,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.TimedVcsCommit;
import com.intellij.vcs.log.VcsLogFilterCollection;
import com.intellij.vcs.log.VcsLogTextFilter;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.visible.filters.VcsLogFilterObject;
import hg4idea.test.HgPlatformTest;
import org.jetbrains.annotations.NotNull;
@@ -79,7 +80,8 @@ public class HgTextFilterTest extends HgPlatformTest {
@NotNull
private List<String> getFilteredCommits(@NotNull HgLogProvider provider, @NotNull VcsLogTextFilter filter) throws VcsException {
VcsLogFilterCollection filterCollection = VcsLogFilterObject.collection(filter);
List<TimedVcsCommit> commits = provider.getCommitsMatchingFilter(getOrCreateProjectBaseDir(), filterCollection, -1);
List<TimedVcsCommit> commits = provider.getCommitsMatchingFilter(getOrCreateProjectBaseDir(), filterCollection,
PermanentGraph.Options.Default, -1);
return ContainerUtil.map(commits, commit -> commit.getId().asString());
}