Merge "Provide SSH command to analyze H2 caches" into stable-3.3
diff --git a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfig.java b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfig.java
index f3f59cf..071bada 100644
--- a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfig.java
+++ b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfig.java
@@ -42,6 +42,7 @@
private final Duration expireAfterWrite;
private final Duration refreshAfterWrite;
private final int maxBloatFactor;
+ private final int version;
public interface Factory {
ChronicleMapCacheConfig create(
@@ -49,7 +50,8 @@
@Assisted("ConfigKey") String configKey,
@Assisted("DiskLimit") long diskLimit,
@Nullable @Assisted("ExpireAfterWrite") Duration expireAfterWrite,
- @Nullable @Assisted("RefreshAfterWrite") Duration refreshAfterWrite);
+ @Nullable @Assisted("RefreshAfterWrite") Duration refreshAfterWrite,
+ int version);
}
@AssistedInject
@@ -60,11 +62,15 @@
@Assisted("ConfigKey") String configKey,
@Assisted("DiskLimit") long diskLimit,
@Nullable @Assisted("ExpireAfterWrite") Duration expireAfterWrite,
- @Nullable @Assisted("RefreshAfterWrite") Duration refreshAfterWrite)
+ @Nullable @Assisted("RefreshAfterWrite") Duration refreshAfterWrite,
+ @Assisted int version)
throws IOException {
+ this.version = version;
final Path cacheDir = getCacheDir(site, cfg.getString("cache", null, "directory"));
this.persistedFile =
- cacheDir != null ? cacheDir.resolve(String.format("%s.dat", name)).toFile() : null;
+ cacheDir != null
+ ? cacheDir.resolve(String.format("%s_%s.dat", name, version)).toFile()
+ : null;
this.diskLimit = cfg.getLong("cache", configKey, "diskLimit", diskLimit);
this.maxEntries =
@@ -91,6 +97,10 @@
cfg.getInt("cache", configKey, "maxBloatFactor", Defaults.maxBloatFactorFor(configKey));
}
+ public int getVersion() {
+ return version;
+ }
+
public Duration getExpireAfterWrite() {
return expireAfterWrite;
}
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 929c1c6..bf5ca56 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
@@ -70,7 +70,8 @@
in.configKey(),
in.diskLimit(),
in.expireAfterWrite(),
- in.refreshAfterWrite());
+ in.refreshAfterWrite(),
+ in.version());
ChronicleMapCacheImpl<K, V> cache = null;
try {
cache = new ChronicleMapCacheImpl<>(in, config, null);
@@ -93,7 +94,8 @@
in.configKey(),
in.diskLimit(),
in.expireAfterWrite(),
- in.refreshAfterWrite());
+ in.refreshAfterWrite(),
+ in.version());
ChronicleMapCacheImpl<K, V> cache = null;
try {
cache = new ChronicleMapCacheImpl<>(in, config, loader);
diff --git a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java
index 59f9f5a..c03b1ac 100644
--- a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java
+++ b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java
@@ -85,10 +85,11 @@
}
logger.atInfo().log(
- "Initialized '%s'|avgKeySize: %s bytes|avgValueSize: %s bytes|"
- + "entries: %s|maxBloatFactor: %s|remainingAutoResizes: %s|"
- + "percentageFreeSpace: %s",
+ "Initialized '%s'|version: %s|avgKeySize: %s bytes|avgValueSize:"
+ + " %s bytes|entries: %s|maxBloatFactor: %s|remainingAutoResizes:"
+ + " %s|percentageFreeSpace: %s",
def.name(),
+ config.getVersion(),
mapBuilder.constantlySizedKeys() ? "CONSTANT" : config.getAverageKeySize(),
config.getAverageValueSize(),
config.getMaxEntries(),
diff --git a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfigTest.java b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfigTest.java
index 735d23b..febff2f 100644
--- a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheConfigTest.java
@@ -38,6 +38,7 @@
private final String cacheName = "foobar-cache";
private final String cacheKey = "foobar-cache-key";
private final long definitionDiskLimit = 100;
+ private final int version = 1;
private final Duration expireAfterWrite = Duration.ofSeconds(10_000);
private final Duration refreshAfterWrite = Duration.ofSeconds(20_000);
@@ -204,6 +205,7 @@
cacheKey,
definitionDiskLimit,
expireAfterWrite,
- refreshAfterWrite);
+ refreshAfterWrite,
+ version);
}
}
diff --git a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java
index 6abf49d..bf0317d 100644
--- a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java
+++ b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java
@@ -60,6 +60,19 @@
}
@Test
+ public void getIfPresentShouldReturnNullWhenThereCacheHasADifferentVersion() throws Exception {
+ gerritConfig.setString("cache", null, "directory", "cache");
+ gerritConfig.save();
+ final ChronicleMapCacheImpl<String, String> cacheV1 = newCacheVersion(1);
+
+ cacheV1.put("foo", "value version 1");
+ cacheV1.close();
+
+ final ChronicleMapCacheImpl<String, String> cacheV2 = newCacheVersion(2);
+ assertThat(cacheV2.getIfPresent("foo")).isNull();
+ }
+
+ @Test
public void getWithLoaderShouldPopulateTheCache() throws Exception {
String cachedValue = UUID.randomUUID().toString();
final ChronicleMapCacheImpl<String, String> cache = newCacheWithLoader();
@@ -77,6 +90,38 @@
}
@Test
+ public void getShouldRetrieveANewValueWhenCacheHasADifferentVersion() throws Exception {
+ gerritConfig.setString("cache", null, "directory", "cache");
+ gerritConfig.save();
+ final ChronicleMapCacheImpl<String, String> cacheV1 = newCacheVersion(1);
+
+ cacheV1.put("foo", "value version 1");
+ cacheV1.close();
+
+ final ChronicleMapCacheImpl<String, String> cacheV2 = newCacheVersion(2);
+
+ final String v2Value = "value version 2";
+ assertThat(cacheV2.get("foo", () -> v2Value)).isEqualTo(v2Value);
+ }
+
+ @Test
+ public void getShouldRetrieveCachedValueWhenCacheHasSameVersion() throws Exception {
+ int cacheVersion = 2;
+ gerritConfig.setString("cache", null, "directory", "cache");
+ gerritConfig.save();
+ final ChronicleMapCacheImpl<String, String> cache = newCacheVersion(cacheVersion);
+
+ final String originalValue = "value 1";
+ cache.put("foo", originalValue);
+ cache.close();
+
+ final ChronicleMapCacheImpl<String, String> newCache = newCacheVersion(cacheVersion);
+
+ final String newValue = "value 2";
+ assertThat(newCache.get("foo", () -> newValue)).isEqualTo(originalValue);
+ }
+
+ @Test
public void getShoudThrowWhenNoLoaderHasBeenProvided() throws Exception {
final ChronicleMapCacheImpl<String, String> cache = newCacheWithoutLoader();
@@ -164,7 +209,8 @@
@Test
public void getIfPresentShouldReturnNullWhenValueIsExpired() throws Exception {
- ChronicleMapCacheImpl<String, String> cache = newCache(true, null, Duration.ofSeconds(1), null);
+ ChronicleMapCacheImpl<String, String> cache =
+ newCache(true, null, Duration.ofSeconds(1), null, 1);
cache.put("foo", "some-stale-value");
Thread.sleep(1010); // Allow cache entry to expire
assertThat(cache.getIfPresent("foo")).isNull();
@@ -174,7 +220,7 @@
public void getShouldRefreshValueWhenExpired() throws Exception {
String newCachedValue = UUID.randomUUID().toString();
ChronicleMapCacheImpl<String, String> cache =
- newCache(true, newCachedValue, null, Duration.ofSeconds(1));
+ newCache(true, newCachedValue, null, Duration.ofSeconds(1), 1);
cache.put("foo", "some-stale-value");
Thread.sleep(1010); // Allow cache to be flagged as needing refresh
assertThat(cache.get("foo")).isEqualTo(newCachedValue);
@@ -182,7 +228,8 @@
@Test
public void shouldPruneExpiredValues() throws Exception {
- ChronicleMapCacheImpl<String, String> cache = newCache(true, null, Duration.ofSeconds(1), null);
+ ChronicleMapCacheImpl<String, String> cache =
+ newCache(true, null, Duration.ofSeconds(1), null, 1);
cache.put("foo1", "some-stale-value1");
cache.put("foo2", "some-stale-value1");
Thread.sleep(1010); // Allow cache entries to expire
@@ -219,7 +266,8 @@
Boolean withLoader,
@Nullable String cachedValue,
@Nullable Duration expireAfterWrite,
- @Nullable Duration refreshAfterWrite)
+ @Nullable Duration refreshAfterWrite,
+ Integer version)
throws IOException {
TestPersistentCacheDef cacheDef = new TestPersistentCacheDef(cachedValue);
@@ -231,22 +279,27 @@
cacheDef.configKey(),
cacheDef.diskLimit(),
expireAfterWrite != null ? expireAfterWrite : Duration.ZERO,
- refreshAfterWrite != null ? refreshAfterWrite : Duration.ZERO);
+ refreshAfterWrite != null ? refreshAfterWrite : Duration.ZERO,
+ version);
return new ChronicleMapCacheImpl<>(cacheDef, config, withLoader ? cacheDef.loader() : null);
}
private ChronicleMapCacheImpl<String, String> newCacheWithLoader(@Nullable String cachedValue)
throws IOException {
- return newCache(true, cachedValue, null, null);
+ return newCache(true, cachedValue, null, null, 1);
}
private ChronicleMapCacheImpl<String, String> newCacheWithLoader() throws IOException {
- return newCache(true, null, null, null);
+ return newCache(true, null, null, null, 1);
+ }
+
+ private ChronicleMapCacheImpl<String, String> newCacheVersion(int version) throws IOException {
+ return newCache(true, null, null, null, version);
}
private ChronicleMapCacheImpl<String, String> newCacheWithoutLoader() throws IOException {
- return newCache(false, null, null, null);
+ return newCache(false, null, null, null, 1);
}
public static class TestPersistentCacheDef implements PersistentCacheDef<String, String> {