Merge branch 'stable-3.3' into stable-3.4

* stable-3.3:
  DRY out common functions between servlets
  DRY out listing of tuned files in AutoAdjustCachesIT
  Expose auto-adjust-cache command as Servlet
  Skip unnecessary auto-adjustments of caches
  Give more patience for cache to load in tests
  Remove empty char at EOL in docs
  Fix auto-adjust-caches example CLI in docs
  Use all-caps for static final strings in test

Also increase the acceptance tests' heap size to 2G
to allow enouch memory to run the Gerrit-based
acceptance tests for cache conversion and tuning.

Change-Id: Iea5144726908ef051f66ae06ec59c08cfe5a2efa
diff --git a/BUILD b/BUILD
index 612cb3d..85222ca 100644
--- a/BUILD
+++ b/BUILD
@@ -51,6 +51,7 @@
     srcs = glob(["src/test/java/**/*IT.java"]),
     group = "server_cache",
     labels = ["server"],
+    vm_args = ["-Xmx2G"],
     deps = [
         ":cache-chroniclemap__plugin",
         ":chroniclemap-test-lib",
diff --git a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheFactory.java b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheFactory.java
index 33fdd1b..088798b 100644
--- a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheFactory.java
+++ b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheFactory.java
@@ -16,15 +16,14 @@
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import com.google.common.flogger.FluentLogger;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.metrics.MetricMaker;
 import com.google.gerrit.server.cache.CacheBackend;
 import com.google.gerrit.server.cache.MemoryCacheFactory;
+import com.google.gerrit.server.cache.PersistentCacheBaseFactory;
 import com.google.gerrit.server.cache.PersistentCacheDef;
-import com.google.gerrit.server.cache.PersistentCacheFactory;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.logging.LoggingContextAwareScheduledExecutorService;
@@ -34,7 +33,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.UncheckedIOException;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.LinkedList;
 import java.util.List;
@@ -45,17 +43,12 @@
 import org.eclipse.jgit.lib.Config;
 
 @Singleton
-class ChronicleMapCacheFactory implements PersistentCacheFactory, LifecycleListener {
-  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
-  private final MemoryCacheFactory memCacheFactory;
-  private final Config config;
+class ChronicleMapCacheFactory extends PersistentCacheBaseFactory implements LifecycleListener {
   private final ChronicleMapCacheConfig.Factory configFactory;
   private final MetricMaker metricMaker;
   private final DynamicMap<Cache<?, ?>> cacheMap;
   private final List<ChronicleMapCacheImpl<?, ?>> caches;
   private final ScheduledExecutorService cleanup;
-  private final Path cacheDir;
 
   @Inject
   ChronicleMapCacheFactory(
@@ -65,12 +58,10 @@
       ChronicleMapCacheConfig.Factory configFactory,
       DynamicMap<Cache<?, ?>> cacheMap,
       MetricMaker metricMaker) {
-    this.memCacheFactory = memCacheFactory;
-    this.config = cfg;
+    super(memCacheFactory, cfg, site);
     this.configFactory = configFactory;
     this.metricMaker = metricMaker;
     this.caches = new LinkedList<>();
-    this.cacheDir = getCacheDir(site, cfg.getString("cache", null, "directory"));
     this.cacheMap = cacheMap;
     this.cleanup =
         new LoggingContextAwareScheduledExecutorService(
@@ -83,10 +74,8 @@
   }
 
   @Override
-  public <K, V> Cache<K, V> build(PersistentCacheDef<K, V> in, CacheBackend backend) {
-    if (isInMemoryCache(in)) {
-      return memCacheFactory.build(in, backend);
-    }
+  public <K, V> Cache<K, V> buildImpl(
+      PersistentCacheDef<K, V> in, long limit, CacheBackend backend) {
     ChronicleMapCacheConfig config =
         configFactory.create(
             in.configKey(),
@@ -106,11 +95,8 @@
   }
 
   @Override
-  public <K, V> LoadingCache<K, V> build(
-      PersistentCacheDef<K, V> in, CacheLoader<K, V> loader, CacheBackend backend) {
-    if (isInMemoryCache(in)) {
-      return memCacheFactory.build(in, loader, backend);
-    }
+  public <K, V> LoadingCache<K, V> buildImpl(
+      PersistentCacheDef<K, V> in, CacheLoader<K, V> loader, long limit, CacheBackend backend) {
     ChronicleMapCacheConfig config =
         configFactory.create(
             in.configKey(),
@@ -141,11 +127,6 @@
     }
   }
 
-  private <K, V> boolean isInMemoryCache(PersistentCacheDef<K, V> in) {
-    return cacheDir == null
-        || config.getLong("cache", in.configKey(), "diskLimit", in.diskLimit()) <= 0;
-  }
-
   @Override
   public void start() {
     for (ChronicleMapCacheImpl<?, ?> cache : caches) {
@@ -163,23 +144,6 @@
   }
 
   protected static Path getCacheDir(SitePaths site, String name) {
-    if (name == null) {
-      return null;
-    }
-    Path loc = site.resolve(name);
-    if (!Files.exists(loc)) {
-      try {
-        Files.createDirectories(loc);
-      } catch (IOException e) {
-        logger.atWarning().log("Can't create disk cache: %s", loc.toAbsolutePath());
-        return null;
-      }
-    }
-    if (!Files.isWritable(loc)) {
-      logger.atWarning().log("Can't write to disk cache: %s", loc.toAbsolutePath());
-      return null;
-    }
-    logger.atInfo().log("Enabling disk cache %s", loc.toAbsolutePath());
-    return loc;
+    return site.resolve(name);
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2CachesIT.java b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2CachesIT.java
index 15140b8..482b9da 100644
--- a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2CachesIT.java
+++ b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2CachesIT.java
@@ -49,7 +49,6 @@
     String result = adminSshSession.exec(cmd);
 
     adminSshSession.assertSuccess();
-    assertThat(result).contains("[cache \"mergeability\"]\n" + "\tmaxEntries = 1\n");
     assertThat(result).contains("[cache \"diff\"]\n" + "\tmaxEntries = 1\n");
     assertThat(result).contains("[cache \"accounts\"]\n" + "\tmaxEntries = 4\n");
     assertThat(result).contains("[cache \"diff_summary\"]\n" + "\tmaxEntries = 1\n");
@@ -70,7 +69,6 @@
             "WARN: Cache change_kind is empty, skipping.",
             "WARN: Cache diff_summary is empty, skipping.",
             "WARN: Cache diff is empty, skipping.",
-            "WARN: Cache mergeability is empty, skipping.",
             "WARN: Cache pure_revert is empty, skipping.",
             "WARN: Cache git_tags is empty, skipping.");
     String result = adminSshSession.exec(cmd);
@@ -90,7 +88,6 @@
             "WARN: Cache change_kind is empty, skipping.",
             "WARN: Cache diff_summary is empty, skipping.",
             "WARN: Cache diff is empty, skipping.",
-            "WARN: Cache mergeability is empty, skipping.",
             "WARN: Cache pure_revert is empty, skipping.",
             "WARN: Cache git_tags is empty, skipping.");
     String result = adminSshSession.exec(cmd);
diff --git a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AutoAdjustCachesIT.java b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AutoAdjustCachesIT.java
index 8fad5ed..57b0e46 100644
--- a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AutoAdjustCachesIT.java
+++ b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/AutoAdjustCachesIT.java
@@ -58,7 +58,7 @@
 public class AutoAdjustCachesIT extends LightweightPluginDaemonTest {
   private static final String SSH_CMD = "cache-chroniclemap auto-adjust-caches";
   private static final String REST_CMD = "/plugins/cache-chroniclemap/auto-adjust-caches";
-  private static final String MERGEABILITY = "mergeability";
+  private static final String GROUPS_BYUUID_PERSISTED = "groups_byuuid_persisted";
   private static final String DIFF = "diff";
   private static final String DIFF_SUMMARY = "diff_summary";
   private static final String ACCOUNTS = "accounts";
@@ -71,7 +71,7 @@
   private static final Function<String, Boolean> MATCH_ALL = (n) -> true;
 
   private static final ImmutableList<String> EXPECTED_CACHES =
-      ImmutableList.of(MERGEABILITY, DIFF, DIFF_SUMMARY, ACCOUNTS, PERSISTED_PROJECTS);
+      ImmutableList.of(GROUPS_BYUUID_PERSISTED, DIFF, DIFF_SUMMARY, ACCOUNTS, PERSISTED_PROJECTS);
 
   @Inject private SitePaths sitePaths;