The LocalCache class is used for size-limited caches. It is used both for caching on-heap objects, as in a local cache or the front portion of a near cache, and can also be used as the backing map for a partitioned cache. Applications can provide custom eviction policies for use with a LocalCache. Note that Coherence's default eviction policy is very effective for most workloads, and so the vast majority of applications will not need to provide a custom policy. Also, it is generally best to restrict the usage of eviction policies to scenarios where the evicted data is present in a backing system (e.g., the back portion of a near cache or a database) – eviction should be treated as a physical operation (freeing memory) and not a logical operation (deleting an entity).
The following source code example shows the implementation of a simple custom eviction policy:
import com.tangosol.net.cache.CacheEvent; import com.tangosol.net.cache.LocalCache; import com.tangosol.net.cache.OldCache; import com.tangosol.util.AbstractMapListener; import com.tangosol.util.MapEvent; import java.util.Iterator; public class MyEvictionPolicy extends AbstractMapListener implements OldCache.EvictionPolicy { LocalCache m_cache = null; public void entryInserted(MapEvent evt) { System.out.println("entryInserted:" + isSynthetic(evt) + evt); if (m_cache == null) { m_cache = (LocalCache) evt.getMap(); } } public void entryUpdated(MapEvent evt) { System.out.println("entryUpdated:" + isSynthetic(evt) + evt); } public void entryDeleted(MapEvent evt) { System.out.println("entryDeleted:" + isSynthetic(evt) + evt); } String isSynthetic(MapEvent evt) { // synthetic events are caused by internal processing - eviction or loading return ((CacheEvent) evt).isSynthetic() ? " SYNTHETIC " : " "; } public void entryTouched(OldCache.Entry entry) { System.out.println("entryTouched:" + entry.getKey()); } public void requestEviction(int cMaximum) { int cCurrent = m_cache.getUnits(); System.out.println("requestEviction: current:" + cCurrent + " to:" + cMaximum); // // ... eviction policy calculations ... // for (Iterator iter = m_cache.entrySet().iterator(); iter.hasNext();) { OldCache.Entry entry = (OldCache.Entry) iter.next(); if (m_cache.getUnits() > cMaximum) { m_cache.evict(entry.getKey()); } else { break; } } } public MyEvictionPolicy() { } }
This Coherence cache configuration (e.g. coherence-cache-config.xml) shows how to plug in the eviction policy:
<?xml version="1.0"?> <!DOCTYPE cache-config SYSTEM "cache-config.dtd"> <cache-config> <caching-scheme-mapping> <cache-mapping> <cache-name>test</cache-name> <scheme-name>example-near</scheme-name> </cache-mapping> </caching-scheme-mapping> <caching-schemes> <distributed-scheme> <scheme-name>example-distributed</scheme-name> <service-name>DistributedCache</service-name> <backing-map-scheme> <local-scheme> <scheme-ref>example-backing-map</scheme-ref> </local-scheme> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme> <near-scheme> <scheme-name>example-near</scheme-name> <front-scheme> <local-scheme> <eviction-policy> <class-scheme> <class-name>MyEvictionPolicy</class-name> </class-scheme> </eviction-policy> <high-units>10</high-units> </local-scheme> </front-scheme> <back-scheme> <distributed-scheme> <scheme-ref>example-distributed</scheme-ref> </distributed-scheme> </back-scheme> <invalidation-strategy>all</invalidation-strategy> <autostart>true</autostart> </near-scheme> <local-scheme> <scheme-name>example-backing-map</scheme-name> <eviction-policy>HYBRID</eviction-policy> <high-units>{back-size-limit 0}</high-units> <expiry-delay>{back-expiry 1h}</expiry-delay> <flush-delay>1m</flush-delay> <cachestore-scheme></cachestore-scheme> </local-scheme> </caching-schemes> </cache-config>