Build both refsById and refsByChange at the same time

Instead of iterating one table from the other, build both at the same
time.  This reduces the constant factor for the table construction
algorithms slightly by avoiding traversal through the Multimap
internal structure just to make the second index of refsById.

Most processing paths that use one table will also use the other
table.  For example pushing to refs/for/master needs refsById to skip
known commits and then refsByChange to process replacement requests.

Change-Id: Ic3f71ec47cad5151456b1558f6095b87cd5d1776
This commit is contained in:
Shawn Pearce
2014-10-17 15:08:41 -07:00
parent 2ffd2cb83f
commit b1417e573b

View File

@@ -2179,24 +2179,36 @@ public class ReceiveCommits {
return refsByChange().get(changeId);
}
private ListMultimap<Change.Id, Ref> refsByChange() {
private void initChangeRefMaps() {
if (refsByChange == null) {
int estRefsPerChange = 4;
refsById = HashMultimap.create();
refsByChange = ArrayListMultimap.create(
allRefs.size() / estRefsPerChange,
estRefsPerChange);
for (Ref ref : allRefs.values()) {
if (ref.getObjectId() != null) {
ObjectId obj = ref.getObjectId();
if (obj != null) {
PatchSet.Id psId = PatchSet.Id.fromRef(ref.getName());
if (psId != null) {
refsById.put(obj, ref);
refsByChange.put(psId.getParentKey(), ref);
}
}
}
}
}
private ListMultimap<Change.Id, Ref> refsByChange() {
initChangeRefMaps();
return refsByChange;
}
private SetMultimap<ObjectId, Ref> changeRefsById() {
initChangeRefMaps();
return refsById;
}
static boolean parentsEqual(RevCommit a, RevCommit b) {
if (a.getParentCount() != b.getParentCount()) {
return false;
@@ -2444,16 +2456,6 @@ public class ReceiveCommits {
return change.getKey();
}
private SetMultimap<ObjectId, Ref> changeRefsById() {
if (refsById == null) {
refsById = HashMultimap.create();
for (Ref r : refsByChange().values()) {
refsById.put(r.getObjectId(), r);
}
}
return refsById;
}
private Map<Change.Key, Change> openChangesByKey(Branch.NameKey branch)
throws OrmException {
final Map<Change.Key, Change> r = new HashMap<>();