[EGIT PATCH 5/5] Cache resolved ids in quickdiff document for faster update
We do this by caching the commit, tree and blob ids and can then very quickly decide whether a change in baseline actually results in a changed version of the reference blob used for quickdiff.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
.../egit/ui/internal/decorators/GitDocument.java | 70 +++++++++++++++++---
1 files changed, 60 insertions(+), 10 deletions(-)
Show changes to org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitDocument.java +60 −10
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitDocument.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitDocument.java
index 347e6fc..59a738c 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitDocument.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitDocument.java
@@ -20,8 +20,11 @@
import org.spearce.egit.core.GitProvider;
import org.spearce.egit.core.project.RepositoryMapping;
import org.spearce.egit.ui.Activator;
+import org.spearce.jgit.lib.AnyObjectId;
+import org.spearce.jgit.lib.Commit;
import org.spearce.jgit.lib.Constants;
import org.spearce.jgit.lib.IndexChangedEvent;
+import org.spearce.jgit.lib.ObjectId;
import org.spearce.jgit.lib.ObjectLoader;
import org.spearce.jgit.lib.RefsChangedEvent;
import org.spearce.jgit.lib.Repository;
@@ -31,6 +34,11 @@
class GitDocument extends Document implements RepositoryListener {
private final IResource resource;
+
+ private AnyObjectId lastCommit;
+ private AnyObjectId lastTree;
+ private AnyObjectId lastBlob;
+
static Map<GitDocument,Repository> doc2repo = new WeakHashMap<GitDocument, Repository>();
static GitDocument create(final IResource resource) throws IOException {
@@ -51,29 +59,68 @@ private GitDocument(IResource resource) {
GitDocument.doc2repo.put(this, getRepository());
}
+ private void setResolved(final AnyObjectId commit, final AnyObjectId tree, final AnyObjectId blob, final String value) {
+ lastCommit = commit != null ? commit.copy() : null;
+ lastTree = tree != null ? tree.copy() : null;
+ lastBlob = blob != null ? blob.copy() : null;
+ set(value);
+ if (blob != null)
+ Activator.trace("(GitDocument) resolved " + resource + " to " + lastBlob + " in " + lastCommit + "/" + lastTree);
+ else
+ Activator.trace("(GitDocument) unresolved " + resource);
+ }
+
void populate() throws IOException {
Activator.trace("(GitDocument) populate: " + resource);
- set("");
final IProject project = resource.getProject();
RepositoryMapping mapping = RepositoryMapping.getMapping(project);
- if (mapping == null)
+ if (mapping == null) {
+ setResolved(null, null, null, "");
return;
+ }
final String gitPath = mapping.getRepoRelativePath(resource);
- final Repository repository = getRepository();
+ final Repository repository = mapping.getRepository();
String baseline = GitQuickDiffProvider.baseline.get(repository);
if (baseline == null)
baseline = Constants.HEAD;
- Tree baselineTree = repository.mapTree(baseline);
- if (baselineTree == null) {
+ ObjectId commitId = repository.resolve(baseline);
+ if (commitId != null) {
+ if (commitId.equals(lastCommit)) {
+ Activator.trace("(GitDocument) already resolved");
+ return;
+ }
+ } else {
Activator.logError("Could not resolve quickdiff baseline "
+ baseline + " corresponding to " + resource + " in "
+ repository, new Throwable());
+ setResolved(null, null, null, "");
+ return;
+ }
+ Commit baselineCommit = repository.mapCommit(commitId);
+ if (baselineCommit == null) {
+ Activator.logError("Could not load commit " + commitId + " for "
+ + baseline + " corresponding to " + resource + " in "
+ + repository, new Throwable());
+ setResolved(null, null, null, "");
+ return;
+ }
+ ObjectId treeId = baselineCommit.getTreeId();
+ if (treeId.equals(lastTree)) {
+ Activator.trace("(GitDocument) already resolved");
+ return;
+ }
+ Tree baselineTree = baselineCommit.getTree();
+ if (baselineTree == null) {
+ Activator.logError("Could not load tree " + treeId + " for "
+ + baseline + " corresponding to " + resource + " in "
+ + repository, new Throwable());
+ setResolved(null, null, null, "");
return;
}
- TreeEntry blobEnry = baselineTree.findBlobMember(gitPath);
- if (blobEnry != null) {
+ TreeEntry blobEntry = baselineTree.findBlobMember(gitPath);
+ if (blobEntry != null && !blobEntry.getId().equals(lastBlob)) {
Activator.trace("(GitDocument) compareTo: " + baseline);
- ObjectLoader loader = repository.openBlob(blobEnry.getId());
+ ObjectLoader loader = repository.openBlob(blobEntry.getId());
byte[] bytes = loader.getBytes();
String charset;
// Get the encoding for the current version. As a matter of
@@ -92,10 +139,13 @@ void populate() throws IOException {
// Finally we could consider validating the content with respect
// to the content. We don't do that here.
String s = new String(bytes, charset);
- set(s);
+ setResolved(commitId, baselineTree.getId(), blobEntry.getId(), s);
Activator.trace("(GitDocument) has reference doc, size=" + s.length() + " bytes");
} else {
- Activator.trace("(GitDocument) no revision.");
+ if (blobEntry == null)
+ setResolved(null, null, null, "");
+ else
+ Activator.trace("(GitDocument) already resolved");
}
}
--
1.6.2.1.345.g89fb