]> source.dussan.org Git - jgit.git/commitdiff
Reuse cached SHA-1 when computing from WorkingTreeIterator 27/1927/7
authorShawn O. Pearce <spearce@spearce.org>
Fri, 19 Nov 2010 01:15:19 +0000 (17:15 -0800)
committerChris Aniszczyk <caniszczyk@gmail.com>
Thu, 3 Feb 2011 23:06:23 +0000 (17:06 -0600)
Change-Id: I2b2170c29017993d8cb7a1d3c8cd94fb16c7dd02
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java

index 48e64831cd459f2e93a3c662edf7c339f61a83b5..e2dd0c773532617cb737a3ca02c9a0ebab4f56c3 100644 (file)
@@ -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();