MergeSuperSet: Avoid repeated ref lookups
This is similar to using a RefCache. We would use that if it already existed in MergeOpRepoManager, but it doesn't. The actual usage within MergeSuperSet is a little more specific, so just do a little cache implementation there. Change-Id: I0404bc3c1240eab59f1dedf53f068632bd67d5ef
This commit is contained in:
@@ -102,6 +102,7 @@ public class MergeSuperSet {
|
|||||||
private final Provider<MergeOpRepoManager> repoManagerProvider;
|
private final Provider<MergeOpRepoManager> repoManagerProvider;
|
||||||
private final Config cfg;
|
private final Config cfg;
|
||||||
private final Map<QueryKey, List<ChangeData>> queryCache;
|
private final Map<QueryKey, List<ChangeData>> queryCache;
|
||||||
|
private final Map<Branch.NameKey, Optional<RevCommit>> heads;
|
||||||
|
|
||||||
private MergeOpRepoManager orm;
|
private MergeOpRepoManager orm;
|
||||||
private boolean closeOrm;
|
private boolean closeOrm;
|
||||||
@@ -116,6 +117,7 @@ public class MergeSuperSet {
|
|||||||
this.queryProvider = queryProvider;
|
this.queryProvider = queryProvider;
|
||||||
this.repoManagerProvider = repoManagerProvider;
|
this.repoManagerProvider = repoManagerProvider;
|
||||||
queryCache = new HashMap<>();
|
queryCache = new HashMap<>();
|
||||||
|
heads = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MergeSuperSet setMergeOpRepoManager(MergeOpRepoManager orm) {
|
public MergeSuperSet setMergeOpRepoManager(MergeOpRepoManager orm) {
|
||||||
@@ -182,13 +184,11 @@ public class MergeSuperSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> walkChangesByHashes(Collection<RevCommit> sourceCommits,
|
private Set<String> walkChangesByHashes(Collection<RevCommit> sourceCommits,
|
||||||
Set<String> ignoreHashes, OpenRepo or, Optional<RevCommit> head)
|
Set<String> ignoreHashes, OpenRepo or, Branch.NameKey b)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Set<String> destHashes = new HashSet<>();
|
Set<String> destHashes = new HashSet<>();
|
||||||
or.rw.reset();
|
or.rw.reset();
|
||||||
if (head.isPresent()) {
|
markHeadUninteresting(or, b);
|
||||||
or.rw.markUninteresting(head.get());
|
|
||||||
}
|
|
||||||
for (RevCommit c : sourceCommits) {
|
for (RevCommit c : sourceCommits) {
|
||||||
String name = c.name();
|
String name = c.name();
|
||||||
if (ignoreHashes.contains(name)) {
|
if (ignoreHashes.contains(name)) {
|
||||||
@@ -270,15 +270,9 @@ public class MergeSuperSet {
|
|||||||
toWalk.add(commit);
|
toWalk.add(commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref ref = or.repo.getRefDatabase().getRef(b.get());
|
|
||||||
Optional<RevCommit> head =
|
|
||||||
ref != null
|
|
||||||
? Optional.<RevCommit>of(or.rw.parseCommit(ref.getObjectId()))
|
|
||||||
: Optional.<RevCommit>absent();
|
|
||||||
|
|
||||||
Set<String> emptySet = Collections.emptySet();
|
Set<String> emptySet = Collections.emptySet();
|
||||||
Set<String> visibleHashes = walkChangesByHashes(visibleCommits,
|
Set<String> visibleHashes =
|
||||||
emptySet, or, head);
|
walkChangesByHashes(visibleCommits, emptySet, or, b);
|
||||||
|
|
||||||
List<ChangeData> cds =
|
List<ChangeData> cds =
|
||||||
byCommitsOnBranchNotMerged(or, db, user, b, visibleHashes);
|
byCommitsOnBranchNotMerged(or, db, user, b, visibleHashes);
|
||||||
@@ -287,8 +281,8 @@ public class MergeSuperSet {
|
|||||||
visibleChanges.add(chd);
|
visibleChanges.add(chd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> nonVisibleHashes = walkChangesByHashes(nonVisibleCommits,
|
Set<String> nonVisibleHashes =
|
||||||
visibleHashes, or, head);
|
walkChangesByHashes(nonVisibleCommits, visibleHashes, or, b);
|
||||||
Iterables.addAll(nonVisibleChanges,
|
Iterables.addAll(nonVisibleChanges,
|
||||||
byCommitsOnBranchNotMerged(or, db, user, b, nonVisibleHashes));
|
byCommitsOnBranchNotMerged(or, db, user, b, nonVisibleHashes));
|
||||||
}
|
}
|
||||||
@@ -310,6 +304,21 @@ public class MergeSuperSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void markHeadUninteresting(OpenRepo or, Branch.NameKey b)
|
||||||
|
throws IOException {
|
||||||
|
Optional<RevCommit> head = heads.get(b);
|
||||||
|
if (head == null) {
|
||||||
|
Ref ref = or.repo.getRefDatabase().exactRef(b.get());
|
||||||
|
head = ref != null
|
||||||
|
? Optional.<RevCommit>of(or.rw.parseCommit(ref.getObjectId()))
|
||||||
|
: Optional.<RevCommit>absent();
|
||||||
|
heads.put(b, head);
|
||||||
|
}
|
||||||
|
if (head.isPresent()) {
|
||||||
|
or.rw.markUninteresting(head.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<ChangeData> byCommitsOnBranchNotMerged(OpenRepo or, ReviewDb db,
|
private List<ChangeData> byCommitsOnBranchNotMerged(OpenRepo or, ReviewDb db,
|
||||||
CurrentUser user, Branch.NameKey branch, Set<String> hashes)
|
CurrentUser user, Branch.NameKey branch, Set<String> hashes)
|
||||||
throws OrmException, IOException {
|
throws OrmException, IOException {
|
||||||
|
|||||||
Reference in New Issue
Block a user