1

Is there a way to not cache some specific elements using Guava Cache? I still want the element to be returned, but not cached.

For example:

LoadingCache guavaCache;

public Element load(String key) {
  Element element = requestElement(key);

  if(element.isActive == false){
    guavaCache.dontCache(element);
  }

  return element;
}
Marcelo Xavier
  • 322
  • 2
  • 11
  • 1
    No, you would have to throw an exception and catch it. In Caffeine you can return null, but effectively every requester would load the key sequentially (block next while computing). In both, you might be able to hack it using a `Weigher` giving `Integer.MAX_VALUE` to force the added entry to be immediately evicted (rather than flushing the cache), causing a small time window of sharing. Depends on the costs and use-case, I guess. – Ben Manes Nov 14 '17 at 05:09
  • Sorry, I forgot to mention that I need the element returned, just don't added to the cache. In your suggestion @BenManes if I throw an exception it doesn't return the element – Marcelo Xavier Nov 15 '17 at 01:12
  • Perhaps the cleanest is to call `cache.invalidate(key)` if not `isActive` after the load (on the caller side)? – Ben Manes Nov 15 '17 at 01:15
  • Yes, that's what I am doing for alternative solution. However, this is not very clean since the element is added to the cache and removed right after. – Marcelo Xavier Nov 15 '17 at 01:18
  • In Guava, the `Weigher` solution is almost the same as it forces the cache to evict it immediately. This scenario isn't designed for, so there are workarounds but otherwise murky. – Ben Manes Nov 15 '17 at 01:22

2 Answers2

3

I implemented a solution for this problem: invalidate the element after return it. This will removed the element from the cache right after inserted it.

Cache config:

public Element load(String key) {
  return requestElement(key);
}

then:

element = guavaCache.get(key);
if(element.isActive == false){
  guavaCache.invalidate(key)
}

This seems not very clean but it's being done internally by Guava.

Marcelo Xavier
  • 322
  • 2
  • 11
  • Nice, simple solution. Consider using [`ForwardingLoadingCache`](https://static.javadoc.io/com.google.guava/guava/23.3-jre/com/google/common/cache/ForwardingLoadingCache.html) to internalize this behaviour. – Henrik Aasted Sørensen Nov 15 '17 at 11:19
1

A simple solution, avoiding adding the element to the cache and invalidate it later on, is to request the element from the source (not using the cache) and add it to the cache if the element is eligible.

element = cache.getIfPresent(key);

if(element == null){
  element = source.request(key);
  if(element != null && eligibleToCache(element)){
    cache.put(key, element)
  }
}

Although you will lose the features of the cache using this. This solution is to avoid insert the element in the cache and have to invalidate it later.

Marcelo Xavier
  • 322
  • 2
  • 11