Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2019-08-28 20:59:44 +0000
committerThomas Wolf2019-09-05 16:11:52 +0000
commit8bf986c31e2b7e97f3490f08993d11706d39c13d (patch)
tree03e8266d97871e92126e4f4b6d5ed2033b2db4d1 /org.eclipse.egit.gitflow.ui/src/org/eclipse
parentfb2fc5db7dd038e73af0bc8acfed1e4f96f8bbd3 (diff)
downloadegit-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.java40
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;
}

Back to the top