Merge branch 'stable-3.0' into stable-3.1

* stable-3.0:
  Cache repository locations in LocalDiskRepositoryManager

Release-Notes: skip
Change-Id: I5b6cd9e19c4a0b052da9705e0a8ddb0eced148c2
diff --git a/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java b/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java
index d42ed25..6ccb73c 100644
--- a/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java
+++ b/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java
@@ -33,8 +33,10 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Collections;
 import java.util.EnumSet;
+import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ConfigConstants;
@@ -108,6 +110,7 @@
   }
 
   private final Path basePath;
+  private final Map<Project.NameKey, FileKey> fileKeyByProject = new ConcurrentHashMap<>();
 
   @Inject
   LocalDiskRepositoryManager(SitePaths site, @GerritServerConfig Config cfg) {
@@ -129,17 +132,23 @@
 
   @Override
   public Repository openRepository(Project.NameKey name) throws RepositoryNotFoundException {
-    return openRepository(getBasePath(name), name);
-  }
+    FileKey cachedLocation = fileKeyByProject.get(name);
+    if (cachedLocation != null) {
+      try {
+        return RepositoryCache.open(cachedLocation);
+      } catch (IOException e) {
+        fileKeyByProject.remove(name, cachedLocation);
+      }
+    }
 
-  private Repository openRepository(Path path, Project.NameKey name)
-      throws RepositoryNotFoundException {
     if (isUnreasonableName(name)) {
       throw new RepositoryNotFoundException("Invalid name: " + name);
     }
-    FileKey loc = FileKey.lenient(path.resolve(name.get()).toFile(), FS.DETECTED);
+    FileKey location = FileKey.lenient(getBasePath(name).resolve(name.get()).toFile(), FS.DETECTED);
     try {
-      return RepositoryCache.open(loc);
+      Repository repo = RepositoryCache.open(location);
+      fileKeyByProject.put(name, location);
+      return repo;
     } catch (IOException e) {
       throw new RepositoryNotFoundException("Cannot open repository " + name, e);
     }