Merge "DfsBlockCache: use PackExtBlockCacheTable when configured"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java
index fef0563..3c7cc07 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java
@@ -13,20 +13,24 @@
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.time.Duration;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.LongStream;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.LongStream;
 
+import org.eclipse.jgit.internal.storage.dfs.DfsBlockCacheConfig.DfsBlockCachePackExtConfig;
 import org.eclipse.jgit.internal.storage.dfs.DfsBlockCacheConfig.IndexEventConsumer;
 import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.junit.TestRepository;
@@ -39,14 +43,35 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
+@RunWith(Parameterized.class)
 public class DfsBlockCacheTest {
 	@Rule
 	public TestName testName = new TestName();
+
 	private TestRng rng;
+
 	private DfsBlockCache cache;
+
 	private ExecutorService pool;
 
+	private enum CacheType {
+		SINGLE_TABLE_CLOCK_BLOCK_CACHE, EXT_SPLIT_TABLE_CLOCK_BLOCK_CACHE
+	}
+
+	@Parameters(name = "cache type: {0}")
+	public static Iterable<? extends Object> data() {
+		return Arrays.asList(CacheType.SINGLE_TABLE_CLOCK_BLOCK_CACHE,
+				CacheType.EXT_SPLIT_TABLE_CLOCK_BLOCK_CACHE);
+	}
+
+	@Parameter
+	public CacheType cacheType;
+
 	@Before
 	public void setUp() {
 		rng = new TestRng(testName.getMethodName());
@@ -448,8 +473,28 @@ private void resetCache() {
 	}
 
 	private void resetCache(int concurrencyLevel) {
-		DfsBlockCache.reconfigure(new DfsBlockCacheConfig().setBlockSize(512)
-				.setConcurrencyLevel(concurrencyLevel).setBlockLimit(1 << 20));
+		DfsBlockCacheConfig cacheConfig = new DfsBlockCacheConfig()
+				.setBlockSize(512).setConcurrencyLevel(concurrencyLevel)
+				.setBlockLimit(1 << 20);
+		switch (cacheType) {
+		case SINGLE_TABLE_CLOCK_BLOCK_CACHE:
+			// SINGLE_TABLE_CLOCK_BLOCK_CACHE doesn't modify the config.
+			break;
+		case EXT_SPLIT_TABLE_CLOCK_BLOCK_CACHE:
+			List<DfsBlockCachePackExtConfig> packExtCacheConfigs = new ArrayList<>();
+			for (PackExt packExt : PackExt.values()) {
+				DfsBlockCacheConfig extCacheConfig = new DfsBlockCacheConfig()
+						.setBlockSize(512).setConcurrencyLevel(concurrencyLevel)
+						.setBlockLimit(1 << 20)
+						.setPackExtCacheConfigurations(packExtCacheConfigs);
+				packExtCacheConfigs.add(new DfsBlockCachePackExtConfig(
+						EnumSet.of(packExt), extCacheConfig));
+			}
+			cacheConfig.setPackExtCacheConfigurations(packExtCacheConfigs);
+			break;
+		}
+		assertNotNull(cacheConfig);
+		DfsBlockCache.reconfigure(cacheConfig);
 		cache = DfsBlockCache.getInstance();
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
index 3e1300c..0334450 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
@@ -97,7 +97,12 @@ private DfsBlockCache(DfsBlockCacheConfig cfg) {
 		double streamRatio = cfg.getStreamRatio();
 		maxStreamThroughCache = (long) (maxBytes * streamRatio);
 
-		dfsBlockCacheTable = new ClockBlockCacheTable(cfg);
+		if (!cfg.getPackExtCacheConfigurations().isEmpty()) {
+			dfsBlockCacheTable = PackExtBlockCacheTable
+					.fromBlockCacheConfigs(cfg);
+		} else {
+			dfsBlockCacheTable = new ClockBlockCacheTable(cfg);
+		}
 
 		for (int i = 0; i < PackExt.values().length; ++i) {
 			Integer limit = cfg.getCacheHotMap().get(PackExt.values()[i]);
@@ -158,8 +163,7 @@ public long getFillPercentage() {
 	 * @return total number of requests (hit + miss), per pack file extension.
 	 */
 	public long[] getTotalRequestCount() {
-		return dfsBlockCacheTable.getBlockCacheStats()
-				.getTotalRequestCount();
+		return dfsBlockCacheTable.getBlockCacheStats().getTotalRequestCount();
 	}
 
 	/**