Repository: incubator-ignite Updated Branches: refs/heads/ignite-446 315e84411 -> 56196599d
ignite-485 Need to implement CacheSortedEvictionPolicy Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/fabe1a69 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/fabe1a69 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/fabe1a69 Branch: refs/heads/ignite-446 Commit: fabe1a69f318e97000a365419ff7098a272a14a0 Parents: 80b1e05 Author: agura <ag...@gridgain.com> Authored: Wed Apr 15 20:46:21 2015 +0300 Committer: agura <ag...@gridgain.com> Committed: Thu Apr 16 20:35:57 2015 +0300 ---------------------------------------------------------------------- .../eviction/sorted/SortedEvictionPolicy.java | 399 +++++++++++++++++++ .../sorted/SortedEvictionPolicyMBean.java | 50 +++ .../cache/eviction/sorted/package-info.java | 21 + .../GridSortedEvictionPolicySelfTest.java | 373 +++++++++++++++++ .../IgniteCacheEvictionSelfTestSuite.java | 2 + 5 files changed, 845 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fabe1a69/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicy.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicy.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicy.java new file mode 100644 index 0000000..b3f3119 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicy.java @@ -0,0 +1,399 @@ +/* + * 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.cache.eviction.sorted; + +import org.apache.ignite.cache.eviction.*; +import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.typedef.internal.*; + +import org.jetbrains.annotations.*; +import org.jsr166.*; + +import java.io.*; +import java.util.*; +import java.util.concurrent.atomic.*; + +import static java.lang.Math.*; +import static org.apache.ignite.configuration.CacheConfiguration.*; + +/** + * Cache eviction policy which will select the minimum cache entry for eviction if cache + * size exceeds the {@link #getMaxSize()} parameter. Entries comparison based on {@link Comparator} instance if provided. + * Default {@code Comparator} behaviour is use cache entries keys for comparison that imposes a requirement for keys + * to implement {@link Comparable} interface. + */ +public class SortedEvictionPolicy<K, V> implements EvictionPolicy<K, V>, SortedEvictionPolicyMBean, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Maximum size. */ + private volatile int max; + + /** Order. */ + private final AtomicLong orderCnt = new AtomicLong(); + + /** Backed sorted set. */ + private final GridConcurrentSkipListSetEx<Holder<K, V>> set; + + /** + * Constructs sorted eviction policy with all defaults. + */ + public SortedEvictionPolicy() { + this(DFLT_CACHE_SIZE, null); + } + + /** + * Constructs sorted eviction policy with maximum size. + * + * @param max Maximum allowed size of cache before entry will start getting evicted. + */ + public SortedEvictionPolicy(int max) { + this(max, null); + } + + /** + * Constructs sorted eviction policy with default maximum size and given entry comparator. + * + * @param comp Entries comparator. + */ + public SortedEvictionPolicy(Comparator<EvictableEntry<K, V>> comp) { + this(DFLT_CACHE_SIZE, comp); + } + + /** + * Constructs sorted eviction policy with given maximum size and entries comparator. + * + * @param max Maximum allowed size of cache before entry will start getting evicted. + * @param comp Entries comparator. + */ + public SortedEvictionPolicy(int max, Comparator<EvictableEntry<K, V>> comp) { + A.ensure(max > 0, "max > 0"); + + this.max = max; + this.set = new GridConcurrentSkipListSetEx<>( + comp == null ? new DefaultHolderComparator<K, V>() : new HolderComparator<>(comp)); + } + + /** + * Gets maximum allowed size of cache before entry will start getting evicted. + * + * @return Maximum allowed size of cache before entry will start getting evicted. + */ + @Override public int getMaxSize() { + return max; + } + + /** + * Sets maximum allowed size of cache before entry will start getting evicted. + * + * @param max Maximum allowed size of cache before entry will start getting evicted. + */ + @Override public void setMaxSize(int max) { + A.ensure(max > 0, "max > 0"); + + this.max = max; + } + + /** {@inheritDoc} */ + @Override public int getCurrentSize() { + return set.sizex(); + } + + /** + * Gets read-only view of backed set in proper order. + * + * @return Read-only view of backed set. + */ + public Collection<EvictableEntry<K, V>> set() { + Set<EvictableEntry<K, V>> cp = new LinkedHashSet<>(); + + for (Holder<K, V> holder : set) + cp.add(holder.entry); + + return Collections.unmodifiableCollection(cp); + } + + /** {@inheritDoc} */ + @Override public void onEntryAccessed(boolean rmv, EvictableEntry<K, V> entry) { + if (!rmv) { + if (!entry.isCached()) + return; + + if (touch(entry)) + shrink(); + } + else { + Holder<K, V> holder = entry.removeMeta(); + + if (holder != null) + removeHolder(holder); + } + } + + /** + * @param entry Entry to touch. + * @return {@code True} if backed set has been changed by this call. + */ + private boolean touch(EvictableEntry<K, V> entry) { + Holder<K, V> holder = entry.meta(); + + // Entry has not been add yet to backed set.. + if (holder == null) { + while (true) { + holder = new Holder<>(entry, orderCnt.incrementAndGet()); + + set.add(holder); + + if (entry.putMetaIfAbsent(holder) != null) { + // Was concurrently added, need to remove it from set. + removeHolder(holder); + + // Set has not been changed. + return false; + } + else if (holder.order > 0) { + if (!entry.isCached()) { + // Was concurrently evicted, need to remove it from set. + removeHolder(holder); + + return false; + } + + return true; + } + // If holder was removed by concurrent shrink() call, we must repeat the whole cycle. + else if (!entry.removeMeta(holder)) + return false; + } + } + + // Entry is already in queue. + return false; + } + + /** + * Shrinks backed set to maximum allowed size. + */ + private void shrink() { + int max = this.max; + + int startSize = set.sizex(); + + if (startSize > max) { + for (int i = max; i < startSize && set.sizex() > max; i++) { + Holder<K, V> h = set.pollFirst(); + + if (h == null) + break; + + EvictableEntry<K, V> entry = h.entry; + + if (h.order > 0 && !entry.evict()) { + entry.removeMeta(); + + touch(entry); + } + } + } + } + + /** + * Removes holder from backed set and marks holder as removed. + * + * @param holder Holder. + */ + private void removeHolder(Holder<K, V> holder) { + long order0 = holder.order; + + if (order0 > 0) + holder.order = -order0; + + set.remove(holder); + } + + /** + * Evictable entry holder. + */ + private static class Holder<K, V> { + /** Entry. */ + private final EvictableEntry<K, V> entry; + + /** Order needs for distinguishing keys that are equal. */ + private volatile long order; + + /** + * Constructs holder for given key. + * + * @param entry Entry. + * @param order Order. + */ + public Holder(EvictableEntry<K, V> entry, long order) { + assert order > 0; + + this.entry = entry; + this.order = order; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return entry.hashCode(); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null || this.getClass() != obj.getClass()) + return false; + + Holder<K, V> h = (Holder<K, V>) obj; + + return Objects.equals(entry, h.entry) && abs(order) == abs(h.order); + } + } + + /** + * Evictable entries holder comparator. Wrapper for client's comparator. + */ + private static class HolderComparator<K, V> implements Comparator<Holder<K, V>>, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Keys comparator. */ + private final Comparator<EvictableEntry<K, V>> comp; + + /** + * @param comp Comparator. + */ + public HolderComparator(Comparator<EvictableEntry<K, V>> comp) { + A.notNull(comp, "comp"); + + this.comp = comp; + } + + /** {@inheritDoc} */ + @Override public int compare(Holder<K, V> h1, Holder<K, V> h2) { + if (h1 == h2) + return 0; + + EvictableEntry<K, V> e1 = h1.entry; + EvictableEntry<K, V> e2 = h2.entry; + + int cmp = comp.compare(e1, e2); + + return cmp == 0 ? Long.compare(abs(h1.order), abs(h2.order)) : cmp; + } + } + + /** + * Default comparator. Uses if comparator isn't provided by client. + * Compares only entry keys that should implements {@link Comparable} interface. + */ + private static class DefaultHolderComparator<K, V> implements Comparator<Holder<K, V>>, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public int compare(Holder<K, V> h1, Holder<K, V> h2) { + if (h1 == h2) + return 0; + + EvictableEntry<K, V> e1 = h1.entry; + EvictableEntry<K, V> e2 = h2.entry; + + int cmp = ((Comparable<K>) e1.getKey()).compareTo(e2.getKey()); + + return cmp == 0 ? Long.compare(abs(h1.order), abs(h2.order)) : cmp; + } + } + + /** + * Provides additional method {@code #sizex()}. NOTE: Only the following methods supports this addition: + * <ul> + * <li>{@code #add()}</li> + * <li>{@code #remove()}</li> + * <li>{@code #pollFirst()}</li> + * <li>{@code #clone()}</li> + * <ul/> + */ + private static class GridConcurrentSkipListSetEx<E> extends GridConcurrentSkipListSet<E> { + /** */ + private static final long serialVersionUID = 0L; + + /** Size. */ + private volatile LongAdder8 size = new LongAdder8(); + + /** + * @param comp Comparator. + */ + public GridConcurrentSkipListSetEx(Comparator<? super E> comp) { + super(comp); + } + + /** + * @return Size based on performed operations. + */ + public int sizex() { + return size.intValue(); + } + + /** {@inheritDoc} */ + @Override public boolean add(E e) { + boolean res = super.add(e); + + if (res) + size.increment(); + + return res; + } + + /** {@inheritDoc} */ + @Override public boolean remove(Object o) { + boolean res = super.remove(o); + + if (res) + size.decrement(); + + return res; + } + + /** {@inheritDoc} */ + @Nullable @Override public E pollFirst() { + E e = super.pollFirst(); + + if (e != null) + size.decrement(); + + return e; + } + + /** {@inheritDoc} */ + @Override public GridConcurrentSkipListSetEx<E> clone() { + GridConcurrentSkipListSetEx<E> clone = (GridConcurrentSkipListSetEx<E>)super.clone(); + + clone.size = new LongAdder8(); + + clone.size.add(size.intValue()); + + return clone; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fabe1a69/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicyMBean.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicyMBean.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicyMBean.java new file mode 100644 index 0000000..f8b0d23 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/SortedEvictionPolicyMBean.java @@ -0,0 +1,50 @@ +/* + * 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.cache.eviction.sorted; + +import org.apache.ignite.mxbean.*; + +/** + * MBean for sorted eviction policy. + */ +@MXBeanDescription("MBean for sorted cache eviction policy.") +public interface SortedEvictionPolicyMBean { + /** + * Gets maximum allowed cache size. + * + * @return Maximum allowed cache size. + */ + @MXBeanDescription("Maximum allowed cache size.") + public int getMaxSize(); + + /** + * Sets maximum allowed cache size. + * + * @param max Maximum allowed cache size. + */ + @MXBeanDescription("Set maximum allowed cache size.") + public void setMaxSize(int max); + + /** + * Gets current size. + * + * @return Current size. + */ + @MXBeanDescription("Current sorted key set size.") + public int getCurrentSize(); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fabe1a69/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/package-info.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/package-info.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/package-info.java new file mode 100644 index 0000000..5d59333 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/sorted/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Contains cache sorted eviction policy implementation. + */ +package org.apache.ignite.cache.eviction.sorted; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fabe1a69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/sorted/GridSortedEvictionPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/sorted/GridSortedEvictionPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/sorted/GridSortedEvictionPolicySelfTest.java new file mode 100644 index 0000000..5e255a1 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/sorted/GridSortedEvictionPolicySelfTest.java @@ -0,0 +1,373 @@ +/* + * 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.sorted; + +import org.apache.ignite.*; +import org.apache.ignite.cache.eviction.*; +import org.apache.ignite.cache.eviction.sorted.*; +import org.apache.ignite.internal.processors.cache.eviction.*; + +import java.util.*; + +import static org.apache.ignite.cache.CacheMode.*; + +/** + * Sorted eviction test. + */ +public class GridSortedEvictionPolicySelfTest extends + GridCacheEvictionAbstractTest<SortedEvictionPolicy<String, String>> { + /** + * @throws Exception If failed. + */ + public void testPolicy() throws Exception { + try { + startGrid(); + + MockEntry e1 = new MockEntry("1", "1"); + MockEntry e2 = new MockEntry("2", "2"); + MockEntry e3 = new MockEntry("3", "3"); + MockEntry e4 = new MockEntry("4", "4"); + MockEntry e5 = new MockEntry("5", "5"); + + SortedEvictionPolicy<String, String> p = policy(); + + p.setMaxSize(3); + + p.onEntryAccessed(false, e1); + + check(p.set(), e1); + + p.onEntryAccessed(false, e2); + + check(p.set(), e1, e2); + + p.onEntryAccessed(false, e3); + + check(p.set(), e1, e2, e3); + + assertFalse(e1.isEvicted()); + assertFalse(e2.isEvicted()); + assertFalse(e3.isEvicted()); + + assertEquals(3, p.getCurrentSize()); + + p.onEntryAccessed(false, e4); + + check(p.set(), e2, e3, e4); + + assertEquals(3, p.getCurrentSize()); + + assertTrue(e1.isEvicted()); + assertFalse(e2.isEvicted()); + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + + p.onEntryAccessed(false, e5); + + check(p.set(), e3, e4, e5); + + assertEquals(3, p.getCurrentSize()); + + assertTrue(e2.isEvicted()); + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + assertFalse(e5.isEvicted()); + + p.onEntryAccessed(false, e1 = new MockEntry("1", "1")); + + check(p.set(), e3, e4, e5); + + assertEquals(3, p.getCurrentSize()); + + assertTrue(e1.isEvicted()); + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + assertFalse(e5.isEvicted()); + + p.onEntryAccessed(false, e5); + + check(p.set(), e3, e4, e5); + + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + assertFalse(e5.isEvicted()); + + p.onEntryAccessed(false, e1); + + assertEquals(3, p.getCurrentSize()); + + check(p.set(), e3, e4, e5); + + assertTrue(e1.isEvicted()); + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + assertFalse(e5.isEvicted()); + + p.onEntryAccessed(false, e5); + + assertEquals(3, p.getCurrentSize()); + + check(p.set(), e3, e4, e5); + + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + assertFalse(e5.isEvicted()); + + p.onEntryAccessed(true, e3); + + assertEquals(2, p.getCurrentSize()); + + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + assertFalse(e5.isEvicted()); + + p.onEntryAccessed(true, e4); + + assertEquals(1, p.getCurrentSize()); + + assertFalse(e4.isEvicted()); + assertFalse(e5.isEvicted()); + + p.onEntryAccessed(true, e5); + + assertEquals(0, p.getCurrentSize()); + + assertFalse(e5.isEvicted()); + + info(p); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testMemory() throws Exception { + try { + startGrid(); + + SortedEvictionPolicy<String, String> p = policy(); + + int max = 10; + + p.setMaxSize(max); + + int cnt = 11; + + for (int i = 0; i < cnt; i++) + p.onEntryAccessed(false, new MockEntry(Integer.toString(i), Integer.toString(i))); + + info(p); + + assertEquals(max, p.getCurrentSize()); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testRandom() throws Exception { + try { + startGrid(); + + SortedEvictionPolicy<String, String> p = policy(); + + int max = 10; + + p.setMaxSize(max); + + Random rand = new Random(); + + int keys = 31; + + MockEntry[] fifos = new MockEntry[keys]; + + for (int i = 0; i < fifos.length; i++) + fifos[i] = new MockEntry(Integer.toString(i)); + + int runs = 5000000; + + for (int i = 0; i < runs; i++) { + boolean rmv = rand.nextBoolean(); + + int j = rand.nextInt(fifos.length); + + MockEntry e = entry(fifos, j); + + if (rmv) + fifos[j] = new MockEntry(Integer.toString(j)); + + p.onEntryAccessed(rmv, e); + } + + info(p); + + int curSize = p.getCurrentSize(); + + assertTrue("curSize <= max [curSize=" + curSize + ", max=" + max + ']', curSize <= max); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testAllowEmptyEntries() 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"); + + SortedEvictionPolicy<String, String> p = policy(); + + p.setMaxSize(10); + + p.onEntryAccessed(false, e1); + + assertFalse(e1.isEvicted()); + + p.onEntryAccessed(false, e2); + + assertFalse(e1.isEvicted()); + assertFalse(e2.isEvicted()); + + p.onEntryAccessed(false, e3); + + assertFalse(e1.isEvicted()); + assertFalse(e3.isEvicted()); + + p.onEntryAccessed(false, e4); + + assertFalse(e1.isEvicted()); + assertFalse(e3.isEvicted()); + assertFalse(e4.isEvicted()); + + p.onEntryAccessed(false, e5); + + assertFalse(e1.isEvicted()); + assertFalse(e3.isEvicted()); + assertFalse(e5.isEvicted()); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testPut() throws Exception { + mode = LOCAL; + syncCommit = true; + plcMax = 100; + + Ignite ignite = startGrid(); + + try { + IgniteCache<Object, Object> cache = ignite.cache(null); + + 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 > plcMax && cacheSize < min) { + min = cacheSize; + minIdx = i; + } + } + + assertTrue("Min cache size is too small: " + min, min >= plcMax); + + 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 - plcMax;) { + 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()); + + assertTrue("Min cache size is too small: " + min, min >= plcMax); + } + finally { + stopAllGrids(); + } + } + + /** {@inheritDoc} */ + @Override protected SortedEvictionPolicy<String, String> createPolicy(int plcMax) { + return new SortedEvictionPolicy<>(plcMax); + } + + /** {@inheritDoc} */ + @Override protected SortedEvictionPolicy<String, String> createNearPolicy(int nearMax) { + return new SortedEvictionPolicy<>(nearMax); + } + + /** {@inheritDoc} */ + @Override protected void checkNearPolicies(int endNearPlcSize) { + for (int i = 0; i < gridCnt; i++) + for (EvictableEntry<String, String> e : nearPolicy(i).set()) + assert !e.isCached() : "Invalid near policy size: " + nearPolicy(i).set(); + } + + /** {@inheritDoc} */ + @Override protected void checkPolicies(int plcMax) { + for (int i = 0; i < gridCnt; i++) + assert policy(i).set().size() <= plcMax; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fabe1a69/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheEvictionSelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheEvictionSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheEvictionSelfTestSuite.java index 1037b54..2c0c46d 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheEvictionSelfTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheEvictionSelfTestSuite.java @@ -24,6 +24,7 @@ import org.apache.ignite.internal.processors.cache.eviction.*; import org.apache.ignite.internal.processors.cache.eviction.fifo.*; import org.apache.ignite.internal.processors.cache.eviction.lru.*; import org.apache.ignite.internal.processors.cache.eviction.random.*; +import org.apache.ignite.internal.processors.cache.eviction.sorted.*; /** * Test suite for cache eviction. @@ -38,6 +39,7 @@ public class IgniteCacheEvictionSelfTestSuite extends TestSuite { suite.addTest(new TestSuite(GridCacheFifoEvictionPolicySelfTest.class)); suite.addTest(new TestSuite(GridCacheFifoBatchEvictionPolicySelfTest.class)); + suite.addTest(new TestSuite(GridSortedEvictionPolicySelfTest.class)); suite.addTest(new TestSuite(GridCacheLruEvictionPolicySelfTest.class)); suite.addTest(new TestSuite(GridCacheLruNearEvictionPolicySelfTest.class)); suite.addTest(new TestSuite(GridCacheNearOnlyLruNearEvictionPolicySelfTest.class));