jeudi 26 février 2015

How do I store a Map in a Guava Cache



I had a Map<Range<Double>, String> that checks where a particular Double value (score) is mapped to a String (level). The end users want to be able to dynamically change this mapping, in the long term we would like for there to be a web based GUI where they control this but for the short term they're happy for a file to be in S3 and to editing that whenever a change is needed. I don't want to hit S3 for each request and want to cache this as it doesn't change too frequently(Once a week or so). I don't want to have to make a code change and bounce my service either.


Here is what I have come up with -



public class Mapper() {
private LoadingCache<Score, String> scoreToLevelCache;

public Mapper() {
scoreToLevelCache = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<Score, String>() {
public String load(Score score) {
Map<Range<Double>, String> scoreToLevelMap = readMappingFromS3(); //readMappingFromS3 omitted for brevity
for(Range<Double> key : scoreToLevelMap.keySet()) {
if(key.contains(score.getCount())) { return scoreToLevelMap.get(key); }
}
throw new IllegalArgumentException("The score couldn't be mapped to a level. Either the score passed in was incorrect or the mapping is incorrect");
}
});
}

public String getContentLevelForScore(Score Score) {
try {
return scoreToLevelCache.get(Score);
} catch (ExecutionException e) { throw new InternalServerException(e); }
}
}


The obvious problem with this approach is in the load method when I do Map<Range<Double>, String> scoreToLevelMap = readMappingFromS3(); For each key I'm loading the entire map over and over. This isn't a performance issue but it could become one when the size increases, in any case this is not an efficient approach.


I think that keeping this entire map in the cache would be better, but I'm not sure how to do that here. Can anyone help with this or suggest a more elegant way of achieving this.




Aucun commentaire:

Enregistrer un commentaire