LocalCacheクラスは、サイズの制限されたキャッシュに使用されます。これは、ヒープ上のオブジェクトのキャッシュ(ローカル・キャッシュやニア・キャッシュのフロント部分など)、およびパーティション・キャッシュのバッキング・マップの両方に使用されます。アプリケーションでは、LocalCacheで使用するカスタム・エビクション・ポリシーを指定できます。
Coherenceのデフォルトのエビクション・ポリシーは大半のワークロードに対して非常に効率的であり、ほとんどのアプリケーションでカスタム・ポリシーを提供する必要がなくなります。一般的に、エビクション・ポリシーを使用するのは、削除されたデータがバッキング・システム(ニア・キャッシュのバック部分またはデータベース)に存在する場合に限定することをお薦めします。エビクションは、論理操作(エンティティの削除)ではなく、物理操作(メモリーの解放)として扱ってください。
例31-1は、単純なカスタム・エビクション・ポリシーの実装を示しています。
例31-1 カスタム・エビクション・ポリシーの実装
package com.tangosol.examples.eviction;
import com.tangosol.net.cache.AbstractEvictionPolicy;
import com.tangosol.net.cache.ConfigurableCacheMap;
import com.tangosol.net.cache.LocalCache;
import com.tangosol.net.BackingMapManagerContext;
import com.tangosol.util.ConverterCollections;
import java.util.Iterator;
import java.util.Map;
/**
* Custom eviction policy that evicts items randomly (or more specifically,
* based on the natural order provided by the map's iterator.)
* This example may be used in cases where fast eviction is required
* with as little processing as possible.
*/
public class SimpleEvictionPolicy
extends AbstractEvictionPolicy
{
/**
* Default constructor; typically used with local caches or the front
* parts of near caches.
*/
public SimpleEvictionPolicy()
{
}
/**
* Constructor that accepts {@link BackingMapManagerContext}; should
* be used with partitioned cache backing maps.
*
* @param ctx backing map context
*/
public SimpleEvictionPolicy(BackingMapManagerContext ctx)
{
m_ctx = ctx;
}
/**
* {@inheritDoc}
*/
public void entryUpdated(ConfigurableCacheMap.Entry entry)
{
}
/**
* {@inheritDoc}
*/
public void entryTouched(ConfigurableCacheMap.Entry entry)
{
}
/**
* {@inheritDoc}
*/
public void requestEviction(int cMaximum)
{
ConfigurableCacheMap cache = getCache();
Iterator iter = cache.entrySet().iterator();
for (int i = 0, c = cache.getUnits() - cMaximum; i < c && iter.hasNext();
i++)
{
ConfigurableCacheMap.Entry entry = (ConfigurableCacheMap.Entry)
iter.next();
StringBuffer buffer = new StringBuffer();
// If the contents of the entry (for example the key/value) need
// to be examined, invoke convertEntry(entry) in case
// the entry must be deserialized
Map.Entry convertedEntry = convertEntry(entry);
buffer.append("Entry: ").append(convertedEntry);
// Here's how to get metadata about creation/last touched
// timestamps for entries. This information might be used
// in determining what gets evicted.
if (entry instanceof LocalCache.Entry)
{
buffer.append(", create millis=");
buffer.append(((LocalCache.Entry) entry).getCreatedMillis());
}
buffer.append(", last touch millis=");
buffer.append(entry.getLastTouchMillis());
// This output is for illustrative purposes; this may generate
// excessive output in a production system
System.out.println(buffer);
// iterate and remove items
// from the cache until below the maximum. Note that
// the non converted entry key is passed to the evict method
cache.evict(entry.getKey());
}
}
/**
* If a {@link BackingMapManagerContext} is configured, wrap the
* Entry with {@link ConverterCollections.ConverterEntry} in order
* to deserialize the entry.
*
* @see ConverterCollections.ConverterEntry
* @see BackingMapManagerContext
*
* @param entry entry to convert if necessary
*
* @return an entry that deserializes its key and value if necessary
*/
protected Map.Entry convertEntry(Map.Entry entry)
{
BackingMapManagerContext ctx = m_ctx;
return ctx == null ? entry :
new ConverterCollections.ConverterEntry(entry,
ctx.getKeyFromInternalConverter(),
ctx.getValueFromInternalConverter(),
ctx.getValueToInternalConverter());
}
private BackingMapManagerContext m_ctx;
}
例31-2は、エビクション・ポリシーが指定されているCoherenceキャッシュ構成ファイル(coherence-cache-config.xml)を示しています。
例31-2 coherence-cache-config.xmlファイル内のカスタム・エビクション・ポリシー
<?xml version="1.0"?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config
coherence-cache-config.xsd">
<caching-scheme-mapping>
<cache-mapping>
<cache-name>*</cache-name>
<scheme-name>example-near</scheme-name>
</cache-mapping>
</caching-scheme-mapping>
<caching-schemes>
<near-scheme>
<scheme-name>example-near</scheme-name>
<front-scheme>
<local-scheme>
<eviction-policy>
<class-scheme>
<class-name>
com.tangosol.examples.eviction.SimpleEvictionPolicy
</class-name>
</class-scheme>
</eviction-policy>
<high-units>1000</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>
<distributed-scheme>
<scheme-name>example-distributed</scheme-name>
<service-name>DistributedCache</service-name>
<backing-map-scheme>
<local-scheme>
<eviction-policy>
<class-scheme>
<class-name>
com.tangosol.examples.eviction.SimpleEvictionPolicy
</class-name>
<init-params>
<!--
Passing the BackingMapManagerContext to the eviction policy;
this is required for deserializing entries
-->
<init-param>
<param-type>
com.tangosol.net.BackingMapManagerContext</param-type>
<param-value>{manager-context}</param-value>
</init-param>
</init-params>
</class-scheme>
</eviction-policy>
<high-units>20m</high-units>
<unit-calculator>binary</unit-calculator>
</local-scheme>
</backing-map-scheme>
<autostart>true</autostart>
</distributed-scheme>
</caching-schemes>
</cache-config>