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.
 
     
     
     
    