0
votes

Hey All so using google's CacheBuilder / CacheLoader:

CacheBuilder.newBuilder().maximumSize(MAX_SIZE).expireAfterAccess()
                                  .build(new CacheLoader<String, Object>() {
                                      @Override
                                      public Object load(String key) throws Exception {
                                          return Query(key);
                                      }
                                  });

Pretty straight forward. Thing is the key is used in the query for loading when not in cache and can actually be pretty big. I'd like to actually store the hash of the key in the cache and so when a lookup in the cache is actually done it uses the hash of the key but when the load is done the key is actually the full query.

Basically I would want my program to use the cache by sending the query to get function but just before key lookup or cache storage I wonder if there is a hook function I can override to hash the key for final cache storage and lookup?

Thanks in advance

Update:

So I figured out a solution using callable version of get. If I wrap the cache in my own container:

class WrappedCache {
    private Cache<String, Object> mInnerCache;

    public Object get(String key) {
        String hashedKey = Hash(key); // get hashed key

        return mInnerCache.get(hashedKey, new Callable<Object>() {
            return Query(key);
        }
    }
}

This way the inner cache only deals with hash values but the callable gets the original query if it needs it to perform it's actions.

If I needed a more complex solution I could have made the WrappedCache implement the Cache<K,V> interface but my usage case is a little simpler and I can get away with above.

1
No, Guava has no support for this. - Louis Wasserman
FYI: Guava has an AbstractCache and an AbstractLoadingCache which should facilitate implementing your own Cache/LoadingCache if you chose to do so. - mfulton26

1 Answers

0
votes

I don't believe the Guava Cache implementation supports such a thing, but you could create a decorator to do the translation on put and get prior to storing.

Would something like this work?

public class CacheDecorator<K1, K2, V> {

    private final Function<K1, K2> keyConversion;
    private final LoadingCache<K2, V> cache;

    public CacheDecorator(Function<K1, K2> keyConversion, LoadingCache<K2, V> cache) {
        this.keyConversion = keyConversion;
        this.cache = cache;
    }

    public V get(K1 key) throws ExecutionException {
        return cache.get(keyConversion.apply(key));
    }

    public void put(K1 key, V value) {
        cache.put(keyConversion.apply(key), value);
    }

}