Default core.streamFileThreshold to a larger value

If this value is not configured by the server administrator
performance on larger text files suffers considerably and
Gerrit may grind to a halt and be unable to answer users.

Default to either 25% of the available JVM heap or ~2048m.

Change-Id: Ib428fea3eb126d4ce13c73a5af493f9a86763ac8
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java
index e5b34b7..1ca74b1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java
@@ -77,11 +77,11 @@
   }
 
   public static class Lifecycle implements LifecycleListener {
-    private final Config cfg;
+    private final Config serverConfig;
 
     @Inject
     Lifecycle(@GerritServerConfig final Config cfg) {
-      this.cfg = cfg;
+      this.serverConfig = cfg;
     }
 
     @Override
@@ -94,7 +94,35 @@
           // Default configuration is batch mode.
         }
       });
-      new WindowCacheConfig().fromConfig(cfg).install();
+
+      WindowCacheConfig cfg = new WindowCacheConfig();
+      cfg.fromConfig(serverConfig);
+      if (serverConfig.getString("core", null, "streamFileThreshold") == null) {
+        long mx = Runtime.getRuntime().maxMemory();
+        int limit = (int) Math.min(
+            mx / 4, // don't use more than 1/4 of the heap.
+            2047 << 20); // cannot exceed array length
+        if ((5 << 20) < limit && limit % (1 << 20) != 0) {
+          // If the limit is at least 5 MiB but is not a whole multiple
+          // of MiB round up to the next one full megabyte. This is a very
+          // tiny memory increase in exchange for nice round units.
+          limit = ((limit / (1 << 20)) + 1) << 20;
+        }
+
+        String desc;
+        if (limit % (1 << 20) == 0) {
+          desc = String.format("%dm", limit / (1 << 20));
+        } else if (limit % (1 << 10) == 0) {
+          desc = String.format("%dk", limit / (1 << 10));
+        } else {
+          desc = String.format("%d", limit);
+        }
+        log.info(String.format(
+            "Defaulting core.streamFileThreshold to %s",
+            desc));
+        cfg.setStreamFileThreshold(limit);
+      }
+      cfg.install();
     }
 
     @Override