package com.ctriposs.bigcache; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import com.ctriposs.bigcache.CacheConfig.StorageMode; import com.ctriposs.bigcache.utils.FileUtil; import com.ctriposs.bigcache.utils.TestSample; import com.ctriposs.bigcache.utils.TestUtil; @RunWith(Parameterized.class) public class BigCachePerfTestA { private static final int THREAD_COUNT = 128; private static final String TEST_DIR = TestUtil.TEST_BASE_DIR + "performance/bigcache/"; private static BigCache<String> cache; @Parameter(value = 0) public StorageMode storageMode; @Parameters public static Collection<StorageMode[]> data() throws IOException { StorageMode[][] data = { { StorageMode.PureFile }, { StorageMode.MemoryMappedPlusFile }, { StorageMode.OffHeapPlusFile } }; return Arrays.asList(data); } private BigCache<String> cache() throws IOException { CacheConfig config = new CacheConfig(); config.setStorageMode(storageMode) .setCapacityPerBlock(20 * 1024 * 1024) .setMergeInterval(2 * 1000) .setPurgeInterval(2 * 1000); BigCache<String> cache = new BigCache<String>(TEST_DIR, config); return cache; } @Test public void testSingleThreadReadWrite() throws IOException, ClassNotFoundException { final int count = 400 * 1000; final TestSample sample = new TestSample(); cache = cache(); long start = System.nanoTime(); StringBuilder user = new StringBuilder(); for (int i = 0; i < count; i++) { sample.intA = i; sample.doubleA = i; sample.longA = i; cache.put(TestSample.users(user, i), sample.toBytes()); } for (int i = 0; i < count; i++) { byte[] result = cache.get(TestSample.users(user, i)); assertNotNull(result); } for (int i = 0; i < count; i++) { byte[] result = cache.get(TestSample.users(user, i)); TestSample re = TestSample.fromBytes(result); assertEquals(i, re.intA); assertEquals(i, re.doubleA, 0.0); assertEquals(i, re.longA); } for (int i = 0; i < count; i++) { cache.delete(TestSample.users(user, i)); } assertEquals(cache.count(), 0); long duration = System.nanoTime() - start; System.out.printf("Put/get %,d K operations per second%n", (int) (count * 4 * 1e6 / duration)); } @Test public void testMultiThreadReadWrite() throws InterruptedException, ExecutionException, IOException { final int count = 2 * 1000 * 1000; ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); cache = cache(); long start = System.nanoTime(); List<Future<?>> futures = new ArrayList<Future<?>>(); for (int i = 0; i < THREAD_COUNT; i++) { final int finalI = i; futures.add(service.submit(new Runnable() { @Override public void run() { try { final TestSample sample = new TestSample(); StringBuilder user = new StringBuilder(); for (int j = finalI; j < count; j += THREAD_COUNT) { sample.intA = j; sample.doubleA = j; sample.longA = j; cache.put(TestSample.users(user, j), sample.toBytes()); } for (int j = finalI; j < count; j += THREAD_COUNT) { byte[] result = cache.get(TestSample.users(user, j)); assertNotNull(result); } for (int j = finalI; j < count; j += THREAD_COUNT) { byte[] result = cache.get(TestSample.users(user, j)); TestSample re = TestSample.fromBytes(result); assertEquals(j, re.intA); assertEquals(j, re.doubleA, 0.0); assertEquals(j, re.longA); } for (int j = finalI; j < count; j += THREAD_COUNT) { cache.delete(TestSample.users(user, j)); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } } })); } for (Future<?> future : futures) { future.get(); } long duration = System.nanoTime() - start; System.out.printf("Put/get %,d K operations per second%n", (int) (count * 4 * 1e6 / duration)); service.shutdown(); } @After public void close() throws IOException { try { cache.close(); FileUtil.deleteDirectory(new File(TEST_DIR)); } catch (IllegalStateException e) { System.gc(); try { FileUtil.deleteDirectory(new File(TEST_DIR)); } catch (IllegalStateException e1) { try { Thread.sleep(3000); } catch (InterruptedException e2) { } FileUtil.deleteDirectory(new File(TEST_DIR)); } } } }