Search code examples
javacachinglru

Java LRU cache retrieve eldest before removing


I am using the LRU cache in java and did override removeEldest.

@Override protected boolean removeEldestEntry (Map.Entry<K,V> eldest) {
            return size() > LRUConcurrentCache.this.cacheSize;
        }

But before removing I want to getEldestEntry for persistence. How can I getEldestEntry before doing the removeEldestEntry?


Solution

  • I'm guessing you have a custom implementation of an LRU cache. In that case, I would recommend a Listener approach to this problem, i.e. create a CacheExpirationListener interface (if you're using Java 8 this is not strictly necessary; you could just as well use the Consumer interface):

    public interface CacheExpirationListener<V> {
        void entryExpired(V value);
    }
    

    Now make sure your cache implementation keeps track of its listeners and calls them accordingly before actually removing items:

    public class MyCacheImplementation<K, V> extends LinkedHashMap<K, V> {
        private final List<CacheExpirationListener<V>> removalListeners = new ArrayList<>();
    
        public void addRemovalListener(CacheExpirationListener<V> listener) {
            removalListeners.add(listener)
        }
    
        protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
            if(size() > LRUConcurrentCache.this.cacheSize) {
                removalListeners.forEach(CacheExpirationListener::entryExpired);
                return true;
            }
    
            return false;
        }
    }
    

    Now, create a CacheExpirationListener implementation that persists the supplied entry, register that with the cache, and you're all set.

    Note however that there's lots of other stuff you need to handle, e.g. what happens when your application shuts down? Do all the values need to be persisted in that case as well? Also, you would obviously need some kind of error handling if persistence doesn't work (database down?). What should happen in that case? Maybe the entry should be retained or - at the very least - you'll need to log that something went wrong.