Search code examples
javacachingguava

Is it proper use of CacheLoader?


I would like to ask what should I do on load method when cache does not contain the key. I add manually elements to the cache by put method:

@Override
    public void addResources(....) {
                    SomeId someId = SomeId.builder()
                            ....
                            .build();
                    cache.put(someId, r.getResource());
    }

After that I'm looking for that key in LoadingCache. If it contains the key I get it by get method.

@Override

  public InputStream someMethod(String uri) throws ExecutionException {
        SomeId someId = SomeId.builder()
                ...
                .build();
        if ( cache.asMap()
                .containsKey(someId) ) {
            return new ByteArrayInputStream(cache.get(someId));
        } else {
            ....
            }
            return is;
        }
    }

I initialize this cache that way:

 private static LoadingCache<SomeId, byte[]> cache;

    @PostConstruct
    public void init() {
        cache = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(24, TimeUnit.HOURS)
                .build(new CacheLoader<SomeId, byte[]>() {
                    @Override
                    public byte[] load(SomeId someId) {
                        throw new IllegalStateException("");
                    }
                });
    }

I do now know what should I do inside it:

@Override
                        public byte[] load(SomeId someId) {
throw new IllegalStateException("");
                        }

as I'm not loading elements from any db just from this cache. If elements is not inside cache than I should do nothing. It is worth to notice that I'm checking in method if key is present in cache

 if ( cache.asMap()
                .containsKey(someId) ) {
            return new ByteArrayInputStream(cache.get(someId));

Solution

  • You don't really need LoadingCache, pure Cache is sufficient for your use case. Just don't pass anything to .build() and you should be good to go:

    private static Cache<SomeId, byte[]> cache;
    
    // ... init
        cache = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(24, TimeUnit.HOURS)
                .build();
    

    Usage:

    byte[] value = cache.getIfPresent(someId);
    if (value != null) { // if key is not present, null is returned
        return new ByteArrayInputStream(value);
    } else {
        // ...
    }