Reputation: 2242
I want to use google Cache to cache my data,So I write the code like this.I find that it can only pass one parameter that called key,But In my method,I have the other parameter,How to fix my code?
private LoadingCacheS<tring, List<Map<String, Long>> getCache(String key,Map<String,String> para1,
String para2){
retrun CacheBuilder.newBuilder()
.refreshAfterWrite(20, TimeUnit.MINUTES)
.expireAfterWrite(30, TimeUnit.MINUTES)
.maximumSize(1)
.build(new CacheLoader<String, List<Map<String, Long>>>() {
@Override
public List<Map<String, Long>> load(String key) throws Exception {
return queryData(key); //can not get the other para
}
@Override
public ListenableFuture<List<Map<String, Long>>> reload(String key, List<Map<String, Long>> oldValue)
throws Exception {
ListenableFutureTask<List<Map<String, Long>>> task = ListenableFutureTask
.create(() -> queryData(key));
executorService.execute(task);
return task;
}
In my queryData method,I have three parameters,How to change my code?
private List<Map<String, Long>> queryData(String key,Map<String,String> para1,
String para2){
//query data and return data
}
Upvotes: 2
Views: 2094
Reputation: 24067
Can you just check if value exist in cache and call your custom load method if it doesn't? Something like this (Kotlin)
fun getDataFromCache(val key: Key, para1: Map<String,String>, para2: String) {
val fromCache = cache.getIfPresent(key)
if (fromCache != null) {
return fromCache
} else {
val loaded = queryData(key, para1, para2)
cache.put(key, loaded)
return loaded
}
}
Upvotes: 0
Reputation: 9621
In these types of cases you have multiple options.
If all of the parameters are part of the mapping, then you can use a composite key. A data class that holds all parameters and correctly implements equals
and hashCode
is the cache key.
Sometimes these parameters irrelevant to the key but the parameters are part of a lifecycle scoped, e.g. to the http request such as the user's access token. In those cases you may be using a dependency injector like Guice that is aware of this lifecycle. In those cases you can inject a Provider<T>
(or equivalent) instead and resolve the parameter at runtime.
The last option is to not use a CacheLoader
but instead use cache.get(key, loader)
. The loader, a Callable
, is a "capturing lambda" which means that it has access to parameters in the surrounding scope. The drawback of this approach is that you cannot use refreshAfterWrite
since that requires a CacheLoader
.
Upvotes: 2