Avoid expensive getAllRefsByPeeledObjectId() in PlotWalk constructor
Instead, do it when we return the first PlotCommit from next(). On a repository with many refs, getAllRefsByPeeledObjectId() can take a while. Doing a late initialization simplifies the handling of a PlotWalk. EGit, for instance, creates and configures an instance, and then does the real walk in a background job. With late initialization, the potentially expensive getAllRefsByPeeledObjectId() also occurs in that background job. Bug: 485743 Change-Id: I84c020cf8f7afda6f181778786612b8e6ddd7ed8 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
parent
b92136f023
commit
2e76daec14
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2008-2009, Robin Rosenberg <robin.rosenberg@dewire.com>
|
* Copyright (C) 2008-2018, Robin Rosenberg <robin.rosenberg@dewire.com>
|
||||||
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
|
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
|
||||||
* and other copyright owners as documented in the project's IP log.
|
* and other copyright owners as documented in the project's IP log.
|
||||||
*
|
*
|
||||||
|
@ -53,6 +53,7 @@
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -75,13 +76,25 @@
|
||||||
*/
|
*/
|
||||||
public class PlotWalk extends RevWalk {
|
public class PlotWalk extends RevWalk {
|
||||||
|
|
||||||
|
private Map<AnyObjectId, Set<Ref>> additionalRefMap;
|
||||||
|
|
||||||
private Map<AnyObjectId, Set<Ref>> reverseRefMap;
|
private Map<AnyObjectId, Set<Ref>> reverseRefMap;
|
||||||
|
|
||||||
|
private Repository repository;
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
reverseRefMap.clear();
|
if (reverseRefMap != null) {
|
||||||
|
reverseRefMap.clear();
|
||||||
|
reverseRefMap = null;
|
||||||
|
}
|
||||||
|
if (additionalRefMap != null) {
|
||||||
|
additionalRefMap.clear();
|
||||||
|
additionalRefMap = null;
|
||||||
|
}
|
||||||
|
repository = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,7 +106,8 @@ public void dispose() {
|
||||||
public PlotWalk(Repository repo) {
|
public PlotWalk(Repository repo) {
|
||||||
super(repo);
|
super(repo);
|
||||||
super.sort(RevSort.TOPO, true);
|
super.sort(RevSort.TOPO, true);
|
||||||
reverseRefMap = repo.getAllRefsByPeeledObjectId();
|
additionalRefMap = new HashMap<>();
|
||||||
|
repository = repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,14 +119,14 @@ public PlotWalk(Repository repo) {
|
||||||
*/
|
*/
|
||||||
public void addAdditionalRefs(Iterable<Ref> refs) throws IOException {
|
public void addAdditionalRefs(Iterable<Ref> refs) throws IOException {
|
||||||
for (Ref ref : refs) {
|
for (Ref ref : refs) {
|
||||||
Set<Ref> set = reverseRefMap.get(ref.getObjectId());
|
Set<Ref> set = additionalRefMap.get(ref.getObjectId());
|
||||||
if (set == null)
|
if (set == null)
|
||||||
set = Collections.singleton(ref);
|
set = Collections.singleton(ref);
|
||||||
else {
|
else {
|
||||||
set = new HashSet<>(set);
|
set = new HashSet<>(set);
|
||||||
set.add(ref);
|
set.add(ref);
|
||||||
}
|
}
|
||||||
reverseRefMap.put(ref.getObjectId(), set);
|
additionalRefMap.put(ref.getObjectId(), set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,10 +155,28 @@ public RevCommit next() throws MissingObjectException,
|
||||||
}
|
}
|
||||||
|
|
||||||
private Ref[] getRefs(AnyObjectId commitId) {
|
private Ref[] getRefs(AnyObjectId commitId) {
|
||||||
|
if (reverseRefMap == null) {
|
||||||
|
reverseRefMap = repository.getAllRefsByPeeledObjectId();
|
||||||
|
for (Map.Entry<AnyObjectId, Set<Ref>> entry : additionalRefMap
|
||||||
|
.entrySet()) {
|
||||||
|
Set<Ref> set = reverseRefMap.get(entry.getKey());
|
||||||
|
Set<Ref> additional = entry.getValue();
|
||||||
|
if (set != null) {
|
||||||
|
if (additional.size() == 1) {
|
||||||
|
// It's an unmodifiable singleton set...
|
||||||
|
additional = new HashSet<>(additional);
|
||||||
|
}
|
||||||
|
additional.addAll(set);
|
||||||
|
}
|
||||||
|
reverseRefMap.put(entry.getKey(), additional);
|
||||||
|
}
|
||||||
|
additionalRefMap.clear();
|
||||||
|
additionalRefMap = null;
|
||||||
|
}
|
||||||
Collection<Ref> list = reverseRefMap.get(commitId);
|
Collection<Ref> list = reverseRefMap.get(commitId);
|
||||||
if (list == null)
|
if (list == null) {
|
||||||
return PlotCommit.NO_REFS;
|
return PlotCommit.NO_REFS;
|
||||||
else {
|
} else {
|
||||||
Ref[] tags = list.toArray(new Ref[list.size()]);
|
Ref[] tags = list.toArray(new Ref[list.size()]);
|
||||||
Arrays.sort(tags, new PlotRefComparator());
|
Arrays.sort(tags, new PlotRefComparator());
|
||||||
return tags;
|
return tags;
|
||||||
|
|
Loading…
Reference in New Issue