0

I was going through Guava Cache examples and wondered is there a way to prevent some entries from getting evicted from the cache on some condition.

Like, if an entry is being used by an application, it's unlikely you would like it to get evicted!

One way, I could think of is using CacheBuilder.weigher() method with size-based eviction, as Javadoc states:

When the weight of an entry is zero it will not be considered for size-based eviction (though it still may be evicted by other means).

But weights are calculated in the beginning and are static during the lifetime of a cache entry. So, when an entry is no longer being used by application its weight cannot be set to zero.

Is there any other efficient way to achieve this? Like, a method would be called by Guava Cache before evicting a specific entry whether it should be evicted or not!

Also, is it a bad idea to cache Presenter instances in an MVP application? As, I am going to use Guava Cache to cache Presenter instances in my application!

Akshat
  • 720
  • 9
  • 24
  • 1
    You shouldn't need to cache presenters in MVP, as they are light weight and should have a low churn. There may be application data to cache, but the component itself should be thin (e.g. presenter calls client-side services that cache remote data). While there are workarounds for the caching angle, it sounds like the wrong path to go down. – Ben Manes Oct 20 '15 at 09:02
  • But consider Presenter as MVP triad, as Presenter holds Model and View too. Is MVP triad considered "light-weight" too? Also, my purpose to cache MVP triad is not primarily to improve the performance but to support "Back-Forward" navigation in my Swing Application. Also, to load existing MVP instance if any button which launches a presenter, is pressed more than once. So, a new MVP triad is not created upon each click! That's my purpose! I know, this could be done other way too, but caching the MVP seems to me a good way! – Akshat Oct 20 '15 at 09:22
  • The triad is lightweight, where the Presenter coordinates between the model (dumb data) and view (dumb UI). It has intelligence, but not state. The management of non-UI state is delegates to client services that may be complex, but encapsulated. History is managed by encoding the state into the navigation, e.g. see how [browser history is encoded](https://en.wikipedia.org/wiki/Single-page_application#Browser_history) into the URL. A back/forwards creates new triads that are populated to provide the view. If you are determined to use a cache, then weak references are probably a better fit. – Ben Manes Oct 20 '15 at 18:12
  • Anyway, I implemented the back/forward feature using a queue to hold states and traversing those states accordingly. Also, I've decided to cache presenters again not for performance, but for me, it is the only way left to track them and dispose unused presenters! [Here is the snapshot...](http://puu.sh/kSm2L/35dc2c87cf.gif) – Akshat Oct 21 '15 at 15:37

1 Answers1

1

If you don't want cache entries to be evicted while in use you should use reference-based eviction, specifically .weakValues(). This will remove the entry from the cache once no other part of the application is referencing it.

If you want to use reference-based eviction and some other eviction strategy (e.g. evict after an hour, if not currently referenced elsewhere) you can use two sibling caches. One uses reference eviction and the other uses timed eviction. Since the second cache holds a strong reference it will prevent the other queue from evicting the entry (and once the timed cache has evicted the reference cache will be free to do so). You could implement this as a custom Cache implementation, so that callers don't need to keep track of the bookkeeping.

dimo414
  • 47,227
  • 18
  • 148
  • 244