Improve performance of ReceiveCommits for repos with many refs

Commit 2fbea6c already improved performance of ReceiveCommits for repos
which have a lot of refs (>100000). In this case adding all existing
refs to RevWalk's as "uninteresting" caused performance problems. But
there was another place in ReceiveCommands where we added all existing
refs as uninteresting: in validateNewCommits(). This commit improves
the performance of this method in the same way as it was done in
2fbea6c.

Change-Id: I1ce6e4198daeabbcf5b8da61e6209b45672eb4be
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index 9f781a0..7d1a33a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -249,7 +249,6 @@
   private final Map<RevCommit, ReplaceRequest> replaceByCommit =
       new HashMap<RevCommit, ReplaceRequest>();
 
-  private Collection<ObjectId> existingObjects;
   private Map<ObjectId, Ref> refsById;
 
   private String destTopicName;
@@ -1116,22 +1115,7 @@
     try {
       Set<ObjectId> existing = Sets.newHashSet();
       walk.markStart(walk.parseCommit(newChange.getNewId()));
-      for (Ref ref : repo.getAllRefs().values()) {
-        if (ref.getObjectId() == null) {
-          continue;
-        } else if (ref.getName().startsWith("refs/changes/")) {
-          existing.add(ref.getObjectId());
-        } else if (ref.getName().startsWith(R_HEADS)
-            || ref.getName().equals(destBranchCtl.getRefName())) {
-          try {
-            walk.markUninteresting(walk.parseCommit(ref.getObjectId()));
-          } catch (IOException e) {
-            log.warn(String.format("Invalid ref %s in %s",
-                ref.getName(), project.getName()), e);
-            continue;
-          }
-        }
-      }
+      markHeadsAsUninteresting(walk, existing);
 
       List<ChangeLookup> pending = Lists.newArrayList();
       final Set<Change.Key> newChangeIds = new HashSet<Change.Key>();
@@ -1229,6 +1213,26 @@
     return newChanges;
   }
 
+
+  private void markHeadsAsUninteresting(final RevWalk walk, Set<ObjectId> existing) {
+    for (Ref ref : repo.getAllRefs().values()) {
+      if (ref.getObjectId() == null) {
+        continue;
+      } else if (ref.getName().startsWith("refs/changes/")) {
+        existing.add(ref.getObjectId());
+      } else if (ref.getName().startsWith(R_HEADS)
+          || (destBranchCtl != null && ref.getName().equals(destBranchCtl.getRefName()))) {
+        try {
+          walk.markUninteresting(walk.parseCommit(ref.getObjectId()));
+        } catch (IOException e) {
+          log.warn(String.format("Invalid ref %s in %s",
+              ref.getName(), project.getName()), e);
+          continue;
+        }
+      }
+    }
+  }
+
   private static boolean isValidChangeId(String idStr) {
     return idStr.matches("^I[0-9a-fA-F]{40}$") && !idStr.matches("^I00*$");
   }
@@ -1811,18 +1815,15 @@
     walk.reset();
     walk.sort(RevSort.NONE);
     try {
+      Set<ObjectId> existing = Sets.newHashSet();
       walk.markStart(walk.parseCommit(cmd.getNewId()));
-      for (ObjectId id : existingObjects()) {
-        try {
-          walk.markUninteresting(walk.parseCommit(id));
-        } catch (IOException e) {
-          continue;
-        }
-      }
+      markHeadsAsUninteresting(walk, existing);
 
       RevCommit c;
       while ((c = walk.next()) != null) {
-        if (!validCommit(ctl, cmd, c)) {
+        if (existing.contains(c)) {
+          continue;
+        } else if (!validCommit(ctl, cmd, c)) {
           break;
         }
       }
@@ -1832,17 +1833,6 @@
     }
   }
 
-  private Collection<ObjectId> existingObjects() {
-    if (existingObjects == null) {
-      Map<String, Ref> refs = repo.getAllRefs();
-      existingObjects = new ArrayList<ObjectId>(refs.size());
-      for (Ref r : refs.values()) {
-        existingObjects.add(r.getObjectId());
-      }
-    }
-    return existingObjects;
-  }
-
   private boolean validCommit(final RefControl ctl, final ReceiveCommand cmd,
       final RevCommit c) throws MissingObjectException, IOException {
     rp.getRevWalk().parseBody(c);