http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheEvictionTouchSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheEvictionTouchSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheEvictionTouchSelfTest.java new file mode 100644 index 0000000..8d8a480 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheEvictionTouchSelfTest.java @@ -0,0 +1,347 @@ +/* + * 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 org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.affinity.*; +import org.apache.ignite.cache.eviction.*; +import org.apache.ignite.cache.eviction.fifo.*; +import org.apache.ignite.cache.store.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.transactions.*; +import org.gridgain.grid.kernal.processors.cache.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.testframework.junits.common.*; + +import javax.cache.configuration.*; +import java.util.*; + +import static org.apache.ignite.cache.GridCacheMode.*; +import static org.apache.ignite.transactions.IgniteTxConcurrency.*; +import static org.apache.ignite.transactions.IgniteTxIsolation.*; +import static org.apache.ignite.cache.GridCacheWriteSynchronizationMode.*; + +/** + * + */ +public class GridCacheEvictionTouchSelfTest extends GridCommonAbstractTest { + /** IP finder. */ + private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** */ + private GridCacheEvictionPolicy<?, ?> plc; + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration c = super.getConfiguration(gridName); + + TransactionsConfiguration txCfg = c.getTransactionsConfiguration(); + + txCfg.setDefaultTxConcurrency(PESSIMISTIC); + txCfg.setDefaultTxIsolation(REPEATABLE_READ); + + CacheConfiguration cc = defaultCacheConfiguration(); + + cc.setCacheMode(REPLICATED); + + cc.setSwapEnabled(false); + + cc.setWriteSynchronizationMode(FULL_SYNC); + + cc.setEvictionPolicy(plc); + + CacheStore store = new GridCacheGenericTestStore<Object, Object>() { + @Override public Object load(Object key) { + return key; + } + + @Override public Map<Object, Object> loadAll(Iterable<?> keys) { + Map<Object, Object> loaded = new HashMap<>(); + + for (Object key : keys) + loaded.put(key, key); + + return loaded; + } + }; + + cc.setCacheStoreFactory(new FactoryBuilder.SingletonFactory(store)); + cc.setReadThrough(true); + cc.setWriteThrough(true); + cc.setLoadPreviousValue(true); + + c.setCacheConfiguration(cc); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + + disco.setIpFinder(ipFinder); + + c.setDiscoverySpi(disco); + + return c; + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + plc = null; + + super.afterTest(); + } + + /** + * @throws Exception If failed. + */ + public void testPolicyConsistency() throws Exception { + plc = new GridCacheFifoEvictionPolicy<Object, Object>(500); + + try { + Ignite ignite = startGrid(1); + + final GridCache<Integer, Integer> cache = ignite.cache(null); + + final Random rnd = new Random(); + + try (IgniteTx tx = cache.txStart()) { + int iterCnt = 20; + int keyCnt = 5000; + + for (int i = 0; i < iterCnt; i++) { + int j = rnd.nextInt(keyCnt); + + // Put or remove? + if (rnd.nextBoolean()) + cache.putx(j, j); + else + cache.remove(j); + + if (i != 0 && i % 1000 == 0) + info("Stats [iterCnt=" + i + ", size=" + cache.size() + ']'); + } + + GridCacheFifoEvictionPolicy<Integer, Integer> plc0 = (GridCacheFifoEvictionPolicy<Integer, Integer>) plc; + + if (!plc0.queue().isEmpty()) { + for (GridCacheEntry<Integer, Integer> e : plc0.queue()) + U.warn(log, "Policy queue item: " + e); + + fail("Test failed, see logs for details."); + } + + tx.commit(); + } + } + catch (Throwable t) { + error("Test failed.", t); + + fail("Test failed, see logs for details."); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testEvictSingle() throws Exception { + plc = new GridCacheFifoEvictionPolicy<Object, Object>(500); + + try { + Ignite ignite = startGrid(1); + + final GridCache<Integer, Integer> cache = ignite.cache(null); + + for (int i = 0; i < 100; i++) + cache.put(i, i); + + assertEquals(100, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + + for (int i = 0; i < 100; i++) + cache.evict(i); + + assertEquals(0, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + assertEquals(0, cache.size()); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testEvictAll() throws Exception { + plc = new GridCacheFifoEvictionPolicy<Object, Object>(500); + + try { + Ignite ignite = startGrid(1); + + final GridCache<Integer, Integer> cache = ignite.cache(null); + + Collection<Integer> keys = new ArrayList<>(100); + + for (int i = 0; i < 100; i++) { + cache.put(i, i); + + keys.add(i); + } + + assertEquals(100, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + + cache.evictAll(keys); + + assertEquals(0, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + assertEquals(0, cache.size()); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testGroupLock() throws Exception { + plc = new GridCacheFifoEvictionPolicy<>(100); + + try { + Ignite g = startGrid(1); + + Integer affKey = 1; + + GridCache<GridCacheAffinityKey<Object>, Integer> cache = g.cache(null); + + IgniteTx tx = cache.txStartAffinity(affKey, PESSIMISTIC, REPEATABLE_READ, 0, 5); + + try { + for (int i = 0; i < 5; i++) + cache.put(new GridCacheAffinityKey<Object>(i, affKey), i); + + tx.commit(); + } + finally { + tx.close(); + } + + assertEquals(5, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + + tx = cache.txStartAffinity(affKey, PESSIMISTIC, REPEATABLE_READ, 0, 5); + + try { + for (int i = 0; i < 5; i++) + cache.remove(new GridCacheAffinityKey<Object>(i, affKey)); + + tx.commit(); + } + finally { + tx.close(); + } + + assertEquals(0, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testPartitionGroupLock() throws Exception { + plc = new GridCacheFifoEvictionPolicy<>(100); + + try { + Ignite g = startGrid(1); + + Integer affKey = 1; + + GridCache<Object, Integer> cache = g.cache(null); + + IgniteTx tx = cache.txStartPartition(cache.affinity().partition(affKey), PESSIMISTIC, REPEATABLE_READ, + 0, 5); + + try { + for (int i = 0; i < 5; i++) + cache.put(new GridCacheAffinityKey<Object>(i, affKey), i); + + tx.commit(); + } + finally { + tx.close(); + } + + assertEquals(5, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + + tx = cache.txStartPartition(cache.affinity().partition(affKey), PESSIMISTIC, REPEATABLE_READ, 0, 5); + + try { + for (int i = 0; i < 5; i++) + cache.remove(new GridCacheAffinityKey<Object>(i, affKey)); + + tx.commit(); + } + finally { + tx.close(); + } + + assertEquals(0, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testReload() throws Exception { + plc = new GridCacheFifoEvictionPolicy<Object, Object>(100); + + try { + Ignite ignite = startGrid(1); + + final GridCache<Integer, Integer> cache = ignite.cache(null); + + for (int i = 0; i < 10000; i++) + cache.reload(i); + + assertEquals(100, cache.size()); + assertEquals(100, cache.size()); + assertEquals(100, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + + Collection<Integer> keys = new ArrayList<>(10000); + + for (int i = 0; i < 10000; i++) + keys.add(i); + + cache.reloadAll(keys); + + assertEquals(100, cache.size()); + assertEquals(100, cache.size()); + assertEquals(100, ((GridCacheFifoEvictionPolicy)plc).queue().size()); + } + finally { + stopAllGrids(); + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheMockEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheMockEntry.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheMockEntry.java new file mode 100644 index 0000000..372feab --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheMockEntry.java @@ -0,0 +1,365 @@ +/* + * 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 org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.lang.*; +import org.apache.ignite.internal.util.future.*; +import org.apache.ignite.internal.util.lang.*; +import org.apache.ignite.internal.util.tostring.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.jetbrains.annotations.*; + +import java.util.*; + +/** + * Mock cache entry. + */ +public class GridCacheMockEntry<K, V> extends GridMetadataAwareAdapter implements GridCacheEntry<K, V> { + /** */ + @GridToStringInclude + private K key; + + /** */ + @GridToStringInclude + private boolean evicted; + + /** */ + @GridToStringInclude + private boolean canEvict = true; + + /** + * Constructor. + * + * @param key Key. + */ + public GridCacheMockEntry(K key) { + this.key = key; + } + + /** + * Constructor. + * + * @param key Key. + * @param canEvict Evict or not. + */ + public GridCacheMockEntry(K key, boolean canEvict) { + this.key = key; + this.canEvict = canEvict; + } + + /** {@inheritDoc} */ + @Override public K getKey() throws IllegalStateException { + return key; + } + + /** {@inheritDoc} */ + @Override public V getValue() throws IllegalStateException { + return null; + } + + /** {@inheritDoc} */ + @Override public V setValue(V val) { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean evict() { + evicted = true; + + onEvicted(); + + return canEvict; + } + + /** + * Eviction callback. + */ + public void onEvicted() { + for (String key : allMeta().keySet()) + removeMeta(key); + } + + /** + * + * @return Evicted or not. + */ + public boolean isEvicted() { + return evicted; + } + + /** {@inheritDoc} */ + @Override public V peek() { + return null; + } + + /** {@inheritDoc} */ + @Override public V peek(@Nullable Collection<GridCachePeekMode> modes) { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean isLocked() { + return false; + } + + /** {@inheritDoc} */ + @Override public boolean isLockedByThread() { + return false; + } + + /** {@inheritDoc} */ + @Nullable @Override public Object version() { + return null; + } + + /** {@inheritDoc} */ + @Override public long expirationTime() { + return 0; + } + + /** {@inheritDoc} */ + @Override public long timeToLive() { + return 0; + } + + /** {@inheritDoc} */ + @Override public boolean primary() { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Override public boolean backup() { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Override public int partition() { + return 0; + } + + /** {@inheritDoc} */ + @Nullable @Override public V set(V val, + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) throws IgniteCheckedException { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<V> setAsync(V val, + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public V setIfAbsent(V val) throws IgniteCheckedException { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<V> setIfAbsentAsync(V val) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Override public boolean setx(V val, + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) throws IgniteCheckedException { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<Boolean> setxAsync(V val, + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Override public boolean setxIfAbsent(@Nullable V val) throws IgniteCheckedException { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<Boolean> setxIfAbsentAsync(V val) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public V replace(V val) throws IgniteCheckedException { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<V> replaceAsync(V val) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Override public boolean replacex(V val) throws IgniteCheckedException { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<Boolean> replacexAsync(V val) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Override public boolean replace(V oldVal, V newVal) throws IgniteCheckedException { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<Boolean> replaceAsync(V oldVal, V newVal) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public V remove( + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) throws IgniteCheckedException { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<V> removeAsync( + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Override public boolean removex(@Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) throws IgniteCheckedException { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<Boolean> removexAsync( + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Override public boolean remove(V val) throws IgniteCheckedException { + // No-op. + return false; + } + + /** {@inheritDoc} */ + @Nullable @Override public IgniteFuture<Boolean> removeAsync(V val) { + // No-op. + return null; + } + + /** {@inheritDoc} */ + @Override public void timeToLive(long ttl) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public boolean lock(long timeout, + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) throws IgniteCheckedException { + return false; + } + + /** {@inheritDoc} */ + @Override public IgniteFuture<Boolean> lockAsync(long timeout, + @Nullable IgnitePredicate<GridCacheEntry<K, V>>... filter) { + return new GridFinishedFuture<>(null, false); + } + + /** {@inheritDoc} */ + @Override public void unlock(IgnitePredicate<GridCacheEntry<K, V>>... filter) throws IgniteCheckedException { + // No-op. + } + + /** {@inheritDoc} */ + @Override public boolean isCached() { + return !evicted; + } + + /** {@inheritDoc} */ + @Override public int memorySize() { + return 1024; + } + + /** {@inheritDoc} */ + @Override public GridCacheProjection<K, V> projection() { + return null; + } + + /** {@inheritDoc} */ + @Nullable @Override public V reload() throws IgniteCheckedException { + return null; + } + + /** {@inheritDoc} */ + @Override public IgniteFuture<V> reloadAsync() { + return new GridFinishedFuture<>(); + } + + /** {@inheritDoc} */ + @Nullable @Override public V get() throws IgniteCheckedException { + return null; + } + + /** {@inheritDoc} */ + @Override public IgniteFuture<V> getAsync() { + return new GridFinishedFuture<>(); + } + + /** {@inheritDoc} */ + @Override public boolean clear() { + return false; + } + + /** {@inheritDoc} */ + @Override public boolean compact() throws IgniteCheckedException { + return false; + } + + /** {@inheritDoc} */ + @Override public <T> T unwrap(Class<T> clazz) { + if(clazz.isAssignableFrom(getClass())) + return clazz.cast(this); + + throw new IllegalArgumentException(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridCacheMockEntry.class, this); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheSynchronousEvictionsFailoverSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheSynchronousEvictionsFailoverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheSynchronousEvictionsFailoverSelfTest.java new file mode 100644 index 0000000..dc69ffe --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/GridCacheSynchronousEvictionsFailoverSelfTest.java @@ -0,0 +1,160 @@ +/* + * 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 org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.affinity.*; +import org.apache.ignite.cache.affinity.consistenthash.*; +import org.apache.ignite.cluster.*; +import org.apache.ignite.lang.*; +import org.gridgain.grid.kernal.processors.cache.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.testframework.*; + +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +import static org.apache.ignite.cache.GridCacheDistributionMode.*; +import static org.apache.ignite.cache.GridCacheMode.*; + +/** + * + */ +public class GridCacheSynchronousEvictionsFailoverSelfTest extends GridCacheAbstractSelfTest { + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 3; + } + + /** {@inheritDoc} */ + @Override protected GridCacheMode cacheMode() { + return PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } + + /** {@inheritDoc} */ + @Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception { + CacheConfiguration ccfg = super.cacheConfiguration(gridName); + + ccfg.setSwapEnabled(false); + ccfg.setEvictSynchronized(true); + ccfg.setEvictSynchronizedKeyBufferSize(10); + + ccfg.setBackups(2); + + ccfg.setAffinity(new GridCacheConsistentHashAffinityFunction(false, 500)); + + return ccfg; + } + + /** {@inheritDoc} */ + @Override protected long getTestTimeout() { + return 60_000; + } + + /** + * @throws Exception If failed. + */ + public void testSynchronousEvictions() throws Exception { + GridCache<String, Integer> cache = cache(0); + + final AtomicBoolean stop = new AtomicBoolean(); + + IgniteFuture<?> fut = null; + + try { + Map<String, Integer> data = new HashMap<>(); + + addKeysForNode(cache.affinity(), grid(0).localNode(), data); + addKeysForNode(cache.affinity(), grid(1).localNode(), data); + addKeysForNode(cache.affinity(), grid(2).localNode(), data); + + fut = GridTestUtils.runAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + Random rnd = new Random(); + + while (!stop.get()) { + int idx = rnd.nextBoolean() ? 1 : 2; + + log.info("Stopping grid: " + idx); + + stopGrid(idx); + + U.sleep(100); + + log.info("Starting grid: " + idx); + + startGrid(idx); + } + + return null; + } + }); + + for (int i = 0 ; i < 100; i++) { + log.info("Iteration: " + i); + + try { + cache.putAll(data); + } + catch (IgniteCheckedException ignore) { + continue; + } + + for (String key : data.keySet()) + cache.evict(key); + } + } + finally { + stop.set(true); + + if (fut != null) + fut.get(); + } + } + + /** + * @param aff Cache affinity. + * @param node Primary node for keys. + * @param data Map where keys/values should be put to. + */ + private void addKeysForNode(GridCacheAffinity<String> aff, ClusterNode node, Map<String, Integer> data) { + int cntr = 0; + + for (int i = 0; i < 100_000; i++) { + String key = String.valueOf(i); + + if (aff.isPrimary(node, key)) { + data.put(key, i); + + cntr++; + + if (cntr == 500) + break; + } + } + + assertEquals(500, cntr); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/fifo/GridCacheFifoEvictionPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/fifo/GridCacheFifoEvictionPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/fifo/GridCacheFifoEvictionPolicySelfTest.java new file mode 100644 index 0000000..828b73f --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/fifo/GridCacheFifoEvictionPolicySelfTest.java @@ -0,0 +1,380 @@ +/* + * 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.fifo; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.fifo.*; +import org.apache.ignite.internal.processors.cache.eviction.*; + +import java.util.*; + +import static org.apache.ignite.cache.GridCacheMode.*; + +/** + * FIFO Eviction test. + */ +@SuppressWarnings({"TypeMayBeWeakened"}) +public class GridCacheFifoEvictionPolicySelfTest extends + GridCacheEvictionAbstractTest<GridCacheFifoEvictionPolicy<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"); + + GridCacheFifoEvictionPolicy<String, String> p = policy(); + + p.setMaxSize(3); + + p.onEntryAccessed(false, e1); + + check(p.queue(), e1); + + p.onEntryAccessed(false, e2); + + check(p.queue(), e1, e2); + + p.onEntryAccessed(false, e3); + + check(p.queue(), e1, e2, e3); + + assert !e1.isEvicted(); + assert !e2.isEvicted(); + assert !e3.isEvicted(); + + assertEquals(3, p.getCurrentSize()); + + p.onEntryAccessed(false, e4); + + check(p.queue(), e2, e3, e4); + + assertEquals(3, p.getCurrentSize()); + + assert e1.isEvicted(); + assert !e2.isEvicted(); + assert !e3.isEvicted(); + assert !e4.isEvicted(); + + p.onEntryAccessed(false, e5); + + check(p.queue(), e3, e4, e5); + + assertEquals(3, p.getCurrentSize()); + + assert e2.isEvicted(); + assert !e3.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e1 = new MockEntry("1", "1")); + + check(p.queue(), e4, e5, e1); + + assertEquals(3, p.getCurrentSize()); + + assert e3.isEvicted(); + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e5); + + check(p.queue(), e4, e5, e1); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e1); + + assertEquals(3, p.getCurrentSize()); + + check(p.queue(), e4, e5, e1); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e5); + + assertEquals(3, p.getCurrentSize()); + + check(p.queue(), e4, e5, e1); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(true, e1); + + assertEquals(2, p.getCurrentSize()); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(true, e4); + + assertEquals(1, p.getCurrentSize()); + + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(true, e5); + + assertEquals(0, p.getCurrentSize()); + + assert !e5.isEvicted(); + + info(p); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testMemory() throws Exception { + try { + startGrid(); + + GridCacheFifoEvictionPolicy<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(); + + GridCacheFifoEvictionPolicy<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(); + + assert curSize <= max : "curSize <= max [curSize=" + curSize + ", max=" + max + ']'; + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testAllowEmptyEntries() throws Exception { + try { + startGrid(); + + MockEntry e1 = new MockEntry("1"); + + e1.setValue("val"); + + MockEntry e2 = new MockEntry("2"); + + MockEntry e3 = new MockEntry("3"); + + e3.setValue("val"); + + MockEntry e4 = new MockEntry("4"); + + MockEntry e5 = new MockEntry("5"); + + e5.setValue("val"); + + GridCacheFifoEvictionPolicy<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 { + GridCache<Integer, Integer> 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; + } + } + + assert min >= plcMax : "Min cache size is too small: " + min; + + info("Min cache size [min=" + min + ", idx=" + minIdx + ']'); + info("Current cache size " + cache.size()); + info("Current cache key size " + cache.size()); + info("Current cache entry set size " + cache.entrySet().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()); + info("Current cache entry set size " + cache.entrySet().size()); + + assert min >= plcMax : "Min cache size is too small: " + min; + } + finally { + stopAllGrids(); + } + } + + /** {@inheritDoc} */ + @Override protected GridCacheFifoEvictionPolicy<String, String> createPolicy(int plcMax) { + return new GridCacheFifoEvictionPolicy<>(plcMax); + } + + /** {@inheritDoc} */ + @Override protected GridCacheFifoEvictionPolicy<String, String> createNearPolicy(int nearMax) { + return new GridCacheFifoEvictionPolicy<>(nearMax); + } + + /** {@inheritDoc} */ + @Override protected void checkNearPolicies(int endNearPlcSize) { + for (int i = 0; i < gridCnt; i++) + for (GridCacheEntry<String, String> e : nearPolicy(i).queue()) + assert !e.isCached() : "Invalid near policy size: " + nearPolicy(i).queue(); + } + + /** {@inheritDoc} */ + @Override protected void checkPolicies(int plcMax) { + for (int i = 0; i < gridCnt; i++) + assert policy(i).queue().size() <= plcMax; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruEvictionPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruEvictionPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruEvictionPolicySelfTest.java new file mode 100644 index 0000000..5035b52 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruEvictionPolicySelfTest.java @@ -0,0 +1,426 @@ +/* + * 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.lru; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.lru.*; +import org.apache.ignite.internal.processors.cache.eviction.*; + +import java.util.*; + +/** + * LRU Eviction test. + */ +@SuppressWarnings( {"TypeMayBeWeakened"}) +public class GridCacheLruEvictionPolicySelfTest extends + GridCacheEvictionAbstractTest<GridCacheLruEvictionPolicy<String, String>> { + /** + * @throws Exception If failed. + */ + public void testPolicy() throws Exception { + startGrid(); + + try { + 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"); + + GridCacheLruEvictionPolicy<String, String> p = policy(); + + p.setMaxSize(3); + + p.onEntryAccessed(false, e1); + + check(p.queue(), e1); + + p.onEntryAccessed(false, e2); + + check(p.queue(), e1, e2); + + p.onEntryAccessed(false, e3); + + check(p.queue(), e1, e2, e3); + + assert !e1.isEvicted(); + assert !e2.isEvicted(); + assert !e3.isEvicted(); + + assertEquals(3, p.getCurrentSize()); + + p.onEntryAccessed(false, e4); + + check(p.queue(), e2, e3, e4); + + assertEquals(3, p.getCurrentSize()); + + assert e1.isEvicted(); + assert !e2.isEvicted(); + assert !e3.isEvicted(); + assert !e4.isEvicted(); + + p.onEntryAccessed(false, e5); + + check(p.queue(), e3, e4, e5); + + assertEquals(3, p.getCurrentSize()); + + assert e2.isEvicted(); + assert !e3.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e1 = new MockEntry("1", "1")); + + check(p.queue(), e4, e5, e1); + + assertEquals(3, p.getCurrentSize()); + + assert e3.isEvicted(); + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e5); + + assertEquals(3, p.getCurrentSize()); + + check(p.queue(), e4, e1, e5); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e1); + + assertEquals(3, p.getCurrentSize()); + + check(p.queue(), e4, e5, e1); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(false, e5); + + assertEquals(3, p.getCurrentSize()); + + check(p.queue(), e4, e1, e5); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(true, e1); + + assertEquals(2, p.getCurrentSize()); + + assert !e1.isEvicted(); + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(true, e4); + + assertEquals(1, p.getCurrentSize()); + + assert !e4.isEvicted(); + assert !e5.isEvicted(); + + p.onEntryAccessed(true, e5); + + assertEquals(0, p.getCurrentSize()); + + assert !e5.isEvicted(); + + info(p); + } + finally { + stopGrid(); + } + } + + /** + * @throws Exception If failed. + */ + public void testMemory() throws Exception { + startGrid(); + + try { + GridCacheLruEvictionPolicy<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 { + stopGrid(); + } + } + + /** + * @throws Exception If failed. + */ + public void testMiddleAccess() throws Exception { + startGrid(); + + try { + GridCacheLruEvictionPolicy<String, String> p = policy(); + + int max = 8; + + p.setMaxSize(max); + + MockEntry entry1 = new MockEntry("1", "1"); + MockEntry entry2 = new MockEntry("2", "2"); + MockEntry entry3 = new MockEntry("3", "3"); + + p.onEntryAccessed(false, entry1); + p.onEntryAccessed(false, entry2); + p.onEntryAccessed(false, entry3); + + MockEntry[] freqUsed = new MockEntry[] { + new MockEntry("4", "4"), + new MockEntry("5", "5"), + new MockEntry("6", "6"), + new MockEntry("7", "7"), + new MockEntry("8", "7") + }; + + for (MockEntry e : freqUsed) + p.onEntryAccessed(false, e); + + for (MockEntry e : freqUsed) + assert !e.isEvicted(); + + int cnt = 1001; + + for (int i = 0; i < cnt; i++) + p.onEntryAccessed(false, entry(freqUsed, i % freqUsed.length)); + + info(p); + + assertEquals(max, p.getCurrentSize()); + } + finally { + stopGrid(); + } + } + + /** + * @throws Exception If failed. + */ + public void testRandom() throws Exception { + startGrid(); + + try { + GridCacheLruEvictionPolicy<String, String> p = policy(); + + int max = 10; + + p.setMaxSize(max); + + Random rand = new Random(); + + int keys = 31; + + MockEntry[] lrus = new MockEntry[keys]; + + for (int i = 0; i < lrus.length; i++) + lrus[i] = new MockEntry(Integer.toString(i)); + + int runs = 500000; + + for (int i = 0; i < runs; i++) { + boolean rmv = rand.nextBoolean(); + + int j = rand.nextInt(lrus.length); + + MockEntry e = entry(lrus, j); + + if (rmv) + lrus[j] = new MockEntry(Integer.toString(j)); + + p.onEntryAccessed(rmv, e); + } + + info(p); + + assert p.getCurrentSize() <= max; + } + finally { + stopGrid(); + } + } + + /** + * @throws Exception If failed. + */ + public void testAllowEmptyEntries() throws Exception { + try { + startGrid(); + + MockEntry e1 = new MockEntry("1"); + + e1.setValue("val"); + + MockEntry e2 = new MockEntry("2"); + + MockEntry e3 = new MockEntry("3"); + + e3.setValue("val"); + + MockEntry e4 = new MockEntry("4"); + + MockEntry e5 = new MockEntry("5"); + + e5.setValue("val"); + + GridCacheLruEvictionPolicy<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 = GridCacheMode.LOCAL; + syncCommit = true; + plcMax = 100; + + Ignite ignite = startGrid(); + + try { + GridCache<Integer, Integer> 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; + } + } + + assert min >= plcMax : "Min cache size is too small: " + min; + + info("Min cache size [min=" + min + ", idx=" + minIdx + ']'); + info("Current cache size " + cache.size()); + info("Current cache key size " + cache.size()); + info("Current cache entry set size " + cache.entrySet().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()); + info("Current cache entry set size " + cache.entrySet().size()); + + assert min >= plcMax : "Min cache size is too small: " + min; + } + finally { + stopAllGrids(); + } + } + + /** {@inheritDoc} */ + @Override protected GridCacheLruEvictionPolicy<String, String> createPolicy(int plcMax) { + return new GridCacheLruEvictionPolicy<>(plcMax); + } + + @Override protected GridCacheLruEvictionPolicy<String, String> createNearPolicy(int nearMax) { + return new GridCacheLruEvictionPolicy<>(nearMax); + } + + /** {@inheritDoc} */ + @Override protected void checkNearPolicies(int endNearPlcSize) { + for (int i = 0; i < gridCnt; i++) + for (GridCacheEntry<String, String> e : nearPolicy(i).queue()) + assert !e.isCached() : "Invalid near policy size: " + nearPolicy(i).queue(); + } + + /** {@inheritDoc} */ + @Override protected void checkPolicies(int plcMax) { + for (int i = 0; i < gridCnt; i++) + assert policy(i).queue().size() <= plcMax; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruNearEvictionPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruNearEvictionPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruNearEvictionPolicySelfTest.java new file mode 100644 index 0000000..a552593 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheLruNearEvictionPolicySelfTest.java @@ -0,0 +1,136 @@ +/* + * 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.lru; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.lru.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.apache.ignite.testframework.junits.common.*; + +import java.util.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheDistributionMode.*; +import static org.apache.ignite.cache.GridCacheMode.*; +import static org.apache.ignite.cache.GridCachePreloadMode.*; +import static org.apache.ignite.cache.GridCacheWriteSynchronizationMode.*; + +/** + * LRU near eviction tests (GG-8884). + */ +public class GridCacheLruNearEvictionPolicySelfTest extends GridCommonAbstractTest { + /** */ + private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** Maximum size for near eviction policy. */ + private static final int EVICTION_MAX_SIZE = 10; + + /** Grid count. */ + private static final int GRID_COUNT = 2; + + /** Cache atomicity mode specified by test. */ + private GridCacheAtomicityMode atomicityMode; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration c = super.getConfiguration(gridName); + + CacheConfiguration cc = new CacheConfiguration(); + + cc.setAtomicityMode(atomicityMode); + cc.setCacheMode(PARTITIONED); + cc.setWriteSynchronizationMode(PRIMARY_SYNC); + cc.setDistributionMode(NEAR_PARTITIONED); + cc.setPreloadMode(SYNC); + cc.setNearEvictionPolicy(new GridCacheLruEvictionPolicy(EVICTION_MAX_SIZE)); + cc.setStartSize(100); + cc.setQueryIndexEnabled(true); + cc.setBackups(0); + + c.setCacheConfiguration(cc); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + + disco.setIpFinder(ipFinder); + + c.setDiscoverySpi(disco); + + return c; + } + + /** + * @throws Exception If failed. + */ + public void testAtomicNearEvictionMaxSize() throws Exception { + atomicityMode = ATOMIC; + + checkNearEvictionMaxSize(); + } + + /** + * @throws Exception If failed. + */ + public void testTransactionalNearEvictionMaxSize() throws Exception { + atomicityMode = TRANSACTIONAL; + + checkNearEvictionMaxSize(); + } + + /** + * @throws Exception If failed. + */ + private void checkNearEvictionMaxSize() throws Exception { + startGridsMultiThreaded(GRID_COUNT); + + try { + Random rand = new Random(0); + + int cnt = 1000; + + info("Inserting " + cnt + " keys to cache."); + + try (IgniteDataLoader<Integer, String> ldr = grid(0).dataLoader(null)) { + for (int i = 0; i < cnt; i++) + ldr.addData(i, Integer.toString(i)); + } + + for (int i = 0; i < GRID_COUNT; i++) + assertTrue("Near cache size " + near(i).nearSize() + ", but eviction maximum size " + EVICTION_MAX_SIZE, + near(i).nearSize() <= EVICTION_MAX_SIZE); + + info("Getting " + cnt + " keys from cache."); + + for (int i = 0; i < cnt; i++) { + GridCache<Integer, String> cache = grid(rand.nextInt(GRID_COUNT)).cache(null); + + assertTrue(cache.get(i).equals(Integer.toString(i))); + } + + for (int i = 0; i < GRID_COUNT; i++) + assertTrue("Near cache size " + near(i).nearSize() + ", but eviction maximum size " + EVICTION_MAX_SIZE, + near(i).nearSize() <= EVICTION_MAX_SIZE); + } + finally { + stopAllGrids(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheNearOnlyLruNearEvictionPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheNearOnlyLruNearEvictionPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheNearOnlyLruNearEvictionPolicySelfTest.java new file mode 100644 index 0000000..d536236 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/lru/GridCacheNearOnlyLruNearEvictionPolicySelfTest.java @@ -0,0 +1,167 @@ +/* + * 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.lru; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.lru.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.apache.ignite.testframework.junits.common.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheDistributionMode.*; +import static org.apache.ignite.cache.GridCacheMode.*; +import static org.apache.ignite.cache.GridCachePreloadMode.*; +import static org.apache.ignite.cache.GridCacheWriteSynchronizationMode.*; + +/** + * LRU near eviction tests for NEAR_ONLY distribution mode (GG-8884). + */ +public class GridCacheNearOnlyLruNearEvictionPolicySelfTest extends GridCommonAbstractTest { + /** */ + private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** Grid count. */ + private static final int GRID_COUNT = 2; + + /** Maximum size for near eviction policy. */ + private static final int EVICTION_MAX_SIZE = 10; + + /** Node count. */ + private int cnt; + + /** Caching mode specified by test. */ + private GridCacheMode cacheMode; + + /** Cache atomicity mode specified by test. */ + private GridCacheAtomicityMode atomicityMode; + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + cnt = 0; + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration c = super.getConfiguration(gridName); + + CacheConfiguration cc = new CacheConfiguration(); + + cc.setAtomicityMode(atomicityMode); + cc.setCacheMode(cacheMode); + cc.setWriteSynchronizationMode(PRIMARY_SYNC); + cc.setDistributionMode(cnt == 0 ? NEAR_ONLY : PARTITIONED_ONLY); + cc.setPreloadMode(SYNC); + cc.setNearEvictionPolicy(new GridCacheLruEvictionPolicy(EVICTION_MAX_SIZE)); + cc.setStartSize(100); + cc.setQueryIndexEnabled(true); + cc.setBackups(0); + + c.setCacheConfiguration(cc); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + + disco.setIpFinder(ipFinder); + + c.setDiscoverySpi(disco); + + cnt++; + + return c; + } + + /** + * @throws Exception If failed. + */ + public void testPartitionedAtomicNearEvictionMaxSize() throws Exception { + atomicityMode = ATOMIC; + cacheMode = PARTITIONED; + + checkNearEvictionMaxSize(); + } + + /** + * @throws Exception If failed. + */ + public void testPartitionedTransactionalNearEvictionMaxSize() throws Exception { + atomicityMode = TRANSACTIONAL; + cacheMode = PARTITIONED; + + checkNearEvictionMaxSize(); + } + + /** + * @throws Exception If failed. + */ + public void testReplicatedAtomicNearEvictionMaxSize() throws Exception { + atomicityMode = ATOMIC; + cacheMode = REPLICATED; + + checkNearEvictionMaxSize(); + } + + /** + * @throws Exception If failed. + */ + public void testReplicatedTransactionalNearEvictionMaxSize() throws Exception { + atomicityMode = TRANSACTIONAL; + cacheMode = REPLICATED; + + checkNearEvictionMaxSize(); + } + + /** + * @throws Exception If failed. + */ + private void checkNearEvictionMaxSize() throws Exception { + startGrids(GRID_COUNT); + + try { + int cnt = 1000; + + info("Inserting " + cnt + " keys to cache."); + + try (IgniteDataLoader<Integer, String> ldr = grid(1).dataLoader(null)) { + for (int i = 0; i < cnt; i++) + ldr.addData(i, Integer.toString(i)); + } + + assertTrue("Near cache size " + near(0).nearSize() + ", but eviction maximum size " + EVICTION_MAX_SIZE, + near(0).nearSize() <= EVICTION_MAX_SIZE); + + info("Getting " + cnt + " keys from cache."); + + for (int i = 0; i < cnt; i++) { + GridCache<Integer, String> cache = grid(0).cache(null); + + assertTrue(cache.get(i).equals(Integer.toString(i))); + } + + assertTrue("Near cache size " + near(0).nearSize() + ", but eviction maximum size " + EVICTION_MAX_SIZE, + near(0).nearSize() <= EVICTION_MAX_SIZE); + } + finally { + stopAllGrids(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/random/GridCacheRandomEvictionPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/random/GridCacheRandomEvictionPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/random/GridCacheRandomEvictionPolicySelfTest.java new file mode 100644 index 0000000..3764260 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/eviction/random/GridCacheRandomEvictionPolicySelfTest.java @@ -0,0 +1,265 @@ +/* + * 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.random; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.random.*; +import org.apache.ignite.internal.processors.cache.eviction.*; +import org.jetbrains.annotations.*; + +import java.util.*; +import java.util.concurrent.*; + +/** + * Random eviction policy test. + */ +public class GridCacheRandomEvictionPolicySelfTest extends + GridCacheEvictionAbstractTest<GridCacheRandomEvictionPolicy<String, String>> { + /** + * @throws Exception If failed. + */ + public void testMemory() throws Exception { + try { + Ignite g = startGrid(0); + + int max = 10; + + policy(0).setMaxSize(max); + + int keys = 31; + + for (int i = 0; i < keys; i++) { + String s = Integer.toString(i); + + g.cache(null).put(s, s); + } + + assert g.cache(null).size() <= max; + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testRandom() throws Exception { + try { + Ignite g = startGrid(0); + + int max = 10; + + policy(0).setMaxSize(max); + + Random rand = new Random(); + + int keys = 31; + + String[] t = new String[keys]; + + for (int i = 0; i < t.length; i++) + t[i] = Integer.toString(i); + + int runs = 10000; + + for (int i = 0; i < runs; i++) { + boolean rmv = rand.nextBoolean(); + + int j = rand.nextInt(t.length); + + if (rmv) + g.cache(null).remove(t[j]); + else + g.cache(null).put(t[j], t[j]); + + if (i % 1000 == 0) + info("Stats [cntr=" + i + ", total=" + runs + ']'); + } + + assert g.cache(null).size() <= max; + + info(policy(0)); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testAllowEmptyEntries() throws Exception { + try { + startGrid(); + + GridCache<String, String> c = cache(); + + MockEntry e1 = new MockEntry("1", c); + + e1.setValue("val"); + + MockEntry e2 = new MockEntry("2", c); + + MockEntry e3 = new MockEntry("3", c); + + e3.setValue("val"); + + MockEntry e4 = new MockEntry("4", c); + + MockEntry e5 = new MockEntry("5", c); + + e5.setValue("val"); + + GridCacheRandomEvictionPolicy<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 testRandomMultiThreaded() throws Exception { + try { + final Ignite g = startGrid(0); + + int max = 10; + + policy(0).setMaxSize(max); + + final Random rand = new Random(); + + int keys = 31; + + final String[] t = new String[keys]; + + for (int i = 0; i < t.length; i++) + t[i] = Integer.toString(i); + + multithreaded(new Callable() { + @Nullable @Override public Object call() throws IgniteCheckedException { + int runs = 3000; + + for (int i = 0; i < runs; i++) { + boolean rmv = rand.nextBoolean(); + + int j = rand.nextInt(t.length); + + if (rmv) + g.cache(null).remove(t[j]); + else + g.cache(null).put(t[j], t[j]); + + if (i != 0 && i % 1000 == 0) + info("Stats [cntr=" + i + ", total=" + runs + ']'); + } + + return null; + } + }, 10); + + assert g.cache(null).size() <= max; + + info(policy(0)); + } + finally { + stopAllGrids(); + } + } + + /** {@inheritDoc} */ + @Override public void testPartitionedNearDisabled() throws Exception { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void testPartitionedNearEnabled() throws Exception { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void testPartitionedNearDisabledMultiThreaded() throws Exception { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void testPartitionedNearDisabledBackupSyncMultiThreaded() throws Exception { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void testPartitionedNearEnabledMultiThreaded() throws Exception { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void testPartitionedNearEnabledBackupSyncMultiThreaded() throws Exception { + // No-op. + } + + /** {@inheritDoc} */ + @Override protected GridCacheRandomEvictionPolicy<String, String> createPolicy(int plcMax) { + return new GridCacheRandomEvictionPolicy<>(plcMax); + } + + /** {@inheritDoc} */ + @Override protected GridCacheRandomEvictionPolicy<String, String> createNearPolicy(int nearMax) { + return new GridCacheRandomEvictionPolicy<>(plcMax); + } + + /** {@inheritDoc} */ + @Override protected void checkNearPolicies(int nearMax) { + // No-op. + } + + /** {@inheritDoc} */ + @Override protected void checkPolicies(int plcMax) { + // No-op. + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/apache/ignite/testsuites/GridCacheEvictionSelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/GridCacheEvictionSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/GridCacheEvictionSelfTestSuite.java index 243360a..051cd62 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/GridCacheEvictionSelfTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/GridCacheEvictionSelfTestSuite.java @@ -20,10 +20,10 @@ package org.apache.ignite.testsuites; import junit.framework.*; import org.gridgain.grid.kernal.processors.cache.*; import org.apache.ignite.internal.processors.cache.distributed.near.*; -import org.gridgain.grid.kernal.processors.cache.eviction.*; -import org.gridgain.grid.kernal.processors.cache.eviction.fifo.*; -import org.gridgain.grid.kernal.processors.cache.eviction.lru.*; -import org.gridgain.grid.kernal.processors.cache.eviction.random.*; +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.*; /** * Test suite for cache eviction. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheBatchEvictUnswapSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheBatchEvictUnswapSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheBatchEvictUnswapSelfTest.java deleted file mode 100644 index d9f5752..0000000 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheBatchEvictUnswapSelfTest.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 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.gridgain.grid.kernal.processors.cache.eviction; - -import org.apache.ignite.*; -import org.apache.ignite.cache.*; -import org.apache.ignite.cache.eviction.fifo.*; -import org.apache.ignite.cache.store.*; -import org.apache.ignite.lang.*; -import org.gridgain.grid.kernal.processors.cache.*; -import org.jetbrains.annotations.*; - -import javax.cache.*; -import javax.cache.configuration.*; -import java.util.*; -import java.util.concurrent.atomic.*; - -import static org.apache.ignite.cache.GridCacheDistributionMode.*; - -/** - * Swap benchmark. - */ -@SuppressWarnings("BusyWait") -public class GridCacheBatchEvictUnswapSelfTest extends GridCacheAbstractSelfTest { - /** Eviction policy size. */ - public static final int EVICT_PLC_SIZE = 100000; - - /** Keys count. */ - public static final int KEYS_CNT = 100000; - - /** Batch size. */ - private static final int BATCH_SIZE = 200; - - /** Number of threads for concurrent benchmark + concurrency level. */ - private static final int N_THREADS = 8; - - /** {@inheritDoc} */ - @Override protected int gridCount() { - return 1; - } - - /** {@inheritDoc} */ - @Override protected long getTestTimeout() { - // Let this test run 2 minutes as it runs for 20 seconds locally. - return 2 * 60 * 1000; - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception { - CacheConfiguration cacheCfg = super.cacheConfiguration(gridName); - - cacheCfg.setCacheMode(GridCacheMode.PARTITIONED); - - CacheStore store = new CacheStoreAdapter<Long, String>() { - @Nullable @Override public String load(Long key) { - return null; - } - - @Override public void loadCache(final IgniteBiInClosure<Long, String> c, - @Nullable Object... args) { - for (int i = 0; i < KEYS_CNT; i++) - c.apply((long)i, String.valueOf(i)); - } - - @Override public void write(Cache.Entry<? extends Long, ? extends String> val) { - // No-op. - } - - @Override public void delete(Object key) { - // No-op. - } - }; - - cacheCfg.setCacheStoreFactory(new FactoryBuilder.SingletonFactory(store)); - cacheCfg.setReadThrough(true); - cacheCfg.setWriteThrough(true); - cacheCfg.setLoadPreviousValue(true); - - cacheCfg.setEvictionPolicy(new GridCacheFifoEvictionPolicy(EVICT_PLC_SIZE)); - cacheCfg.setSwapEnabled(true); - cacheCfg.setEvictSynchronized(false); - cacheCfg.setDistributionMode(PARTITIONED_ONLY); - - return cacheCfg; - } - - /** - * @throws Exception If failed. - */ - public void testConcurrentEvictions() throws Exception { - runConcurrentTest(grid(0), KEYS_CNT, BATCH_SIZE); - } - - /** - * @param g Grid instance. - * @param keysCnt Number of keys to swap and promote. - * @param batchSize Size of batch to swap/promote. - * @throws Exception If failed. - */ - private void runConcurrentTest(Ignite g, final int keysCnt, final int batchSize) throws Exception { - assert keysCnt % batchSize == 0; - - final AtomicInteger evictedKeysCnt = new AtomicInteger(); - - final GridCache<Object, Object> cache = g.cache(null); - - cache.loadCache(null, 0); - - info("Finished load cache."); - - IgniteFuture<?> evictFut = multithreadedAsync(new Runnable() { - @Override public void run() { - Collection<Long> keys = new ArrayList<>(batchSize); - - int evictedBatches = 0; - - for (long i = 0; i < keysCnt; i++) { - keys.add(i); - - if (keys.size() == batchSize) { - cache.evictAll(keys); - - evictedKeysCnt.addAndGet(batchSize); - - keys.clear(); - - evictedBatches++; - - if (evictedBatches % 100 == 0 && evictedBatches > 0) - info("Evicted " + (evictedBatches * batchSize) + " entries."); - } - } - } - }, N_THREADS, "evict"); - - final AtomicInteger unswappedKeys = new AtomicInteger(); - - IgniteFuture<?> unswapFut = multithreadedAsync(new Runnable() { - @Override public void run() { - try { - Collection<Long> keys = new ArrayList<>(batchSize); - - int unswappedBatches = 0; - - for (long i = 0; i < keysCnt; i++) { - keys.add(i); - - if (keys.size() == batchSize) { - cache.promoteAll(keys); - - unswappedKeys.addAndGet(batchSize); - - keys.clear(); - - unswappedBatches++; - - if (unswappedBatches % 100 == 0 && unswappedBatches > 0) - info("Unswapped " + (unswappedBatches * batchSize) + " entries."); - } - } - } - catch (IgniteCheckedException e) { - e.printStackTrace(); - } - } - }, N_THREADS, "promote"); - - evictFut.get(); - - unswapFut.get(); - - info("Clearing cache."); - - for (long i = 0; i < KEYS_CNT; i++) - cache.remove(i); - } -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a916db69/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheConcurrentEvictionConsistencySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheConcurrentEvictionConsistencySelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheConcurrentEvictionConsistencySelfTest.java deleted file mode 100644 index 2e6de1a..0000000 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheConcurrentEvictionConsistencySelfTest.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 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.gridgain.grid.kernal.processors.cache.eviction; - -import org.apache.ignite.*; -import org.apache.ignite.cache.*; -import org.apache.ignite.cache.eviction.*; -import org.apache.ignite.cache.eviction.fifo.*; -import org.apache.ignite.cache.eviction.lru.*; -import org.apache.ignite.configuration.*; -import org.apache.ignite.lang.*; -import org.apache.ignite.transactions.*; -import org.apache.ignite.spi.discovery.tcp.*; -import org.apache.ignite.spi.discovery.tcp.ipfinder.*; -import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; -import org.apache.ignite.internal.util.typedef.internal.*; -import org.apache.ignite.testframework.junits.common.*; - -import java.util.*; -import java.util.concurrent.*; - -import static org.apache.ignite.cache.GridCacheMode.*; -import static org.apache.ignite.cache.GridCacheDistributionMode.*; -import static org.apache.ignite.transactions.IgniteTxConcurrency.*; -import static org.apache.ignite.transactions.IgniteTxIsolation.*; -import static org.apache.ignite.cache.GridCacheWriteSynchronizationMode.*; - -/** - * - */ -public class GridCacheConcurrentEvictionConsistencySelfTest extends GridCommonAbstractTest { - /** IP finder. */ - private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); - - /** Default iteration count. */ - private static final int ITERATION_CNT = 50000; - - /** Size of policy internal queue. */ - private static final int POLICY_QUEUE_SIZE = 50; - - /** Tested policy. */ - private GridCacheEvictionPolicy<?, ?> plc; - - /** Key count to put into the cache. */ - private int keyCnt; - - /** Number of threads. */ - private int threadCnt = 50; - - /** {@inheritDoc} */ - @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { - IgniteConfiguration c = super.getConfiguration(gridName); - - c.getTransactionsConfiguration().setDefaultTxConcurrency(PESSIMISTIC); - c.getTransactionsConfiguration().setDefaultTxIsolation(READ_COMMITTED); - - CacheConfiguration cc = defaultCacheConfiguration(); - - cc.setCacheMode(LOCAL); - - cc.setSwapEnabled(false); - - cc.setWriteSynchronizationMode(FULL_SYNC); - - cc.setDistributionMode(PARTITIONED_ONLY); - - cc.setEvictionPolicy(plc); - - c.setCacheConfiguration(cc); - - TcpDiscoverySpi disco = new TcpDiscoverySpi(); - - disco.setIpFinder(ipFinder); - - c.setDiscoverySpi(disco); - - return c; - } - - /** {@inheritDoc} */ - @Override protected long getTestTimeout() { - return 5 * 60 * 1000; // 5 min. - } - - /** - * @throws Exception If failed. - */ - public void testPolicyConsistencyFifoLocalTwoKeys() throws Exception { - plc = new GridCacheFifoEvictionPolicy<Object, Object>(1); - - keyCnt = 2; - threadCnt = 10; - - checkPolicyConsistency(); - } - - /** - * @throws Exception If failed. - */ - public void testPolicyConsistencyLruLocalTwoKeys() throws Exception { - plc = new GridCacheLruEvictionPolicy<Object, Object>(1); - - keyCnt = 2; - threadCnt = 10; - - checkPolicyConsistency(); - } - - /** - * @throws Exception If failed. - */ - public void testPolicyConsistencyFifoLocalFewKeys() throws Exception { - plc = new GridCacheFifoEvictionPolicy<Object, Object>(POLICY_QUEUE_SIZE); - - keyCnt = POLICY_QUEUE_SIZE + 5; - - checkPolicyConsistency(); - } - - /** - * @throws Exception If failed. - */ - public void testPolicyConsistencyLruLocalFewKeys() throws Exception { - plc = new GridCacheLruEvictionPolicy<Object, Object>(POLICY_QUEUE_SIZE); - - keyCnt = POLICY_QUEUE_SIZE + 5; - - checkPolicyConsistency(); - } - - /** - * @throws Exception If failed. - */ - public void testPolicyConsistencyFifoLocal() throws Exception { - plc = new GridCacheFifoEvictionPolicy<Object, Object>(POLICY_QUEUE_SIZE); - - keyCnt = POLICY_QUEUE_SIZE * 10; - - checkPolicyConsistency(); - } - - /** - * @throws Exception If failed. - */ - public void testPolicyConsistencyLruLocal() throws Exception { - plc = new GridCacheLruEvictionPolicy<Object, Object>(POLICY_QUEUE_SIZE); - - keyCnt = POLICY_QUEUE_SIZE * 10; - - checkPolicyConsistency(); - } - - /** - * @throws Exception If failed. - */ - private void checkPolicyConsistency() throws Exception { - try { - Ignite ignite = startGrid(1); - - final GridCache<Integer, Integer> cache = ignite.cache(null); - - long start = System.currentTimeMillis(); - - IgniteFuture<?> fut = multithreadedAsync( - new Callable<Object>() { - @Override - public Object call() throws Exception { - final Random rnd = new Random(); - - for (int i = 0; i < ITERATION_CNT; i++) { - - int j = rnd.nextInt(keyCnt); - - try (IgniteTx tx = cache.txStart()) { - // Put or remove? - if (rnd.nextBoolean()) - cache.putx(j, j); - else - cache.remove(j); - - tx.commit(); - } - - if (i != 0 && i % 10000 == 0) - info("Stats [iterCnt=" + i + ", size=" + cache.size() + ']'); - } - - return null; - } - }, - threadCnt - ); - - fut.get(); - - Collection<GridCacheEntry<Integer, Integer>> queue = internalQueue(plc); - - info("Test results [threadCnt=" + threadCnt + ", iterCnt=" + ITERATION_CNT + ", cacheSize=" + cache.size() + - ", internalQueueSize" + queue.size() + ", duration=" + (System.currentTimeMillis() - start) + ']'); - - for (GridCacheEntry<Integer, Integer> e : queue) { - Integer rmv = cache.remove(e.getKey()); - - if (rmv == null) - fail("Eviction policy contains key that is not present in cache: " + e); - else - info("Entry removed: " + rmv); - } - - if (!cache.isEmpty()) { - boolean zombies = false; - - for (GridCacheEntry<Integer, Integer> e : cache) { - U.warn(log, "Zombie entry: " + e); - - zombies = true; - } - - if (zombies) - fail("Cache contained zombie entries."); - } - else - info("Cache is empty after test."); - } - finally { - stopAllGrids(); - } - } - - /** - * Gets internal policy queue. - * - * @param plc Policy to get queue from. - * @return Internal entries collection. - */ - private Collection<GridCacheEntry<Integer, Integer>> internalQueue(GridCacheEvictionPolicy<?, ?> plc) { - if (plc instanceof GridCacheFifoEvictionPolicy) { - GridCacheFifoEvictionPolicy<Integer, Integer> plc0 = (GridCacheFifoEvictionPolicy<Integer, Integer>)plc; - - return plc0.queue(); - } - else if (plc instanceof GridCacheLruEvictionPolicy) { - GridCacheLruEvictionPolicy<Integer, Integer> plc0 = (GridCacheLruEvictionPolicy<Integer, Integer>)plc; - - return plc0.queue(); - } - - assert false : "Unexpected policy type: " + plc.getClass().getName(); - - return Collections.emptyList(); - } -}