blob: 6191f4d43f54366b4b72630208e373058a81494d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite.internal.processors.cache.eviction;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
import javax.cache.Cache;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.eviction.EvictableEntry;
import org.apache.ignite.cache.eviction.EvictionFilter;
import org.apache.ignite.cache.eviction.EvictionPolicy;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.NearCacheConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.processors.cache.distributed.dht.colocated.GridDhtColocatedCache;
import org.apache.ignite.internal.util.typedef.C2;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.transactions.Transaction;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
import static org.apache.ignite.cache.CacheMode.LOCAL;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
import static org.apache.ignite.cache.CacheMode.REPLICATED;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
import static org.apache.ignite.events.EventType.EVT_JOB_MAPPED;
import static org.apache.ignite.events.EventType.EVT_TASK_FAILED;
import static org.apache.ignite.events.EventType.EVT_TASK_FINISHED;
import static org.apache.ignite.internal.processors.cache.eviction.EvictionAbstractTest.EvictionPolicyProxy.proxy;
import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
/**
* Base class for eviction tests.
*/
public abstract class EvictionAbstractTest<T extends EvictionPolicy<?, ?>>
extends GridCommonAbstractTest {
/** Put entry size. */
protected static final int PUT_ENTRY_SIZE = 10;
/** Replicated cache. */
protected CacheMode mode = REPLICATED;
/** Near enabled flag. */
protected boolean nearEnabled;
/** Policy max. */
protected int plcMax = 10;
/** Policy batch size. */
protected int plcBatchSize = 1;
/** Policy max memory size. */
protected long plcMaxMemSize = 0;
/** Near policy max. */
protected int nearMax = 3;
/** Synchronous commit. */
protected boolean syncCommit;
/** */
protected int gridCnt = 2;
/** */
protected EvictionFilter<?, ?> filter;
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration c = super.getConfiguration(igniteInstanceName);
CacheConfiguration cc = defaultCacheConfiguration();
cc.setCacheMode(mode);
cc.setEvictionPolicy(createPolicy(plcMax));
cc.setOnheapCacheEnabled(true);
cc.setWriteSynchronizationMode(syncCommit ? FULL_SYNC : FULL_ASYNC);
cc.setAtomicityMode(TRANSACTIONAL);
if (nearEnabled) {
NearCacheConfiguration nearCfg = new NearCacheConfiguration();
nearCfg.setNearEvictionPolicy(createNearPolicy(nearMax));
cc.setNearConfiguration(nearCfg);
}
else
cc.setNearConfiguration(null);
if (mode == PARTITIONED)
cc.setBackups(1);
if (filter != null)
cc.setEvictionFilter(filter);
c.setCacheConfiguration(cc);
c.setIncludeEventTypes(EVT_TASK_FAILED, EVT_TASK_FINISHED, EVT_JOB_MAPPED);
c.setIncludeProperties();
return c;
}
/** {@inheritDoc} */
@Override protected void afterTestsStopped() throws Exception {
filter = null;
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizePolicy() throws Exception {
plcMax = 3;
plcMaxMemSize = 0;
plcBatchSize = 1;
doTestPolicy();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizePolicyWithBatch() throws Exception {
plcMax = 3;
plcMaxMemSize = 0;
plcBatchSize = 2;
doTestPolicyWithBatch();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxMemSizePolicy() throws Exception {
plcMax = 0;
plcMaxMemSize = 3 * MockEntry.ENTRY_SIZE;
plcBatchSize = 1;
doTestPolicy();
}
/**
* Batch ignored when {@code maxSize > 0} and {@code maxMemSize > 0}.
*
* @throws Exception If failed.
*/
@Test
public void testMaxMemSizePolicyWithBatch() throws Exception {
plcMax = 3;
plcMaxMemSize = 10 * MockEntry.ENTRY_SIZE;
plcBatchSize = 2;
doTestPolicy();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizeMemory() throws Exception {
int max = 10;
plcMax = max;
plcMaxMemSize = 0;
plcBatchSize = 1;
doTestMemory(max);
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizeMemoryWithBatch() throws Exception {
int max = 10;
plcMax = max;
plcMaxMemSize = 0;
plcBatchSize = 2;
doTestMemory(max);
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxMemSizeMemory() throws Exception {
int max = 10;
plcMax = 0;
plcMaxMemSize = max * MockEntry.ENTRY_SIZE;
plcBatchSize = 1;
doTestMemory(max);
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizeRandom() throws Exception {
plcMax = 10;
plcMaxMemSize = 0;
plcBatchSize = 1;
doTestRandom();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizeRandomWithBatch() throws Exception {
plcMax = 10;
plcMaxMemSize = 0;
plcBatchSize = 2;
doTestRandom();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxMemSizeRandom() throws Exception {
plcMax = 0;
plcMaxMemSize = 10 * MockEntry.KEY_SIZE;
plcBatchSize = 1;
doTestRandom();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizeAllowEmptyEntries() throws Exception {
plcMax = 10;
plcMaxMemSize = 0;
plcBatchSize = 1;
doTestAllowEmptyEntries();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizeAllowEmptyEntriesWithBatch() throws Exception {
plcMax = 10;
plcMaxMemSize = 0;
plcBatchSize = 2;
doTestAllowEmptyEntries();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxMemSizeAllowEmptyEntries() throws Exception {
plcMax = 0;
plcMaxMemSize = 10 * MockEntry.KEY_SIZE;
plcBatchSize = 1;
doTestAllowEmptyEntries();
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizePut() throws Exception {
plcMax = 100;
plcBatchSize = 1;
plcMaxMemSize = 0;
doTestPut(plcMax);
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxSizePutWithBatch() throws Exception {
plcMax = 100;
plcBatchSize = 2;
plcMaxMemSize = 0;
doTestPut(plcMax);
}
/**
* @throws Exception If failed.
*/
@Test
public void testMaxMemSizePut() throws Exception {
int max = 100;
plcMax = 0;
plcBatchSize = 2;
plcMaxMemSize = max * PUT_ENTRY_SIZE;
doTestPut(max);
}
/**
* Tests policy behaviour.
*
* @throws Exception If failed.
*/
protected abstract void doTestPolicy() throws Exception;
/**
* Tests policy behaviour with batch enabled.
*
* @throws Exception If failed.
*/
protected abstract void doTestPolicyWithBatch() throws Exception;
/**
* @throws Exception If failed.
*/
protected void doTestAllowEmptyEntries() throws Exception {
try {
startGrid();
MockEntry e1 = new MockEntry("1");
MockEntry e2 = new MockEntry("2");
MockEntry e3 = new MockEntry("3");
MockEntry e4 = new MockEntry("4");
MockEntry e5 = new MockEntry("5");
EvictionPolicyProxy p = proxy(policy());
p.onEntryAccessed(false, e1);
assertFalse(e1.isEvicted());
check(p.queue().size(), MockEntry.KEY_SIZE);
p.onEntryAccessed(false, e2);
assertFalse(e1.isEvicted());
assertFalse(e2.isEvicted());
check(p.queue().size(), MockEntry.KEY_SIZE);
p.onEntryAccessed(false, e3);
assertFalse(e1.isEvicted());
assertFalse(e3.isEvicted());
check(p.queue().size(), MockEntry.KEY_SIZE);
p.onEntryAccessed(false, e4);
assertFalse(e1.isEvicted());
assertFalse(e3.isEvicted());
assertFalse(e4.isEvicted());
check(p.queue().size(), MockEntry.KEY_SIZE);
p.onEntryAccessed(false, e5);
assertFalse(e1.isEvicted());
assertFalse(e3.isEvicted());
assertFalse(e5.isEvicted());
check(p.queue().size(), MockEntry.KEY_SIZE);
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If failed.
*/
protected void doTestMemory(int max) throws Exception {
try {
startGrid();
EvictionPolicyProxy p = proxy(policy());
int cnt = max + plcBatchSize;
for (int i = 0; i < cnt; i++)
p.onEntryAccessed(false, new MockEntry(Integer.toString(i), Integer.toString(i)));
info(p);
check(max, MockEntry.ENTRY_SIZE);
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If failed.
*/
protected void doTestRandom() throws Exception {
try {
startGrid();
EvictionPolicyProxy p = proxy(policy());
int max = 10;
Random rand = new Random();
int keys = 31;
MockEntry[] entries = new MockEntry[keys];
for (int i = 0; i < entries.length; i++)
entries[i] = new MockEntry(Integer.toString(i));
int runs = 5000000;
for (int i = 0; i < runs; i++) {
boolean rmv = rand.nextBoolean();
int j = rand.nextInt(entries.length);
MockEntry e = entry(entries, j);
if (rmv)
entries[j] = new MockEntry(Integer.toString(j));
p.onEntryAccessed(rmv, e);
}
info(p);
assertTrue(p.getCurrentSize() <= (plcMaxMemSize > 0 ? max : max + plcBatchSize));
assertTrue(p.getCurrentMemorySize() <= (plcMaxMemSize > 0 ? max : max + plcBatchSize) * MockEntry.KEY_SIZE);
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If failed.
*/
protected void doTestPut(int max) throws Exception {
mode = LOCAL;
syncCommit = true;
try {
Ignite ignite = startGrid();
IgniteCache<Object, Object> cache = ignite.cache(DEFAULT_CACHE_NAME);
int cnt = 500;
int min = Integer.MAX_VALUE;
int minIdx = 0;
for (int i = 0; i < cnt; i++) {
cache.put(i, i);
int cacheSize = cache.size();
if (i > max && cacheSize < min) {
min = cacheSize;
minIdx = i;
}
}
assertTrue("Min cache size is too small: " + min, min >= max);
check(max, PUT_ENTRY_SIZE);
info("Min cache size [min=" + min + ", idx=" + minIdx + ']');
info("Current cache size " + cache.size());
info("Current cache key size " + cache.size());
min = Integer.MAX_VALUE;
minIdx = 0;
// Touch.
for (int i = cnt; --i > cnt - max;) {
cache.get(i);
int cacheSize = cache.size();
if (cacheSize < min) {
min = cacheSize;
minIdx = i;
}
}
info("----");
info("Min cache size [min=" + min + ", idx=" + minIdx + ']');
info("Current cache size " + cache.size());
info("Current cache key size " + cache.size());
check(max, PUT_ENTRY_SIZE);
}
finally {
stopAllGrids();
}
}
/**
* @param arr Array.
* @param idx Index.
* @return Entry at the index.
*/
protected MockEntry entry(MockEntry[] arr, int idx) {
MockEntry e = arr[idx];
if (e.isEvicted())
e = arr[idx] = new MockEntry(e.getKey());
return e;
}
/**
* @param prefix Prefix.
* @param p Policy.
*/
protected void info(String prefix, EvictionPolicy<?, ?> p) {
info(prefix + ": " + p.toString());
}
/** @param p Policy. */
protected void info(EvictionPolicy<?, ?> p) {
info(p.toString());
}
/**
* @param c1 Policy collection.
* @param c2 Expected list.
*/
protected static void check(Collection<EvictableEntry<String, String>> c1, MockEntry... c2) {
check(c1, F.asList(c2));
}
/**
* @param expSize Expected size.
* @param entrySize Entry size.
*/
protected void check(int expSize, int entrySize) {
EvictionPolicyProxy proxy = proxy(policy());
assertEquals(expSize, proxy.getCurrentSize());
assertEquals(expSize * entrySize, proxy.getCurrentMemorySize());
}
/**
* @param entrySize Entry size.
* @param c1 Closure 1.
* @param c2 Closure 2.
*/
protected void check(int entrySize, Collection<EvictableEntry<String, String>> c1, MockEntry... c2) {
check(c2.length, entrySize);
check(c1, c2);
}
/** @return Policy. */
@SuppressWarnings({"unchecked"})
protected T policy() {
return (T)grid().cache(DEFAULT_CACHE_NAME).getConfiguration(CacheConfiguration.class).getEvictionPolicy();
}
/**
* @param i Grid index.
* @return Policy.
*/
@SuppressWarnings({"unchecked"})
protected T policy(int i) {
return (T)grid(i).cache(DEFAULT_CACHE_NAME).getConfiguration(CacheConfiguration.class).getEvictionPolicy();
}
/**
* @param i Grid index.
* @return Policy.
*/
@SuppressWarnings({"unchecked"})
protected T nearPolicy(int i) {
CacheConfiguration cfg = grid(i).cache(DEFAULT_CACHE_NAME).getConfiguration(CacheConfiguration.class);
NearCacheConfiguration nearCfg = cfg.getNearConfiguration();
return (T)(nearCfg == null ? null : nearCfg.getNearEvictionPolicy());
}
/**
* @param c1 Policy collection.
* @param c2 Expected list.
*/
protected static void check(Collection<EvictableEntry<String, String>> c1, List<MockEntry> c2) {
assert c1.size() == c2.size() : "Mismatch [actual=" + string(c1) + ", expected=" + string(c2) + ']';
assert c1.containsAll(c2) : "Mismatch [actual=" + string(c1) + ", expected=" + string(c2) + ']';
int i = 0;
// Check order.
for (Cache.Entry<String, String> e : c1)
assertEquals(e, c2.get(i++));
}
/**
* @param c Collection.
* @return String.
*/
protected static String string(Iterable<? extends Cache.Entry> c) {
return "[" +
F.fold(
c,
"",
new C2<Cache.Entry, String, String>() {
@Override public String apply(Cache.Entry e, String b) {
return b.isEmpty() ? e.getKey().toString() : b + ", " + e.getKey();
}
}) +
"]]";
}
/** @throws Exception If failed. */
@Test
public void testMaxSizePartitionedNearDisabled() throws Exception {
mode = PARTITIONED;
nearEnabled = false;
plcMax = 10;
syncCommit = true;
gridCnt = 2;
checkPartitioned();
}
/** @throws Exception If failed. */
@Test
public void testMaxSizePartitionedNearDisabledWithBatch() throws Exception {
mode = PARTITIONED;
nearEnabled = false;
plcMax = 10;
plcBatchSize = 2;
syncCommit = true;
gridCnt = 2;
checkPartitioned();
}
/** @throws Exception If failed. */
@Test
public void testMaxMemSizePartitionedNearDisabled() throws Exception {
mode = PARTITIONED;
nearEnabled = false;
plcMax = 0;
plcMaxMemSize = 100;
syncCommit = true;
gridCnt = 2;
checkPartitioned();
}
/** @throws Exception If failed. */
@Test
public void testPartitionedNearEnabled() throws Exception {
mode = PARTITIONED;
nearEnabled = true;
nearMax = 3;
plcMax = 10;
syncCommit = true;
gridCnt = 2;
checkPartitioned(); // Near size is 0 because of backups present.
}
/** @throws Exception If failed. */
@Test
public void testPartitionedNearDisabledMultiThreaded() throws Exception {
mode = PARTITIONED;
nearEnabled = false;
plcMax = 100;
gridCnt = 2;
checkPartitionedMultiThreaded();
}
/** @throws Exception If failed. */
@Test
public void testPartitionedNearEnabledMultiThreaded() throws Exception {
mode = PARTITIONED;
nearEnabled = true;
plcMax = 10;
gridCnt = 2;
checkPartitionedMultiThreaded();
}
/**
* @throws Exception if failed.
*/
@Test
public void testEvictionPolicyMbeanValidity() throws Exception {
try {
Ignite ignite = startGrids(2);
//Instantiate policy object to know exact class.
EvictionPolicy plc = createPolicy(0);
validateMbeans(ignite, plc.getClass().getName());
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If failed.
*/
protected void checkPartitioned() throws Exception {
int endSize = nearEnabled ? 0 : plcMax;
int endPlcSize = nearEnabled ? 0 : plcMax;
startGridsMultiThreaded(gridCnt);
try {
Random rand = new Random();
int cnt = 500;
for (int i = 0; i < cnt; i++) {
IgniteCache<Integer, String> cache = grid(rand.nextInt(2)).cache(DEFAULT_CACHE_NAME);
int key = rand.nextInt(100);
String val = Integer.toString(key);
cache.put(key, val);
if (i % 100 == 0)
info("Stored cache object for key [key=" + key + ", idx=" + i + ']');
}
if (nearEnabled) {
for (int i = 0; i < gridCnt; i++)
assertEquals(endSize, near(i).nearSize());
if (endPlcSize >= 0)
checkNearPolicies(endPlcSize);
}
else {
if (plcMaxMemSize > 0) {
for (int i = 0; i < gridCnt; i++) {
GridDhtColocatedCache<Object, Object> cache = colocated(i);
int memSize = 0;
for (Cache.Entry<Object, Object> entry : cache.entrySet())
memSize += entry.unwrap(EvictableEntry.class).size();
EvictionPolicyProxy plc = proxy(policy(i));
assertTrue(plc.getCurrentMemorySize() <= memSize);
}
}
if (plcMax > 0) {
for (int i = 0; i < gridCnt; i++) {
int actual = colocated(i).map().internalSize();
assertTrue("Cache size is greater then policy size [expected=" + endSize + ", actual=" + actual + ']',
actual <= endSize + (plcMaxMemSize > 0 ? 1 : plcBatchSize));
}
}
checkPolicies();
}
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If failed.
*/
protected void checkPartitionedMultiThreaded() throws Exception {
try {
startGridsMultiThreaded(gridCnt);
final Random rand = new Random();
final AtomicInteger cntr = new AtomicInteger();
multithreaded(new Callable() {
@Nullable @Override public Object call() throws Exception {
int cnt = 100;
for (int i = 0; i < cnt && !Thread.currentThread().isInterrupted(); i++) {
IgniteEx grid = grid(rand.nextInt(2));
IgniteCache<Integer, String> cache = grid.cache(DEFAULT_CACHE_NAME);
int key = rand.nextInt(1000);
String val = Integer.toString(key);
try (Transaction tx = grid.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
String v = cache.get(key);
assert v == null || v.equals(Integer.toString(key)) : "Invalid value for key [key=" + key +
", val=" + v + ']';
cache.put(key, val);
tx.commit();
}
if (cntr.incrementAndGet() % 100 == 0)
info("Stored cache object for key [key=" + key + ", idx=" + i + ']');
}
return null;
}
}, 10);
}
finally {
stopAllGrids();
}
}
/**
* @param plcMax Policy max.
* @return Policy.
*/
protected abstract T createPolicy(int plcMax);
/**
* @param nearMax Near max.
* @return Policy.
*/
protected abstract T createNearPolicy(int nearMax);
/**
* Performs after-test near policy check.
*
* @param nearMax Near max.
*/
protected void checkNearPolicies(int nearMax) {
for (int i = 0; i < gridCnt; i++) {
EvictionPolicyProxy proxy = proxy(nearPolicy(i));
for (EvictableEntry e : proxy.queue())
assert !e.isCached() : "Invalid near policy size: " + proxy.queue();
}
}
/**
* Performs after-test policy check.
*/
protected void checkPolicies() {
for (int i = 0; i < gridCnt; i++) {
if (plcMaxMemSize > 0) {
int size = 0;
for (EvictableEntry entry : proxy(policy(i)).queue())
size += entry.size();
assertEquals(size, proxy(policy(i)).getCurrentMemorySize());
}
else
assertTrue(proxy(policy(i)).queue().size() <= plcMax + plcBatchSize);
}
}
/**
*
*/
protected static class MockEntry extends GridCacheMockEntry<String, String> {
/** Key size. */
public static final int KEY_SIZE = 1;
/** Value size. */
public static final int VALUE_SIZE = 1;
/** Entry size. */
public static final int ENTRY_SIZE = KEY_SIZE + VALUE_SIZE;
/** */
private IgniteCache<String, String> parent;
/** Entry value. */
private String val;
/** @param key Key. */
public MockEntry(String key) {
super(key);
}
/**
* @param key Key.
* @param val Value.
*/
public MockEntry(String key, String val) {
super(key);
this.val = val;
}
/**
* @param key Key.
* @param parent Parent.
*/
public MockEntry(String key, @Nullable IgniteCache<String, String> parent) {
super(key);
this.parent = parent;
}
/** {@inheritDoc} */
@Override public <T> T unwrap(Class<T> clazz) {
if (clazz.isAssignableFrom(IgniteCache.class))
return (T)parent;
return super.unwrap(clazz);
}
/** {@inheritDoc} */
@Override public String getValue() throws IllegalStateException {
return val;
}
/** {@inheritDoc} */
@Override public int size() {
return val == null ? KEY_SIZE : ENTRY_SIZE;
}
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(MockEntry.class, this, super.toString());
}
}
/**
* Rvicition policy proxy.
*/
public static class EvictionPolicyProxy implements EvictionPolicy {
/** Policy. */
private final EvictionPolicy plc;
/**
* @param plc Policy.
*/
private EvictionPolicyProxy(EvictionPolicy plc) {
this.plc = plc;
}
/**
* @param plc Policy.
* @return Policy proxy.
*/
public static EvictionPolicyProxy proxy(EvictionPolicy plc) {
return new EvictionPolicyProxy(plc);
}
/**
* @return Get current size.
*/
int getCurrentSize() {
try {
return (Integer)plc.getClass().getDeclaredMethod("getCurrentSize").invoke(plc);
}
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* @return Current memory size.
*/
long getCurrentMemorySize() {
try {
return (Long)plc.getClass().getMethod("getCurrentMemorySize").invoke(plc);
}
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* @return Current queue.
*/
public Collection<EvictableEntry> queue() {
try {
return (Collection<EvictableEntry>)plc.getClass().getDeclaredMethod("queue").invoke(plc);
}
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* @param rmv Remove.
* @param entry Entry.
*/
@Override public void onEntryAccessed(boolean rmv, EvictableEntry entry) {
try {
plc.getClass()
.getMethod("onEntryAccessed", boolean.class, EvictableEntry.class)
.invoke(plc, rmv, entry);
}
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}