diff options
author | Thomas Wolf | 2019-09-01 11:02:30 +0000 |
---|---|---|
committer | Thomas Wolf | 2019-09-05 16:11:52 +0000 |
commit | 1c865c47ba54836f5fe9379a1fb5e1930c8ab362 (patch) | |
tree | 132f2ea94f36fdd1eac7830710d99ebeaf4a58a9 /org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal | |
parent | 8bf986c31e2b7e97f3490f08993d11706d39c13d (diff) | |
download | egit-1c865c47ba54836f5fe9379a1fb5e1930c8ab362.tar.gz egit-1c865c47ba54836f5fe9379a1fb5e1930c8ab362.tar.xz egit-1c865c47ba54836f5fe9379a1fb5e1930c8ab362.zip |
Eliminate exactRef(HEAD) on the UI thread in the history table
CommitGraphTable.doPaint() called input.getHead() every time. This
is a fairly expensive file access occurring on the UI thread for
every row that is painted. At least, it will check whether HEAD
and the ref it may point to have been modified.
Eliminate these calls from the UI thread completely by doing it
once in the SWTWalk, which runs in the background. Once determined,
the head Ref can be obtained through the SWTCommit.
The CommitGraphTable (or rather, the SWTPlotRenderer) uses the head
Ref *only* to bolden the branch that is HEAD.
Bug: 544600
Change-Id: Iea994a0f426a574c26501f4151bc568461dc8aaf
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal')
5 files changed, 65 insertions, 26 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java index b262c19a41..c6ff9f1368 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java @@ -588,7 +588,7 @@ class CommitGraphTable { event.gc.setFont(nFont); } - renderer.paint(event, input == null ? null : input.getHead()); + renderer.paint(event); } /** diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java index 6fb2938a0a..7159c31734 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java @@ -14,7 +14,6 @@ package org.eclipse.egit.ui.internal.history; import java.io.File; -import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -22,12 +21,7 @@ import java.util.List; import java.util.Objects; import org.eclipse.core.resources.IResource; -import org.eclipse.egit.ui.Activator; -import org.eclipse.egit.ui.internal.UIText; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; -import org.eclipse.osgi.util.NLS; /** * Input for the {@link GitHistoryPage} @@ -145,23 +139,6 @@ public class HistoryPageInput { } /** - * @return the HEAD Ref - */ - public Ref getHead() { - try { - Ref h = repo.exactRef(Constants.HEAD); - if (h != null && h.isSymbolic()) - return h; - return null; - } catch (IOException e) { - throw new IllegalStateException(NLS.bind( - UIText.GitHistoryPage_errorParsingHead, Activator - .getDefault().getRepositoryUtil() - .getRepositoryName(repo)), e); - } - } - - /** * Tests whether a file is in a repository's .git directory (or is that * directory itself). * diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTCommit.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTCommit.java index fa3337bbe1..e0fb8aa33c 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTCommit.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTCommit.java @@ -19,6 +19,7 @@ import java.io.IOException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.egit.core.internal.IRepositoryCommit; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revplot.PlotCommit; import org.eclipse.jgit.revwalk.RevCommit; @@ -48,6 +49,17 @@ class SWTCommit extends PlotCommit<SWTCommitList.SWTLane> } } + /** + * Retrieves the HEAD ref if it is symbolic. + * + * @return the Ref, or {@code null} if HEAD is not a symbolic Ref + * @throws IOException + * if the head cannot be read + */ + public Ref getHead() throws IOException { + return walk.getHead(); + } + @Override public <T> T getAdapter(Class<T> adapter) { if (adapter != Repository.class) { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java index 981656e7a3..0235e3fa1f 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java @@ -113,10 +113,9 @@ class SWTPlotRenderer extends AbstractPlotRenderer<SWTLane, Color> { commitDotOutline = resources.createColor(new RGB(110, 110, 110)); } - void paint(final Event event, Ref actHeadRef) { + void paint(final Event event) { g = event.gc; - this.headRef = actHeadRef; cellX = event.x; cellY = event.y; cellFG = g.getForeground(); @@ -128,6 +127,7 @@ class SWTPlotRenderer extends AbstractPlotRenderer<SWTLane, Color> { SWTCommit commit = (SWTCommit) ti.getData(); try { commit.parseBody(); + headRef = commit.getHead(); } catch (IOException e) { Activator.error("Error parsing body", e); //$NON-NLS-1$ return; diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTWalk.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTWalk.java index e832423230..f8945dc80d 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTWalk.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTWalk.java @@ -13,7 +13,13 @@ *******************************************************************************/ package org.eclipse.egit.ui.internal.history; +import java.io.IOException; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revplot.PlotWalk; import org.eclipse.jgit.revwalk.RevCommit; @@ -22,6 +28,10 @@ class SWTWalk extends PlotWalk { private final Repository repo; + private Ref head; + + private boolean headInitialized; + SWTWalk(final Repository repo) { super(repo); this.repo = repo; @@ -32,7 +42,47 @@ class SWTWalk extends PlotWalk { } @Override + protected void reset(int retainFlags) { + headInitialized = false; + head = null; + super.reset(retainFlags); + } + + @Override + public RevCommit next() throws MissingObjectException, + IncorrectObjectTypeException, IOException { + if (!headInitialized) { + head = determineHead(); + headInitialized = true; + } + return super.next(); + } + + /** + * Retrieves the HEAD ref if it is symbolic. + * + * @return the Ref, or {@code null} if HEAD is not a symbolic Ref + * @throws IOException + * if the head cannot be read + */ + public Ref getHead() throws IOException { + if (!headInitialized) { + head = determineHead(); + headInitialized = true; + } + return head; + } + + @Override protected RevCommit createCommit(final AnyObjectId id) { return new SWTCommit(id, this); } + + private Ref determineHead() throws IOException { + Ref h = repo.exactRef(Constants.HEAD); + if (h != null && h.isSymbolic()) { + return h; + } + return null; + } } |