Optimize RevWalkUtils.findBranchesReachableFrom()
In [1], improved RevWalk.getMergedInto() is introduced to avoid repeated work while performing RevWalk.isMergedInto() on many refs. Modify findBranchesReachableFrom() to use it. [1] I65de9873dce67af9c415d1d236bf52d31b67e8fe Change-Id: I81d615241638d4093df64b449637af601843a5ed Signed-off-by: Adithya Chakilam <quic_achakila@quicinc.com>
This commit is contained in:
parent
0bd2f4bf77
commit
41643dcb79
|
@ -32,10 +32,12 @@
|
||||||
import org.eclipse.jgit.lib.AsyncObjectLoaderQueue;
|
import org.eclipse.jgit.lib.AsyncObjectLoaderQueue;
|
||||||
import org.eclipse.jgit.lib.Constants;
|
import org.eclipse.jgit.lib.Constants;
|
||||||
import org.eclipse.jgit.lib.MutableObjectId;
|
import org.eclipse.jgit.lib.MutableObjectId;
|
||||||
|
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.ObjectIdOwnerMap;
|
import org.eclipse.jgit.lib.ObjectIdOwnerMap;
|
||||||
import org.eclipse.jgit.lib.ObjectLoader;
|
import org.eclipse.jgit.lib.ObjectLoader;
|
||||||
import org.eclipse.jgit.lib.ObjectReader;
|
import org.eclipse.jgit.lib.ObjectReader;
|
||||||
|
import org.eclipse.jgit.lib.ProgressMonitor;
|
||||||
import org.eclipse.jgit.lib.Ref;
|
import org.eclipse.jgit.lib.Ref;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.revwalk.filter.RevFilter;
|
import org.eclipse.jgit.revwalk.filter.RevFilter;
|
||||||
|
@ -450,7 +452,33 @@ public boolean isMergedInto(RevCommit base, RevCommit tip)
|
||||||
*/
|
*/
|
||||||
public List<Ref> getMergedInto(RevCommit commit, Collection<Ref> refs)
|
public List<Ref> getMergedInto(RevCommit commit, Collection<Ref> refs)
|
||||||
throws IOException{
|
throws IOException{
|
||||||
return getMergedInto(commit, refs, GetMergedIntoStrategy.EVALUATE_ALL);
|
return getMergedInto(commit, refs, NullProgressMonitor.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the Refs into which a commit is merged.
|
||||||
|
* <p>
|
||||||
|
* A commit is merged into a ref if we can find a path of commits that leads
|
||||||
|
* from that specific ref and ends at <code>commit</code>.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @param commit
|
||||||
|
* commit the caller thinks is reachable from <code>refs</code>.
|
||||||
|
* @param refs
|
||||||
|
* refs to start iteration from, and which is most likely a
|
||||||
|
* descendant (child) of <code>commit</code>.
|
||||||
|
* @param monitor
|
||||||
|
* the callback for progress and cancellation
|
||||||
|
* @return list of refs that are reachable from <code>commit</code>.
|
||||||
|
* @throws java.io.IOException
|
||||||
|
* a pack file or loose object could not be read.
|
||||||
|
* @since 5.12
|
||||||
|
*/
|
||||||
|
public List<Ref> getMergedInto(RevCommit commit, Collection<Ref> refs,
|
||||||
|
ProgressMonitor monitor) throws IOException{
|
||||||
|
return getMergedInto(commit, refs,
|
||||||
|
GetMergedIntoStrategy.EVALUATE_ALL,
|
||||||
|
monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -470,7 +498,8 @@ public List<Ref> getMergedInto(RevCommit commit, Collection<Ref> refs)
|
||||||
public boolean isMergedIntoAny(RevCommit commit, Collection<Ref> refs)
|
public boolean isMergedIntoAny(RevCommit commit, Collection<Ref> refs)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return getMergedInto(commit, refs,
|
return getMergedInto(commit, refs,
|
||||||
GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND).size() > 0;
|
GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND,
|
||||||
|
NullProgressMonitor.INSTANCE).size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -490,12 +519,13 @@ public boolean isMergedIntoAny(RevCommit commit, Collection<Ref> refs)
|
||||||
public boolean isMergedIntoAll(RevCommit commit, Collection<Ref> refs)
|
public boolean isMergedIntoAll(RevCommit commit, Collection<Ref> refs)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return getMergedInto(commit, refs,
|
return getMergedInto(commit, refs,
|
||||||
GetMergedIntoStrategy.RETURN_ON_FIRST_NOT_FOUND).size()
|
GetMergedIntoStrategy.RETURN_ON_FIRST_NOT_FOUND,
|
||||||
|
NullProgressMonitor.INSTANCE).size()
|
||||||
== refs.size();
|
== refs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Ref> getMergedInto(RevCommit needle, Collection<Ref> haystacks,
|
private List<Ref> getMergedInto(RevCommit needle, Collection<Ref> haystacks,
|
||||||
Enum returnStrategy) throws IOException {
|
Enum returnStrategy, ProgressMonitor monitor) throws IOException {
|
||||||
List<Ref> result = new ArrayList<>();
|
List<Ref> result = new ArrayList<>();
|
||||||
RevFilter oldRF = filter;
|
RevFilter oldRF = filter;
|
||||||
TreeFilter oldTF = treeFilter;
|
TreeFilter oldTF = treeFilter;
|
||||||
|
@ -504,6 +534,10 @@ private List<Ref> getMergedInto(RevCommit needle, Collection<Ref> haystacks,
|
||||||
filter = RevFilter.ALL;
|
filter = RevFilter.ALL;
|
||||||
treeFilter = TreeFilter.ALL;
|
treeFilter = TreeFilter.ALL;
|
||||||
for (Ref r: haystacks) {
|
for (Ref r: haystacks) {
|
||||||
|
if (monitor.isCancelled()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
monitor.update(1);
|
||||||
RevObject o = parseAny(r.getObjectId());
|
RevObject o = parseAny(r.getObjectId());
|
||||||
if (!(o instanceof RevCommit)) {
|
if (!(o instanceof RevCommit)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -159,15 +159,12 @@ public static List<Ref> findBranchesReachableFrom(RevCommit commit,
|
||||||
// Make sure commit is from the same RevWalk
|
// Make sure commit is from the same RevWalk
|
||||||
commit = revWalk.parseCommit(commit.getId());
|
commit = revWalk.parseCommit(commit.getId());
|
||||||
revWalk.reset();
|
revWalk.reset();
|
||||||
List<Ref> result = new ArrayList<>();
|
List<Ref> filteredRefs = new ArrayList<>();
|
||||||
monitor.beginTask(JGitText.get().searchForReachableBranches,
|
monitor.beginTask(JGitText.get().searchForReachableBranches,
|
||||||
refs.size());
|
refs.size());
|
||||||
final int SKEW = 24*3600; // one day clock skew
|
final int SKEW = 24*3600; // one day clock skew
|
||||||
|
|
||||||
for (Ref ref : refs) {
|
for (Ref ref : refs) {
|
||||||
if (monitor.isCancelled())
|
|
||||||
return result;
|
|
||||||
monitor.update(1);
|
|
||||||
RevObject maybehead = revWalk.parseAny(ref.getObjectId());
|
RevObject maybehead = revWalk.parseAny(ref.getObjectId());
|
||||||
if (!(maybehead instanceof RevCommit))
|
if (!(maybehead instanceof RevCommit))
|
||||||
continue;
|
continue;
|
||||||
|
@ -179,9 +176,9 @@ public static List<Ref> findBranchesReachableFrom(RevCommit commit,
|
||||||
if (headCommit.getCommitTime() + SKEW < commit.getCommitTime())
|
if (headCommit.getCommitTime() + SKEW < commit.getCommitTime())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (revWalk.isMergedInto(commit, headCommit))
|
filteredRefs.add(ref);
|
||||||
result.add(ref);
|
|
||||||
}
|
}
|
||||||
|
List<Ref> result = revWalk.getMergedInto(commit, filteredRefs, monitor);
|
||||||
monitor.endTask();
|
monitor.endTask();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue