From 1c2a61ba3257c1f6b9a07d4d98d6799bcd0d5823 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Wed, 27 Dec 2017 03:42:25 +0300 Subject: [PATCH] [vcs-log] walk through storage only once --- .../vcs/log/data/InMemoryStorage.java | 15 +++------------ .../intellij/vcs/log/data/VcsLogStorage.java | 19 ++++++++++++++++++- .../vcs/log/data/VcsLogStorageImpl.java | 16 +++------------- .../vcs/log/ui/frame/DetailsPanel.java | 17 +++++++++++------ .../vcs/log/visible/VisiblePackBuilderTest.kt | 3 +-- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryStorage.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryStorage.java index 207101645b1d..f51f1afebbf3 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryStorage.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryStorage.java @@ -15,8 +15,8 @@ */ package com.intellij.vcs.log.data; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Function; import com.intellij.util.containers.BiDirectionalEnumerator; import com.intellij.vcs.log.CommitId; import com.intellij.vcs.log.Hash; @@ -45,18 +45,9 @@ public class InMemoryStorage implements VcsLogStorage { return myCommitIdEnumerator.getValue(commitIndex); } - @Nullable @Override - public CommitId findCommitId(@NotNull final Condition condition) { - final CommitId[] result = new CommitId[]{null}; - myCommitIdEnumerator.forEachValue(commitId -> { - if (condition.value(commitId)) { - result[0] = commitId; - return false; - } - return true; - }); - return result[0]; + public void iterateCommits(@NotNull Function consumer) { + myCommitIdEnumerator.forEachValue(commitId -> !consumer.fun(commitId)); } @Override diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorage.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorage.java index 190af9492104..8deef3d24bdc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorage.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorage.java @@ -16,7 +16,9 @@ package com.intellij.vcs.log.data; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Function; import com.intellij.vcs.log.CommitId; import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.VcsRef; @@ -49,13 +51,28 @@ public interface VcsLogStorage { @Nullable CommitId getCommitId(int commitIndex); + /** + * Iterates over known commit ids. Stops when consumer returns true. + */ + void iterateCommits(@NotNull Function consumer); + /** * Iterates over known commit ids to find the first one which satisfies given condition. * * @return matching commit or null if no commit matches the given condition */ @Nullable - CommitId findCommitId(@NotNull Condition condition); + default CommitId findCommitId(@NotNull Condition condition) { + Ref hashRef = Ref.create(); + iterateCommits(commitId -> { + boolean matches = condition.value(commitId); + if (matches) { + hashRef.set(commitId); + } + return matches; + }); + return hashRef.get(); + } /** * Returns an integer index that is a unique identifier for a reference. diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java index ec5abac495a7..9a3df87481c2 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java @@ -126,26 +126,18 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { } @Override - @Nullable - public CommitId findCommitId(@NotNull final Condition condition) { + public void iterateCommits(@NotNull Function consumer) { checkDisposed(); try { - final Ref hashRef = Ref.create(); myCommitIdEnumerator.iterateData(new CommonProcessors.FindProcessor() { @Override protected boolean accept(CommitId commitId) { - boolean matches = condition.value(commitId); - if (matches) { - hashRef.set(commitId); - } - return matches; + return consumer.fun(commitId); } }); - return hashRef.get(); } catch (IOException e) { myExceptionReporter.consume(this, e); - return null; } } @@ -246,10 +238,8 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { throw new UnsupportedOperationException("Illegal access to empty hash map by index " + commitIndex); } - @Nullable @Override - public CommitId findCommitId(@NotNull Condition string) { - return null; + public void iterateCommits(@NotNull Function consumer) { } @Override diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java index d6ed48044ccc..89f77c38ed6c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java @@ -43,7 +43,6 @@ import com.intellij.util.ui.UIUtil; import com.intellij.vcs.log.CommitId; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.VcsRef; -import com.intellij.vcs.log.data.CommitIdByStringCondition; import com.intellij.vcs.log.data.VcsLogData; import com.intellij.vcs.log.ui.VcsLogColorManager; import com.intellij.vcs.log.ui.frame.CommitPresentationUtil.CommitPresentation; @@ -182,13 +181,19 @@ public class DetailsPanel extends JPanel implements EditorColorsListener, Dispos if (!unResolvedHashes.isEmpty()) { myResolveIndicator = BackgroundTaskUtil.executeOnPooledThread(this, () -> { Map resolvedHashes = ContainerUtil.newHashMap(); + myLogData.getStorage().iterateCommits(commitId -> { + Set found = ContainerUtil.newHashSet(); + for (String hashString : unResolvedHashes) { - for (String hashString : unResolvedHashes) { - CommitId commitId = myLogData.getStorage().findCommitId(new CommitIdByStringCondition(hashString)); - if (commitId != null) { - resolvedHashes.put(hashString, commitId); + if (StringUtil.startsWithIgnoreCase(commitId.getHash().asString(), hashString)) { + resolvedHashes.put(hashString, commitId); + found.add(hashString); + // do not break, check all hashes (we can have several substrings of the same hash) + } } - } + unResolvedHashes.removeAll(found); + return unResolvedHashes.isEmpty(); + }); List resolvedPresentations = ContainerUtil.map2List(presentations, presentation -> presentation.resolve(resolvedHashes)); diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/visible/VisiblePackBuilderTest.kt b/platform/vcs-log/impl/test/com/intellij/vcs/log/visible/VisiblePackBuilderTest.kt index 6106d1567085..6ce5f643b50c 100644 --- a/platform/vcs-log/impl/test/com/intellij/vcs/log/visible/VisiblePackBuilderTest.kt +++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/visible/VisiblePackBuilderTest.kt @@ -17,7 +17,6 @@ package com.intellij.vcs.log.visible import com.intellij.mock.MockVirtualFile import com.intellij.openapi.progress.ProgressIndicator -import com.intellij.openapi.util.Condition import com.intellij.openapi.vfs.VirtualFile import com.intellij.util.Consumer import com.intellij.util.Function @@ -239,7 +238,7 @@ class VisiblePackBuilderTest { override fun getRefIndex(ref: VcsRef): Int = refsReversed[ref]!! - override fun findCommitId(condition: Condition): CommitId? = throw UnsupportedOperationException() + override fun iterateCommits(consumer: Function) = throw UnsupportedOperationException() override fun flush() { }