Skip to content

Instantly share code, notes, and snippets.

@rrevol
Created February 10, 2016 14:18
Show Gist options
  • Save rrevol/8ab557eeb3b9f1185256 to your computer and use it in GitHub Desktop.
Save rrevol/8ab557eeb3b9f1185256 to your computer and use it in GitHub Desktop.
Test of guava cache stats coherency
import java.util.*;
import java.util.concurrent.*;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheStats;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.propagate;
import static java.util.concurrent.Executors.*;
public class CacheTest {
private static final int NUMBER_OF_CACHE_GET = 100;
private static final int THREAD_POOL_SIZE = 6;
private CacheTest() {
}
/**
* Performs NUMBER_OF_CACHE_GET for the same key on a cache then verifies that cache stats are coherent
*/
public static void main(String[] args) {
for (int j = 0; j < 200000; j++) { // several runs may be necessary to reproduce the pb
final Object key = new Object();
final Object value = new Object();
final Callable<Object> valueLoader = new Callable<Object>() {
@Override
public Object call() throws Exception {
return value;
}
};
final Cache<Object, Object> cache = CacheBuilder.newBuilder().maximumSize(100).recordStats().build();
try {
ExecutorService pool = newFixedThreadPool(THREAD_POOL_SIZE);
final Collection<Callable<Void>> executions = new ArrayList<>();
for (int i = 0; i < NUMBER_OF_CACHE_GET; i++) {
executions.add(new Callable<Void>() {
@Override
public Void call() throws Exception {
cache.get(key, valueLoader);
return null;
}
});
}
List<Future<Void>> futures = pool.invokeAll(executions);
try {
for (Future<Void> future : futures) {
try {
future.get();
} catch (Exception e) {
throw propagate(e.getCause());
}
}
CacheStats stats = cache.stats();
/* OK */
checkState(stats.loadCount() == 1, "Unexpected load count : %s", stats.loadCount());
/* OK */
checkState(stats.evictionCount() == 0, "Unexpected eviction count : %s > 0", stats.evictionCount());
/* OK */
checkState(stats.hitCount() == (NUMBER_OF_CACHE_GET - stats.missCount()), // since eviction count is 0
"Inconsistent counters : gets(%) != hits(%s) + miss(%s)", //
NUMBER_OF_CACHE_GET, stats.hitCount(), stats.missCount());
/* regularly NOK */
checkState(stats.missCount() <= THREAD_POOL_SIZE, "Unexpected miss count : %s > nb of threads (%s)", stats.missCount(), THREAD_POOL_SIZE);
} finally {
pool.shutdown();
}
} catch (Throwable e) {
System.out.println("Run " + j);
System.out.println("Cache stats " + cache.stats());
throw propagate(e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment