From a3620cbbe144c9b666ce4472fd5e8ef1222bd641 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 18 Nov 2010 17:15:19 -0800 Subject: [PATCH] Reuse cached SHA-1 when computing from WorkingTreeIterator Change-Id: I2b2170c29017993d8cb7a1d3c8cd94fb16c7dd02 Signed-off-by: Shawn O. Pearce Signed-off-by: Christian Halstrick --- .../jgit/treewalk/WorkingTreeIterator.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index 48e64831cd..e2dd0c7735 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -64,6 +64,7 @@ import org.eclipse.jgit.JGitText; import org.eclipse.jgit.diff.RawText; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheEntry; +import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.ignore.IgnoreNode; import org.eclipse.jgit.ignore.IgnoreRule; @@ -181,6 +182,24 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { ignoreNode = new RootIgnoreNode(entry, repo); } + /** + * Define the matching {@link DirCacheIterator}, to optimize ObjectIds. + * + * Once the DirCacheIterator has been set this iterator must only be + * advanced by the TreeWalk that is supplied, as it assumes that itself and + * the corresponding DirCacheIterator are positioned on the same file path + * whenever {@link #idBuffer()} is invoked. + * + * @param walk + * the walk that will be advancing this iterator. + * @param treeId + * index of the matching {@link DirCacheIterator}. + */ + public void setDirCacheIterator(TreeWalk walk, int treeId) { + state.walk = walk; + state.dirCacheTree = treeId; + } + @Override public boolean hasId() { if (contentIdFromPtr == ptr) @@ -192,6 +211,21 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { public byte[] idBuffer() { if (contentIdFromPtr == ptr) return contentId; + + if (state.walk != null) { + // If there is a matching DirCacheIterator, we can reuse + // its idBuffer, but only if we appear to be clean against + // the cached index information for the path. + // + DirCacheIterator i = state.walk.getTree(state.dirCacheTree, + DirCacheIterator.class); + if (i != null) { + DirCacheEntry ent = i.getDirCacheEntry(); + if (ent != null && compareMetadata(ent) == MetadataDiff.EQUAL) + return i.idBuffer(); + } + } + switch (mode & FileMode.TYPE_MASK) { case FileMode.TYPE_FILE: contentIdFromPtr = ptr; @@ -890,6 +924,12 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { /** Buffer used to perform {@link #contentId} computations. */ byte[] contentReadBuffer; + /** TreeWalk with a (supposedly) matching DirCacheIterator. */ + TreeWalk walk; + + /** Position of the matching {@link DirCacheIterator}. */ + int dirCacheTree; + IteratorState(WorkingTreeOptions options) { this.options = options; this.nameEncoder = Constants.CHARSET.newEncoder(); -- 2.39.5