diff options
author | Thomas Wolf | 2019-08-28 20:59:44 +0000 |
---|---|---|
committer | Thomas Wolf | 2019-09-05 16:11:52 +0000 |
commit | 8bf986c31e2b7e97f3490f08993d11706d39c13d (patch) | |
tree | 03e8266d97871e92126e4f4b6d5ed2033b2db4d1 /org.eclipse.egit.gitflow.ui/src/org/eclipse | |
parent | fb2fc5db7dd038e73af0bc8acfed1e4f96f8bbd3 (diff) | |
download | egit-8bf986c31e2b7e97f3490f08993d11706d39c13d.tar.gz egit-8bf986c31e2b7e97f3490f08993d11706d39c13d.tar.xz egit-8bf986c31e2b7e97f3490f08993d11706d39c13d.zip |
Cache more repository state for re-use in the UI thread
Many EGit commands depend on some repository state determining their
enablement. Eclipse re-evaluates activation/enablement expressions or
handlers' isEnabled() method very frequently. For globally available
handlers, on every selection change; for others for instance when
they are included in some (context) menu.
JGit operations to determine repository state access the file system
(typically config files, or the packed_refs file, or loose refs), and
check every time whether the file has been changed since the last
access. In the case of a repository config file, this check is even
done for the user and system config files, too. If JGit determines
that a file has been changed it reloads it, perhaps even multiple
times depending on the file timestamp resolution.
Thus accessing the repository config file or determining the currently
checked out branch are expensive file system operations. Handler
enablements are evaluated on the UI thread, so EGit did *a lot* of
expensive file system accesses on the UI thread, which slows down
Eclipse startup and context menus in particular.
Introduce a cache for the most important values of a repository that
are used in property testers and in handler activation and enablement
code. The cache is cleared whenever the workbench selection or the
"menu selection" changes to avoid serving stale values. When Eclipse
then re-evaluates enablements, only the first expressions will actually
access the file system, while all later re-evaluations due to a
selection change will use the cached values.
Caching values until the next selection change is a valid strategy.
When a series of enablements is re-computed, these re-computations
are all based on the same selection, thus using the repository state
as it was at the beginning is fine.
This greatly reduces the number of times EGit accesses the file system
on the UI thread and generally makes the EGit UI *much* snappier.
This cache should be used only for evaluations that are known to
happen synchronously in the UI thread in response to a selection
change. This includes property testers and isEnabled() on handlers.
Bug: 544600
Change-Id: Idd369b50d8b4bd6dd68b30d640bbc13f5a5976c5
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.egit.gitflow.ui/src/org/eclipse')
-rw-r--r-- | org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/properties/RepositoryPropertyTester.java | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/properties/RepositoryPropertyTester.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/properties/RepositoryPropertyTester.java index 23e0d64030..ad7e9886c0 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/properties/RepositoryPropertyTester.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/properties/RepositoryPropertyTester.java @@ -13,14 +13,11 @@ *******************************************************************************/ package org.eclipse.egit.gitflow.ui.internal.properties; -import static org.eclipse.egit.gitflow.ui.Activator.error; - import java.io.File; -import java.io.IOException; -import org.eclipse.egit.gitflow.Activator; -import org.eclipse.egit.gitflow.GitFlowRepository; +import org.eclipse.egit.gitflow.GitFlowConfig; import org.eclipse.egit.ui.internal.expressions.AbstractPropertyTester; +import org.eclipse.egit.ui.internal.selection.RepositoryStateCache; import org.eclipse.jgit.lib.Repository; /** @@ -62,25 +59,30 @@ public class RepositoryPropertyTester extends AbstractPropertyTester { } private boolean internalTest(Repository repository, String property) { - GitFlowRepository gitFlowRepository = new GitFlowRepository(repository); - try { - if (IS_INITIALIZED.equals(property)) { - return gitFlowRepository.getConfig().isInitialized(); - } else if (IS_FEATURE.equals(property)) { - return gitFlowRepository.isFeature(); + GitFlowConfig config = new GitFlowConfig( + RepositoryStateCache.INSTANCE.getConfig(repository)); + if (IS_INITIALIZED.equals(property)) { + return config.isInitialized(); + } else if (HAS_DEFAULT_REMOTE.equals(property)) { + return config.hasDefaultRemote(); + } else { + String branch = RepositoryStateCache.INSTANCE + .getFullBranchName(repository); + if (branch == null) { + return false; + } + branch = Repository.shortenRefName(branch); + if (IS_FEATURE.equals(property)) { + return branch.startsWith(config.getFeaturePrefix()); } else if (IS_RELEASE.equals(property)) { - return gitFlowRepository.isRelease(); + return branch.startsWith(config.getReleasePrefix()); } else if (IS_HOTFIX.equals(property)) { - return gitFlowRepository.isHotfix(); + return branch.startsWith(config.getHotfixPrefix()); } else if (IS_DEVELOP.equals(property)) { - return gitFlowRepository.isDevelop(); + return branch.equals(config.getDevelop()); } else if (IS_MASTER.equals(property)) { - return gitFlowRepository.isMaster(); - } else if (HAS_DEFAULT_REMOTE.equals(property)) { - return gitFlowRepository.getConfig().hasDefaultRemote(); + return branch.equals(config.getMaster()); } - } catch (IOException e) { - Activator.getDefault().getLog().log(error(e.getMessage(), e)); } return false; } |