CommitGraphWriter: use ANY_DIFF instead of idEquals inside next()
Calculating the paths modified in a commit respect its parents is
taking undue amount of time in big trees.
Use ANY_DIFF filter, instead of #idEquals() inside the #next(). This
shorcuts the tree browsing earlier.
Change-Id: I318eee3ae817b7b9004d60bdb8d0f1bf19b9962d
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriterTest.java
index 7130d59..80a0f0c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriterTest.java
@@ -435,6 +435,8 @@ public void testPathDiffCalculator_skipUnchangedTree() throws Exception {
.map(b -> StandardCharsets.UTF_8.decode(b).toString())
.collect(toList());
assertThat(asString, containsInAnyOrder("d", "d/sd2", "d/sd2/f2"));
+ // We don't walk into d/sd1/f1
+ assertEquals(1, c.stepCounter);
}
RevCommit commit(RevCommit... parents) throws Exception {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriter.java
index 37a0de8..55539e2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriter.java
@@ -52,6 +52,7 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.EmptyTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.NB;
/**
@@ -447,12 +448,18 @@ private void writeExtraEdges(CancellableDigestOutputStream out)
// Visible for testing
static class PathDiffCalculator {
+
+ // Walk steps in the last invocation of changedPaths
+ int stepCounter;
+
Optional<HashSet<ByteBuffer>> changedPaths(
ObjectReader or, RevCommit cmit) throws MissingObjectException,
IncorrectObjectTypeException, CorruptObjectException, IOException {
+ stepCounter = 0;
HashSet<ByteBuffer> paths = new HashSet<>();
try (TreeWalk walk = new TreeWalk(null, or)) {
walk.setRecursive(true);
+ walk.setFilter(TreeFilter.ANY_DIFF);
if (cmit.getParentCount() == 0) {
walk.addTree(new EmptyTreeIterator());
} else {
@@ -460,9 +467,7 @@ Optional<HashSet<ByteBuffer>> changedPaths(
}
walk.addTree(cmit.getTree());
while (walk.next()) {
- if (walk.idEqual(0, 1)) {
- continue;
- }
+ stepCounter += 1;
byte[] rawPath = walk.getRawPath();
paths.add(ByteBuffer.wrap(rawPath));
for (int i = 0; i < rawPath.length; i++) {