CommitsCollection: Avoid Repository#getAllRefs

Some upstream methods can also make use of better RefDatabase APIs.

Change-Id: If84f61abf6a8117908b496520545a8a6511b7be4
diff --git a/java/com/google/gerrit/server/permissions/PermissionBackend.java b/java/com/google/gerrit/server/permissions/PermissionBackend.java
index e6fe3a5..f0f7f42 100644
--- a/java/com/google/gerrit/server/permissions/PermissionBackend.java
+++ b/java/com/google/gerrit/server/permissions/PermissionBackend.java
@@ -15,6 +15,7 @@
 package com.google.gerrit.server.permissions;
 
 import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.toMap;
 import static java.util.stream.Collectors.toSet;
 
 import com.google.auto.value.AutoValue;
@@ -334,6 +335,21 @@
     public abstract Map<String, Ref> filter(
         Map<String, Ref> refs, Repository repo, RefFilterOptions opts)
         throws PermissionBackendException;
+
+    /**
+     * Filter a list of references by visibility.
+     *
+     * @param refs a list of references to filter.
+     * @param repo an open {@link Repository} handle for this instance's project
+     * @param opts further options for filtering.
+     * @return a partition of the provided refs that are visible to the user that this instance is
+     *     scoped to.
+     * @throws PermissionBackendException if failure consulting backend configuration.
+     */
+    public Map<String, Ref> filter(List<Ref> refs, Repository repo, RefFilterOptions opts)
+        throws PermissionBackendException {
+      return filter(refs.stream().collect(toMap(Ref::getName, r -> r)), repo, opts);
+    }
   }
 
   /** Options for filtering refs using {@link ForProject}. */
diff --git a/java/com/google/gerrit/server/project/Reachable.java b/java/com/google/gerrit/server/project/Reachable.java
index 63fda19..76ee8c9 100644
--- a/java/com/google/gerrit/server/project/Reachable.java
+++ b/java/com/google/gerrit/server/project/Reachable.java
@@ -14,10 +14,9 @@
 
 package com.google.gerrit.server.project;
 
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.Project.NameKey;
 import com.google.gerrit.server.change.IncludedInResolver;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
@@ -25,11 +24,10 @@
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
-import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
@@ -50,8 +48,7 @@
   }
 
   /** @return true if a commit is reachable from a given set of refs. */
-  public boolean fromRefs(
-      Project.NameKey project, Repository repo, RevCommit commit, Map<String, Ref> refs) {
+  public boolean fromRefs(NameKey project, Repository repo, RevCommit commit, List<Ref> refs) {
     try (RevWalk rw = new RevWalk(repo)) {
       Map<String, Ref> filtered =
           permissionBackend
@@ -69,13 +66,7 @@
   /** @return true if a commit is reachable from a repo's branches and tags. */
   boolean fromHeadsOrTags(Project.NameKey project, Repository repo, RevCommit commit) {
     try {
-      RefDatabase refdb = repo.getRefDatabase();
-      Collection<Ref> heads = refdb.getRefsByPrefix(Constants.R_HEADS);
-      Collection<Ref> tags = refdb.getRefsByPrefix(Constants.R_TAGS);
-      Map<String, Ref> refs = Maps.newHashMapWithExpectedSize(heads.size() + tags.size());
-      for (Ref r : Iterables.concat(heads, tags)) {
-        refs.put(r.getName(), r);
-      }
+      List<Ref> refs = repo.getRefDatabase().getRefsByPrefix(Constants.R_HEADS, Constants.R_TAGS);
       return fromRefs(project, repo, commit, refs);
     } catch (IOException e) {
       logger.atSevere().withCause(e).log(
diff --git a/java/com/google/gerrit/server/restapi/project/CommitsCollection.java b/java/com/google/gerrit/server/restapi/project/CommitsCollection.java
index 15cd824..63dcf5c 100644
--- a/java/com/google/gerrit/server/restapi/project/CommitsCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/CommitsCollection.java
@@ -105,7 +105,7 @@
   }
 
   /** @return true if {@code commit} is visible to the caller. */
-  public boolean canRead(ProjectState state, Repository repo, RevCommit commit) {
+  public boolean canRead(ProjectState state, Repository repo, RevCommit commit) throws IOException {
     Project.NameKey project = state.getNameKey();
 
     // Look for changes associated with the commit.
@@ -122,6 +122,6 @@
       }
     }
 
-    return reachable.fromRefs(project, repo, commit, repo.getAllRefs());
+    return reachable.fromRefs(project, repo, commit, repo.getRefDatabase().getRefs());
   }
 }