]> source.dussan.org Git - jgit.git/commitdiff
Offer ObjectReaders advice about a RevWalk 21/1221/3
authorShawn O. Pearce <spearce@spearce.org>
Fri, 30 Jul 2010 02:52:36 +0000 (19:52 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Sat, 21 Aug 2010 00:41:27 +0000 (17:41 -0700)
By giving the reader information about the roots of a revision
traversal, some readers may be able to prefetch information from
their backing store using background threads in order to reduce
data access latency.  However this isn't typically necessary so
the default reader implementation doesn't react to the advice.

Change-Id: I72c6cbd05cff7d8506826015f50d9f57d5cda77e
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java

index 7bdc5bce4546a552243a88da3e09d63735a839a1..e1ee1441d7c7713fa86ae8bcf670d8819e816a97 100644 (file)
 package org.eclipse.jgit.lib;
 
 import java.io.IOException;
+import java.util.Collection;
 
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.storage.pack.ObjectReuseAsIs;
 
 /**
@@ -173,6 +177,44 @@ public abstract class ObjectReader {
                return open(objectId, typeHint).getSize();
        }
 
+       /**
+        * Advice from a {@link RevWalk} that a walk is starting from these roots.
+        *
+        * @param walk
+        *            the revision pool that is using this reader.
+        * @param roots
+        *            starting points of the revision walk. The starting points have
+        *            their headers parsed, but might be missing bodies.
+        * @throws IOException
+        *             the reader cannot initialize itself to support the walk.
+        */
+       public void walkAdviceBeginCommits(RevWalk walk, Collection<RevCommit> roots)
+                       throws IOException {
+               // Do nothing by default, most readers don't want or need advice.
+       }
+
+       /**
+        * Advice from an {@link ObjectWalk} that trees will be traversed.
+        *
+        * @param ow
+        *            the object pool that is using this reader.
+        * @param min
+        *            the first commit whose root tree will be read.
+        * @param max
+        *            the last commit whose root tree will be read.
+        * @throws IOException
+        *             the reader cannot initialize itself to support the walk.
+        */
+       public void walkAdviceBeginTrees(ObjectWalk ow, RevCommit min, RevCommit max)
+                       throws IOException {
+               // Do nothing by default, most readers don't want or need advice.
+       }
+
+       /** Advice from that a walk is over. */
+       public void walkAdviceEnd() {
+               // Do nothing by default, most readers don't want or need advice.
+       }
+
        /**
         * Release any resources used by this reader.
         * <p>
index 76510ce38781250dc1d198067bb4d7073731d3e7..735f7d6023f32e8e22fb7b59ccfca996bb7200de 100644 (file)
@@ -137,6 +137,7 @@ class MergeBaseGenerator extends Generator {
                for (;;) {
                        final RevCommit c = pending.next();
                        if (c == null) {
+                               walker.reader.walkAdviceEnd();
                                walker.reader.release();
                                return null;
                        }
index a6ecfe219230fb519aa8510b3d056128625a388e..3df5a468f6bd7cc9ddde83da0e1209ecaa22595c 100644 (file)
@@ -91,6 +91,10 @@ public class ObjectWalk extends RevWalk {
 
        private RevObject last;
 
+       private RevCommit firstCommit;
+
+       private RevCommit lastCommit;
+
        /**
         * Create a new revision and object walker for a given repository.
         *
@@ -235,6 +239,9 @@ public class ObjectWalk extends RevWalk {
                                }
                                continue;
                        }
+                       if (firstCommit == null)
+                               firstCommit = r;
+                       lastCommit = r;
                        pendingObjects.add(r.getTree());
                        return r;
                }
@@ -295,11 +302,19 @@ public class ObjectWalk extends RevWalk {
                        treeWalk = treeWalk.next();
                }
 
+               if (firstCommit != null) {
+                       reader.walkAdviceBeginTrees(this, firstCommit, lastCommit);
+                       firstCommit = null;
+                       lastCommit = null;
+               }
+
                last = null;
                for (;;) {
                        final RevObject o = pendingObjects.next();
-                       if (o == null)
+                       if (o == null) {
+                               reader.walkAdviceEnd();
                                return null;
+                       }
                        if ((o.flags & SEEN) != 0)
                                continue;
                        o.flags |= SEEN;
@@ -403,6 +418,8 @@ public class ObjectWalk extends RevWalk {
                treeWalk = new CanonicalTreeParser();
                currentTree = null;
                last = null;
+               firstCommit = null;
+               lastCommit = null;
        }
 
        @Override
@@ -412,6 +429,8 @@ public class ObjectWalk extends RevWalk {
                treeWalk = new CanonicalTreeParser();
                currentTree = null;
                last = null;
+               firstCommit = null;
+               lastCommit = null;
        }
 
        private void addObject(final RevObject o) {
index 0e2bb98320720e7f4b52da5d9ad08b61cf03e7df..ec7069b4d28a7e219329399146495b38a9a13ac4 100644 (file)
@@ -128,7 +128,9 @@ class PendingGenerator extends Generator {
                        for (;;) {
                                final RevCommit c = pending.next();
                                if (c == null) {
-                                       walker.reader.release();
+                                       walker.reader.walkAdviceEnd();
+                                       if (!(walker instanceof ObjectWalk))
+                                               walker.reader.release();
                                        return null;
                                }
 
@@ -174,6 +176,7 @@ class PendingGenerator extends Generator {
                                        c.disposeBody();
                        }
                } catch (StopWalkException swe) {
+                       walker.reader.walkAdviceEnd();
                        walker.reader.release();
                        pending.clear();
                        return null;
index 7406bb60cd52e37c112b6833537f7b8b7f114969..5f8fd5c8af9f7e7b323fa5a3c84eff506827ecf4 100644 (file)
@@ -172,7 +172,7 @@ public class RevWalk implements Iterable<RevCommit> {
 
        int carryFlags = UNINTERESTING;
 
-       private final ArrayList<RevCommit> roots;
+       final ArrayList<RevCommit> roots;
 
        AbstractRevQueue queue;
 
index 5e778a416e6b7c75f362c2d1c87a4630ac94c532..fbff027784325a326ff65b341ed58c7036956877 100644 (file)
@@ -85,6 +85,8 @@ class StartGenerator extends Generator {
                final TreeFilter tf = w.getTreeFilter();
                AbstractRevQueue q = walker.queue;
 
+               w.reader.walkAdviceBeginCommits(w, w.roots);
+
                if (rf == RevFilter.MERGE_BASE) {
                        // Computing for merge bases is a special case and does not
                        // use the bulk of the generator pipeline.