4

Is it ok to use a Guava Cache of maximum size 1?

I'm reading that sometimes there can be evictions even before that maximum size is reached.

However, I only need one cache entry. So I'm wondering what value to set for maximum size that would be safe, but not excessive.

ycomp
  • 8,316
  • 19
  • 57
  • 95
  • 2
    Most likely using [Suppliers.memoize](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Suppliers.html#memoize(com.google.common.base.Supplier)) or an `AtomicReference` is a better match for a single entry cache. – Ben Manes Feb 07 '16 at 05:26
  • [caching - Thread-safe cache of one object in java - Stack Overflow](https://stackoverflow.com/questions/3636244/thread-safe-cache-of-one-object-in-java) – ycomp Feb 08 '16 at 20:19

1 Answers1

2

You should be able to use Cache.cleanUp() as explained in When Does Cleanup Happen? and test whether a maximum size of 1 suites your needs or not.

e.g. The following shows that using a LoadingCache with maximum size of 1 will not evict an existing entry until a different entry is loaded to take its place:

final LoadingCache<Character, Integer> loadingCache = CacheBuilder.newBuilder()
        .maximumSize(1)
        .build(new CacheLoader<Object, Integer>() {
            private final AtomicInteger loadInvocationCount = new AtomicInteger();

            @Override
            public Integer load(Object key) throws Exception {
                return loadInvocationCount.getAndIncrement();
            }
        });
assert loadingCache.size() == 0;

assert loadingCache.getUnchecked('a') == 0;
assert loadingCache.size() == 1;

loadingCache.cleanUp();
assert loadingCache.size() == 1;

assert loadingCache.getUnchecked('a') == 0;
assert loadingCache.size() == 1;

assert loadingCache.getUnchecked('b') == 1;
assert loadingCache.size() == 1;

loadingCache.cleanUp();
assert loadingCache.size() == 1;

assert loadingCache.getUnchecked('a') == 2;
assert loadingCache.size() == 1;

loadingCache.cleanUp();
assert loadingCache.size() == 1;

Note that this may be specific to the type of LoadingCache being built so you will need to test whatever configuration you plan to use.

mfulton26
  • 29,956
  • 6
  • 64
  • 88
  • thanks, I used `Suppliers.memoizeWithExpiration()` instead, since basically this is the feature I was looking for - to cache 1 object for a given amount of time. I was ignorant of `memoization` when I made the original post. – ycomp Feb 08 '16 at 18:58