| /* |
| * 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.geode.internal.cache; |
| |
| import static java.lang.System.getProperties; |
| import static java.util.Map.Entry; |
| import static java.util.concurrent.TimeUnit.SECONDS; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNotSame; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.File; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import org.junit.Test; |
| |
| import org.apache.geode.cache.AttributesFactory; |
| import org.apache.geode.cache.CacheException; |
| import org.apache.geode.cache.CacheListener; |
| import org.apache.geode.cache.DiskStore; |
| import org.apache.geode.cache.DiskStoreFactory; |
| import org.apache.geode.cache.EntryEvent; |
| import org.apache.geode.cache.EvictionAction; |
| import org.apache.geode.cache.EvictionAttributes; |
| import org.apache.geode.cache.InterestPolicy; |
| import org.apache.geode.cache.Operation; |
| import org.apache.geode.cache.PartitionAttributes; |
| import org.apache.geode.cache.PartitionAttributesFactory; |
| import org.apache.geode.cache.Region; |
| import org.apache.geode.cache.RegionAttributes; |
| import org.apache.geode.cache.SubscriptionAttributes; |
| import org.apache.geode.cache.util.CacheListenerAdapter; |
| import org.apache.geode.cache.util.ObjectSizer; |
| import org.apache.geode.cache30.CacheSerializableRunnable; |
| import org.apache.geode.internal.cache.control.HeapMemoryMonitor; |
| import org.apache.geode.internal.cache.control.InternalResourceManager.ResourceType; |
| import org.apache.geode.internal.cache.eviction.HeapEvictor; |
| import org.apache.geode.internal.cache.eviction.HeapLRUController; |
| import org.apache.geode.logging.internal.OSProcess; |
| import org.apache.geode.test.awaitility.GeodeAwaitility; |
| import org.apache.geode.test.dunit.Assert; |
| import org.apache.geode.test.dunit.Host; |
| import org.apache.geode.test.dunit.IgnoredException; |
| import org.apache.geode.test.dunit.SerializableCallable; |
| import org.apache.geode.test.dunit.SerializableRunnable; |
| import org.apache.geode.test.dunit.VM; |
| import org.apache.geode.test.dunit.WaitCriterion; |
| import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase; |
| |
| |
| public class PartitionedRegionEvictionDUnitTest extends JUnit4CacheTestCase { |
| |
| @Test |
| public void testHeapLRUWithOverflowToDisk() { |
| // Ignore this excetion as this can happen if pool is shutting down |
| IgnoredException |
| .addIgnoredException(java.util.concurrent.RejectedExecutionException.class.getName()); |
| final Host host = Host.getHost(0); |
| final VM vm2 = host.getVM(2); |
| final VM vm3 = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final float heapPercentage = 50.9f; |
| final int redundantCopies = 1; |
| final int evictorInterval = 100; |
| final String name = uniqName + "-PR"; |
| |
| final CacheSerializableRunnable create = |
| new CacheSerializableRunnable("Create Heap LRU with Overflow to disk partitioned Region") { |
| @Override |
| public void run2() { |
| System.setProperty(HeapLRUController.TOP_UP_HEAP_EVICTION_PERCENTAGE_PROPERTY, |
| Float.toString(0)); |
| setEvictionPercentage(heapPercentage); |
| final Properties sp = System.getProperties(); |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes( |
| EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK)); |
| factory.setDiskSynchronous(true); |
| DiskStoreFactory dsf = getCache().createDiskStoreFactory(); |
| final File[] diskDirs = new File[1]; |
| diskDirs[0] = new File("overflowDir/" + uniqName + "_" + OSProcess.getId()); |
| diskDirs[0].mkdirs(); |
| dsf.setDiskDirs(diskDirs); |
| DiskStore ds = dsf.create(name); |
| factory.setDiskStoreName(ds.getName()); |
| final PartitionedRegion pr = |
| (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| vm3.invoke(create); |
| vm2.invoke(create); |
| |
| final int bucketsToCreate = 3; |
| final SerializableRunnable createBuckets = new SerializableRunnable("Create Buckets") { |
| @Override |
| public void run() { |
| setEvictionPercentage(heapPercentage); |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| // Create three buckets, add enough stuff in each to force two |
| // overflow |
| // ops in each |
| for (int i = 0; i < bucketsToCreate; i++) { |
| // assume mod-based hashing for bucket creation |
| pr.put(new Integer(i), "value0"); |
| pr.put(new Integer(i + pr.getPartitionAttributes().getTotalNumBuckets()), "value1"); |
| pr.put(new Integer(i + (pr.getPartitionAttributes().getTotalNumBuckets()) * 2), "value2"); |
| } |
| } |
| }; |
| vm3.invoke(createBuckets); |
| |
| final SerializableCallable assertBucketAttributesAndEviction = |
| new SerializableCallable("Assert bucket attributes and eviction") { |
| @Override |
| public Object call() throws Exception { |
| |
| try { |
| setEvictionPercentage(heapPercentage); |
| final Properties sp = getProperties(); |
| final int expectedInvocations = 10; |
| final int maximumWaitSeconds = 60; // seconds |
| final int pollWaitMillis = evictorInterval * 2; |
| assertTrue(pollWaitMillis < (SECONDS.toMillis(maximumWaitSeconds) * 4)); |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| for (final Iterator i = |
| ((PartitionedRegion) pr).getDataStore().getAllLocalBuckets().iterator(); i |
| .hasNext();) { |
| final Entry entry = (Entry) i.next(); |
| final BucketRegion bucketRegion = (BucketRegion) entry.getValue(); |
| if (bucketRegion == null) { |
| continue; |
| } |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAlgorithm() |
| .isLRUHeap()); |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAction() |
| .isOverflowToDisk()); |
| } |
| raiseFakeNotification(); |
| WaitCriterion wc = new WaitCriterion() { |
| String excuse; |
| |
| @Override |
| public boolean done() { |
| // we have a primary |
| if (pr.getDiskRegionStats().getNumOverflowOnDisk() == 9) { |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public String description() { |
| return excuse; |
| } |
| }; |
| GeodeAwaitility.await().untilAsserted(wc); |
| |
| int entriesEvicted = 0; |
| |
| entriesEvicted += pr.getDiskRegionStats().getNumOverflowOnDisk(); |
| return new Integer(entriesEvicted); |
| } finally { |
| cleanUpAfterFakeNotification(); |
| // Clean up the observer for future tests |
| // final Properties sp = System.getProperties(); |
| /* |
| * assertNotNull(sp .remove(HeapLRUCapacityController.FREE_MEMORY_OBSERVER)); |
| */ |
| } |
| } |
| }; |
| final Integer v2i = (Integer) vm2.invoke(assertBucketAttributesAndEviction); |
| final Integer v3i = (Integer) vm3.invoke(assertBucketAttributesAndEviction); |
| final int totalEvicted = v2i.intValue() + v3i.intValue(); |
| // assume all three entries in each bucket were evicted to disk |
| assertEquals((3 * bucketsToCreate * (redundantCopies + 1)), totalEvicted); |
| } |
| |
| protected void raiseFakeNotification() { |
| ((GemFireCacheImpl) getCache()).getHeapEvictor().setTestAbortAfterLoopCount(1); |
| HeapMemoryMonitor.setTestDisableMemoryUpdates(true); |
| |
| setEvictionPercentage(85); |
| HeapMemoryMonitor hmm = |
| ((GemFireCacheImpl) getCache()).getInternalResourceManager().getHeapMonitor(); |
| hmm.setTestMaxMemoryBytes(100); |
| |
| hmm.updateStateAndSendEvent(90, "test"); |
| } |
| |
| protected void cleanUpAfterFakeNotification() { |
| ((GemFireCacheImpl) getCache()).getHeapEvictor().setTestAbortAfterLoopCount(Integer.MAX_VALUE); |
| HeapMemoryMonitor.setTestDisableMemoryUpdates(false); |
| } |
| |
| @Test |
| public void testHeapLRUWithLocalDestroy() { |
| // Ignore this excetion as this can happen if pool is shutting down |
| IgnoredException |
| .addIgnoredException(java.util.concurrent.RejectedExecutionException.class.getName()); |
| final Host host = Host.getHost(0); |
| final VM vm2 = host.getVM(2); |
| final VM vm3 = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final float heapPercentage = 50.9f; |
| final int redundantCopies = 1; |
| final int evictorInterval = 100; |
| final String name = uniqName + "-PR"; |
| |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Heap LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| System.setProperty(HeapLRUController.TOP_UP_HEAP_EVICTION_PERCENTAGE_PROPERTY, |
| Float.toString(0)); |
| setEvictionPercentage(heapPercentage); |
| final Properties sp = System.getProperties(); |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes(EvictionAttributes.createLRUHeapAttributes()); |
| final PartitionedRegion pr = (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| vm3.invoke(create); |
| vm2.invoke(create); |
| |
| final int bucketsToCreate = 3; |
| final SerializableRunnable createBuckets = new SerializableRunnable("Create Buckets") { |
| @Override |
| public void run() { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| // Create three buckets, add enough stuff in each to force two |
| // overflow |
| // ops in each |
| for (int i = 0; i < bucketsToCreate; i++) { |
| // assume mod-based hashing for bucket creation |
| pr.put(new Integer(i), "value0"); |
| pr.put(new Integer(i + pr.getPartitionAttributes().getTotalNumBuckets()), "value1"); |
| pr.put(new Integer(i + (pr.getPartitionAttributes().getTotalNumBuckets()) * 2), "value2"); |
| } |
| } |
| }; |
| vm3.invoke(createBuckets); |
| |
| final SerializableCallable assertBucketAttributesAndEviction = |
| new SerializableCallable("Assert bucket attributes and eviction") { |
| @Override |
| public Object call() throws Exception { |
| try { |
| final Properties sp = getProperties(); |
| final int expectedInvocations = 10; |
| final int maximumWaitSeconds = 60; // seconds |
| final int pollWaitMillis = evictorInterval * 2; |
| assertTrue(pollWaitMillis < (SECONDS.toMillis(maximumWaitSeconds) * 4)); |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| |
| long entriesEvicted = 0; |
| for (final Iterator i = pr.getDataStore().getAllLocalBuckets().iterator(); i |
| .hasNext();) { |
| final Entry entry = (Entry) i.next(); |
| |
| final BucketRegion bucketRegion = (BucketRegion) entry.getValue(); |
| if (bucketRegion == null) { |
| continue; |
| } |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAlgorithm() |
| .isLRUHeap()); |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAction() |
| .isLocalDestroy()); |
| } |
| raiseFakeNotification(); |
| WaitCriterion wc = new WaitCriterion() { |
| String excuse; |
| |
| @Override |
| public boolean done() { |
| // we have a primary |
| if (pr.getTotalEvictions() == 9) { |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public String description() { |
| return excuse; |
| } |
| }; |
| GeodeAwaitility.await().untilAsserted(wc); |
| |
| entriesEvicted = pr.getTotalEvictions(); |
| return new Long(entriesEvicted); |
| } finally { |
| cleanUpAfterFakeNotification(); |
| // Clean up the observer for future tests |
| // final Properties sp = System.getProperties(); |
| /* |
| * assertNotNull(sp .remove(HeapLRUCapacityController.FREE_MEMORY_OBSERVER)); |
| */ |
| } |
| } |
| }; |
| final Long v2i = (Long) vm2.invoke(assertBucketAttributesAndEviction); |
| final Long v3i = (Long) vm3.invoke(assertBucketAttributesAndEviction); |
| final int totalEvicted = v2i.intValue() + v3i.intValue(); |
| // assume all three entries in each bucket were evicted to disk |
| assertEquals((3 * bucketsToCreate * (redundantCopies + 1)), totalEvicted); |
| } |
| |
| @Test |
| public void testMemoryLRUWithOverflowToDisk() { |
| final Host host = Host.getHost(0); |
| final VM vm2 = host.getVM(2); |
| final VM vm3 = host.getVM(3); |
| final VM vm0 = host.getVM(0); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxBuckets = 8; |
| final int localMaxMem = 16; |
| final int halfKb = 512; |
| final int justShyOfTwoMb = (2 * 1024 * 1024) - halfKb; |
| |
| final String name = uniqName + "-PR"; |
| final SerializableRunnable create = |
| new SerializableRunnable("Create Memory LRU with Overflow to disk partitioned Region") { |
| @Override |
| public void run() { |
| try { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies) |
| .setLocalMaxMemory(localMaxMem).setTotalNumBuckets(maxBuckets).create()); |
| |
| factory.setEvictionAttributes(EvictionAttributes |
| .createLRUMemoryAttributes(ObjectSizer.DEFAULT, EvictionAction.OVERFLOW_TO_DISK)); |
| factory.setDiskSynchronous(true); |
| DiskStoreFactory dsf = getCache().createDiskStoreFactory(); |
| final File[] diskDirs = new File[1]; |
| diskDirs[0] = new File("overflowDir/" + uniqName + "_" + OSProcess.getId()); |
| diskDirs[0].mkdirs(); |
| dsf.setDiskDirs(diskDirs); |
| DiskStore ds = dsf.create(name); |
| factory.setDiskStoreName(ds.getName()); |
| final PartitionedRegion pr = |
| (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } catch (final CacheException ex) { |
| Assert.fail("While creating Partitioned region", ex); |
| } |
| } |
| }; |
| vm3.invoke(create); |
| vm2.invoke(create); |
| final int extraEntries = 4; |
| final SerializableRunnable createBuckets = new SerializableRunnable("Create Buckets") { |
| @Override |
| public void run() { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| for (int counter = 1; counter <= localMaxMem + extraEntries; counter++) { |
| pr.put(new Integer(counter), new byte[1 * 1024 * 1024]); |
| } |
| } |
| }; |
| vm3.invoke(createBuckets); |
| |
| final SerializableCallable assertBucketAttributesAndEviction = |
| new SerializableCallable("Assert bucket attributes and eviction") { |
| @Override |
| public Object call() throws Exception { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| assertNull(pr.getDiskRegion()); |
| |
| // assert over-flow behavior in local buckets and number of |
| // entries |
| // overflowed |
| long entriesEvicted = 0; |
| for (final Iterator i = pr.getDataStore().getAllLocalBuckets().iterator(); i |
| .hasNext();) { |
| final Map.Entry entry = (Map.Entry) i.next(); |
| |
| final BucketRegion bucketRegion = (BucketRegion) entry.getValue(); |
| if (bucketRegion == null) { |
| continue; |
| } |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAlgorithm() |
| .isLRUMemory()); |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAction() |
| .isOverflowToDisk()); |
| |
| } |
| entriesEvicted += pr.getDiskRegionStats().getNumOverflowOnDisk(); |
| return new Long(entriesEvicted); |
| } |
| }; |
| final Long vm2i = (Long) vm2.invoke(assertBucketAttributesAndEviction); |
| final Long vm3i = (Long) vm3.invoke(assertBucketAttributesAndEviction); |
| final int totalEvicted = vm2i.intValue() + vm3i.intValue(); |
| assertTrue(2 * extraEntries <= totalEvicted); |
| |
| // Test for bug 42056 - make sure we get the faulted out entries. |
| vm0.invoke(create); |
| |
| vm0.invoke(new SerializableRunnable("Test to see that we can get keys") { |
| @Override |
| public void run() { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| // Make sure we can get all of the entries |
| for (int counter = 1; counter <= localMaxMem + extraEntries; counter++) { |
| assertNotNull(pr.get(new Integer(counter))); |
| } |
| } |
| }); |
| } |
| |
| @Test |
| public void testMemoryLRUWithLocalDestroy() { |
| final Host host = Host.getHost(0); |
| final VM vm2 = host.getVM(2); |
| final VM vm3 = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxBuckets = 8; |
| final int localMaxMem = 16; |
| final int halfKb = 512; |
| final int justShyOfTwoMb = (2 * 1024 * 1024) - halfKb; |
| final String name = uniqName + "-PR"; |
| |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Memory LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies) |
| .setLocalMaxMemory(16).setTotalNumBuckets(maxBuckets).create()); |
| factory.setEvictionAttributes(EvictionAttributes |
| .createLRUMemoryAttributes(ObjectSizer.DEFAULT, EvictionAction.LOCAL_DESTROY)); |
| final PartitionedRegion pr = (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| vm3.invoke(create); |
| vm2.invoke(create); |
| |
| final int extraEntries = 4; |
| final SerializableRunnable createBuckets = new SerializableRunnable("Create Buckets") { |
| @Override |
| public void run() { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| for (int counter = 1; counter <= localMaxMem + extraEntries; counter++) { |
| pr.put(new Integer(counter), new byte[1 * 1024 * 1024]); |
| } |
| } |
| }; |
| vm3.invoke(createBuckets); |
| |
| final SerializableCallable assertBucketAttributesAndEviction = |
| new SerializableCallable("Assert bucket attributes and eviction") { |
| @Override |
| public Object call() throws Exception { |
| try { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| long entriesEvicted = 0; |
| for (final Iterator i = pr.getDataStore().getAllLocalBuckets().iterator(); i |
| .hasNext();) { |
| final Map.Entry entry = (Map.Entry) i.next(); |
| |
| final BucketRegion bucketRegion = (BucketRegion) entry.getValue(); |
| if (bucketRegion == null) { |
| continue; |
| } |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAlgorithm() |
| .isLRUMemory()); |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAction() |
| .isLocalDestroy()); |
| } |
| entriesEvicted = pr.getTotalEvictions(); |
| return new Long(entriesEvicted); |
| } finally { |
| } |
| } |
| }; |
| final Long v2i = (Long) vm2.invoke(assertBucketAttributesAndEviction); |
| final Long v3i = (Long) vm3.invoke(assertBucketAttributesAndEviction); |
| final int totalEvicted = v2i.intValue() + v3i.intValue(); |
| assertTrue(2 * extraEntries <= totalEvicted); |
| } |
| |
| @Test |
| public void testEntryLRUWithOverflowToDisk() { |
| final Host host = Host.getHost(0); |
| final VM vm2 = host.getVM(2); |
| final VM vm3 = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxBuckets = 8; |
| final int maxEntries = 16; |
| final String name = uniqName + "-PR"; |
| final SerializableRunnable create = |
| new SerializableRunnable("Create Entry LRU with Overflow to disk partitioned Region") { |
| @Override |
| public void run() { |
| try { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setTotalNumBuckets(maxBuckets).create()); |
| factory.setEvictionAttributes(EvictionAttributes.createLRUEntryAttributes(maxEntries, |
| EvictionAction.OVERFLOW_TO_DISK)); |
| factory.setDiskSynchronous(true); |
| DiskStoreFactory dsf = getCache().createDiskStoreFactory(); |
| final File[] diskDirs = new File[1]; |
| diskDirs[0] = new File("overflowDir/" + uniqName + "_" + OSProcess.getId()); |
| diskDirs[0].mkdirs(); |
| dsf.setDiskDirs(diskDirs); |
| DiskStore ds = dsf.create(name); |
| factory.setDiskStoreName(ds.getName()); |
| final PartitionedRegion pr = |
| (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } catch (final CacheException ex) { |
| Assert.fail("While creating Partitioned region", ex); |
| } |
| } |
| }; |
| vm3.invoke(create); |
| vm2.invoke(create); |
| final int extraEntries = 4; |
| final SerializableRunnable createBuckets = new SerializableRunnable("Create Buckets") { |
| @Override |
| public void run() { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| for (int counter = 1; counter <= maxEntries + extraEntries; counter++) { |
| pr.put(new Integer(counter), new byte[1 * 1024 * 1024]); |
| } |
| } |
| }; |
| vm3.invoke(createBuckets); |
| |
| final SerializableCallable assertBucketAttributesAndEviction = |
| new SerializableCallable("Assert bucket attributes and eviction") { |
| @Override |
| public Object call() throws Exception { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| |
| // assert over-flow behavior in local buckets and number of |
| // entries |
| // overflowed |
| int entriesEvicted = 0; |
| for (final Iterator i = pr.getDataStore().getAllLocalBuckets().iterator(); i |
| .hasNext();) { |
| final Map.Entry entry = (Map.Entry) i.next(); |
| |
| final BucketRegion bucketRegion = (BucketRegion) entry.getValue(); |
| if (bucketRegion == null) { |
| continue; |
| } |
| assertTrue( |
| bucketRegion.getAttributes().getEvictionAttributes().getAlgorithm().isLRUEntry()); |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAction() |
| .isOverflowToDisk()); |
| } |
| entriesEvicted += pr.getDiskRegionStats().getNumOverflowOnDisk(); |
| return new Integer(entriesEvicted); |
| |
| } |
| }; |
| final Integer vm2i = (Integer) vm2.invoke(assertBucketAttributesAndEviction); |
| final Integer vm3i = (Integer) vm3.invoke(assertBucketAttributesAndEviction); |
| final int totalEvicted = vm2i.intValue() + vm3i.intValue(); |
| assertEquals(extraEntries * 2, totalEvicted); |
| } |
| |
| private static class VerifiableCacheListener extends CacheListenerAdapter |
| implements java.io.Serializable { |
| public boolean verify(long expectedEvictions) { |
| return false; |
| } |
| }; |
| |
| @Test |
| public void testEntryLRUWithLocalDestroy() { |
| final Host host = Host.getHost(0); |
| final VM vm2 = host.getVM(2); |
| final VM vm3 = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxBuckets = 8; |
| final int maxEntries = 16; |
| final String name = uniqName + "-PR"; |
| final int extraEntries = 4; |
| |
| // final int heapPercentage = 66; |
| // final int evictorInterval = 100; |
| |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setTotalNumBuckets(maxBuckets).create()); |
| factory.setEvictionAttributes( |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY)); |
| factory.addCacheListener(new VerifiableCacheListener() { |
| private long evictionDestroyEvents = 0; |
| |
| @Override |
| public void afterDestroy(EntryEvent e) { |
| System.out.println("EEEEEEEEEEEEEE key:" + e.getKey()); |
| EntryEventImpl eei = (EntryEventImpl) e; |
| if (Operation.EVICT_DESTROY.equals(eei.getOperation())) { |
| evictionDestroyEvents++; |
| } |
| } |
| |
| @Override |
| public boolean verify(long expectedEntries) { |
| return expectedEntries == evictionDestroyEvents; |
| } |
| }); |
| final PartitionedRegion pr = (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| vm3.invoke(create); |
| |
| final SerializableRunnable create2 = |
| new SerializableRunnable("Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run() { |
| try { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setTotalNumBuckets(8).create()); |
| factory |
| .setEvictionAttributes(EvictionAttributes.createLRUEntryAttributes(maxEntries)); |
| final PartitionedRegion pr = |
| (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } catch (final CacheException ex) { |
| Assert.fail("While creating Partitioned region", ex); |
| } |
| } |
| }; |
| vm2.invoke(create2); |
| |
| final SerializableRunnable createBuckets = new SerializableRunnable("Create Buckets") { |
| @Override |
| public void run() { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| for (int counter = 1; counter <= maxEntries + extraEntries; counter++) { |
| pr.put(new Integer(counter), new byte[1 * 1024 * 1024]); |
| } |
| } |
| }; |
| vm3.invoke(createBuckets); |
| |
| final SerializableCallable assertBucketAttributesAndEviction = |
| new SerializableCallable("Assert bucket attributes and eviction") { |
| @Override |
| public Object call() throws Exception { |
| try { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| for (final Iterator i = pr.getDataStore().getAllLocalBuckets().iterator(); i |
| .hasNext();) { |
| final Map.Entry entry = (Map.Entry) i.next(); |
| |
| final BucketRegion bucketRegion = (BucketRegion) entry.getValue(); |
| if (bucketRegion == null) { |
| continue; |
| } |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAlgorithm() |
| .isLRUEntry()); |
| assertTrue(bucketRegion.getAttributes().getEvictionAttributes().getAction() |
| .isLocalDestroy()); |
| } |
| return pr.getTotalEvictions(); |
| } finally { |
| } |
| } |
| }; |
| |
| final Long v2i = (Long) vm2.invoke(assertBucketAttributesAndEviction); |
| final Long v3i = (Long) vm3.invoke(assertBucketAttributesAndEviction); |
| final int totalEvicted = v2i.intValue() + v3i.intValue(); |
| assertEquals(2 * extraEntries, totalEvicted); |
| |
| final SerializableCallable assertListenerCount = new SerializableCallable( |
| "Assert that the number of listener invocations matches the expected total") { |
| @Override |
| public Object call() throws Exception { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| RegionAttributes attrs = pr.getAttributes(); |
| assertNotNull(attrs); |
| long entriesEvicted = pr.getTotalEvictions(); |
| VerifiableCacheListener verifyMe = null; |
| for (CacheListener listener : attrs.getCacheListeners()) { |
| if (listener instanceof VerifiableCacheListener) { |
| verifyMe = ((VerifiableCacheListener) listener); |
| } |
| } |
| assertNotNull(verifyMe); // assert if unable to find the expected listener |
| return verifyMe.verify(entriesEvicted); |
| } |
| }; |
| assertTrue((Boolean) vm3.invoke(assertListenerCount)); |
| } |
| |
| // Test to validate the Eviction Attribute : LRU Check |
| @Test |
| public void testEvictionValidationForLRUEntry() { |
| final Host host = Host.getHost(0); |
| final VM testAccessor = host.getVM(1); |
| final VM testDatastore = host.getVM(2); |
| final VM firstDatastore = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxEntries = 226; |
| final String name = uniqName + "-PR"; |
| |
| // final int evictionSizeInMB = 200; |
| final EvictionAttributes firstEvictionAttrs = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY); |
| |
| // Creating LRU Entry Count Eviction Attribute |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| |
| // Assert that LRUEntry maximum can be less than 1 entry per |
| // bucket |
| // DUnit not required for this test, but its a convenient place |
| // to put it. |
| { |
| final int buks = 11; |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(new PartitionAttributesFactory().setTotalNumBuckets(buks) |
| .setRedundantCopies(0).create()); |
| factory.setEvictionAttributes(EvictionAttributes.createLRUEntryAttributes((buks / 2))); |
| final PartitionedRegion pr = (PartitionedRegion) createRootRegion(name, factory.create()); |
| final Integer key = new Integer(1); |
| pr.put(key, "testval"); |
| final BucketRegion b; |
| try { |
| b = pr.getDataStore().getInitializedBucketForId(key, |
| new Integer(PartitionedRegionHelper.getHashKey(pr, null, key, null, null))); |
| } catch (final ForceReattemptException e) { |
| fail(); |
| } |
| pr.destroyRegion(); |
| } |
| |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| firstDatastore.invoke(create); |
| |
| final SerializableRunnable create2 = |
| new SerializableRunnable("Create Entry LRU with Overflow to disk partitioned Region") { |
| @Override |
| public void run() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| // Assert a different algo is invalid |
| try { |
| getCache().getLogger().info( |
| "<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(!firstEvictionAttrs.getAlgorithm().isLRUHeap()); |
| final EvictionAttributes illegalEa = |
| EvictionAttributes.createLRUHeapAttributes(null, firstEvictionAttrs.getAction()); |
| assertTrue(!firstEvictionAttrs.equals(illegalEa)); |
| factory.setEvictionAttributes(illegalEa); |
| setEvictionPercentage(50); |
| createRootRegion(name, factory.create()); |
| fail("Creating LRU Entry Count Eviction Attribute"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info("<ExpectedException action=remove>" |
| + "IllegalStateException</ExpectedException>"); |
| } |
| |
| // Assert a different action is invalid |
| try { |
| getCache().getLogger().info( |
| "<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(firstEvictionAttrs.getAlgorithm().isLRUEntry()); |
| assertTrue(!firstEvictionAttrs.getAction().isOverflowToDisk()); |
| final EvictionAttributes illegalEa = EvictionAttributes.createLRUEntryAttributes( |
| firstEvictionAttrs.getMaximum(), EvictionAction.OVERFLOW_TO_DISK); |
| assertTrue(!firstEvictionAttrs.equals(illegalEa)); |
| factory.setEvictionAttributes(illegalEa); |
| createRootRegion(name, factory.create()); |
| fail("Creating LRU Entry Count Eviction Attribute"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info("<ExpectedException action=remove>" |
| + "IllegalStateException</ExpectedException>"); |
| } |
| |
| |
| assertTrue(firstEvictionAttrs.getAlgorithm().isLRUEntry()); |
| final EvictionAttributes brokenEa = EvictionAttributes.createLRUEntryAttributes( |
| firstEvictionAttrs.getMaximum() + 1, firstEvictionAttrs.getAction()); |
| assertTrue(!firstEvictionAttrs.equals(brokenEa)); |
| factory.setEvictionAttributes(brokenEa); |
| createRootRegion(name, factory.create()); |
| } |
| }; |
| testDatastore.invoke(create2); |
| |
| testAccessor.invoke( |
| new CacheSerializableRunnable("Create an Accessor with and without eviction attributes") { |
| @Override |
| public void run2() throws CacheException { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| setEvictionPercentage(50); |
| Region r1 = createRootRegion(name, factory.create()); |
| assertNotNull(r1); |
| assertEquals(firstEvictionAttrs, r1.getAttributes().getEvictionAttributes()); |
| } |
| }); |
| } |
| |
| // Test to validate the Eviction Attribute : LRU Action |
| @Test |
| public void testEvictionValidationForLRUAction() { |
| final Host host = Host.getHost(0); |
| final VM testDatastore = host.getVM(2); |
| final VM firstDatastore = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxEntries = 226; |
| final String name = uniqName + "-PR"; |
| final EvictionAttributes firstEa = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY); |
| |
| // Creating LRU Entry Count Eviction Attribute : Algorithm : |
| // LOCAL_DESTROY |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes(firstEa); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertEquals(firstEa, pr.getAttributes().getEvictionAttributes()); |
| } |
| }; |
| firstDatastore.invoke(create); |
| |
| final SerializableRunnable create2 = |
| new SerializableRunnable("Create Entry LRU with Overflow to disk partitioned Region") { |
| @Override |
| public void run() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| // Creating LRU Entry Count Eviction Attribute : Action : |
| // OVERFLOW_TO_DISK // Exception should occur |
| try { |
| getCache().getLogger().info( |
| "<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(firstEa.getAlgorithm().isLRUEntry()); |
| assertTrue(!firstEa.getAction().isOverflowToDisk()); |
| factory.setEvictionAttributes(EvictionAttributes.createLRUEntryAttributes(maxEntries, |
| EvictionAction.OVERFLOW_TO_DISK)); |
| createRootRegion(name, factory.create()); |
| fail("Test to validate the Eviction Attribute : LRU Action"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info("<ExpectedException action=remove>" |
| + "IllegalStateException</ExpectedException>"); |
| } |
| // Creating LRU Entry Count Eviction Attribute : Action : NONE |
| // // Exception should occur |
| try { |
| getCache().getLogger().info( |
| "<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(firstEa.getAlgorithm().isLRUEntry()); |
| assertTrue(!firstEa.getAction().isNone()); |
| factory.setEvictionAttributes( |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.NONE)); |
| createRootRegion(name, factory.create()); |
| fail("Test to validate the Eviction Attribute : LRU Action"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info("<ExpectedException action=remove>" |
| + "IllegalStateException</ExpectedException>"); |
| } |
| // Creating LRU Entry Count Eviction Attribute : Action : |
| // LOCAL_DESTROY // Exception should not occur |
| factory.setEvictionAttributes(firstEa); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertEquals(firstEa, pr.getAttributes().getEvictionAttributes()); |
| } |
| }; |
| testDatastore.invoke(create2); |
| } |
| |
| // Test to validate the Eviction Attribute : LRU Maximum |
| @Test |
| public void testEvictionValidationForLRUMaximum() { |
| final Host host = Host.getHost(0); |
| final VM testDatastore = host.getVM(2); |
| final VM firstDatastore = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxEntries = 226; |
| final String name = uniqName + "-PR"; |
| final EvictionAttributes firstEvictionAttributes = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY); |
| |
| // Creating LRU Entry Count Eviction Attribute : maxentries : 2 |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertEquals(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| } |
| }; |
| firstDatastore.invoke(create); |
| |
| final SerializableRunnable create2 = |
| new SerializableRunnable("Create Entry LRU with Overflow to disk partitioned Region") { |
| @Override |
| public void run() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| |
| final EvictionAttributes ea = EvictionAttributes.createLRUEntryAttributes( |
| firstEvictionAttributes.getMaximum() + 10, firstEvictionAttributes.getAction()); |
| factory.setEvictionAttributes(ea); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| testDatastore.invoke(create2); |
| } |
| |
| // Test to validate the Eviction Attribute for LRUHeap |
| @Test |
| public void testEvictionValidationForLRUHeap() { |
| final Host host = Host.getHost(0); |
| final VM testDatastore = host.getVM(2); |
| final VM firstDatastore = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final String name = uniqName + "-PR"; |
| final int heapPercentage = 66; |
| final int evictorInterval = 100; |
| |
| final EvictionAttributes firstEvictionAttributes = EvictionAttributes.createLRUHeapAttributes(); |
| // Creating Heap LRU Eviction Attribute : evictorInterval : 100 |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| getCache().getResourceManager().setEvictionHeapPercentage(heapPercentage); |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertEquals(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| } |
| }; |
| firstDatastore.invoke(create); |
| |
| final SerializableRunnable create2 = |
| new SerializableRunnable("Create Entry LRU with Overflow to disk partitioned Region") { |
| @Override |
| public void run() { |
| setEvictionPercentage(heapPercentage); |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| // Assert that a different algo is invalid |
| try { |
| getCache().getLogger().info( |
| "<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(!firstEvictionAttributes.getAlgorithm().isLRUEntry()); |
| final EvictionAttributes invalidEa = EvictionAttributes.createLRUEntryAttributes(); |
| assertTrue(!invalidEa.equals(firstEvictionAttributes)); |
| factory.setEvictionAttributes(invalidEa); |
| createRootRegion(name, factory.create()); |
| fail("Expected an IllegalStateException"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info("<ExpectedException action=remove>" |
| + "IllegalStateException</ExpectedException>"); |
| } |
| |
| // Assert that a different action is invalid |
| try { |
| getCache().getLogger().info( |
| "<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(firstEvictionAttributes.getAlgorithm().isLRUHeap()); |
| assertTrue(!firstEvictionAttributes.getAction().isOverflowToDisk()); |
| final EvictionAttributes invalidEa = |
| EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK); |
| assertTrue(!invalidEa.equals(firstEvictionAttributes)); |
| factory.setEvictionAttributes(invalidEa); |
| createRootRegion(name, factory.create()); |
| fail("Expected an IllegalStateException"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info("<ExpectedException action=remove>" |
| + "IllegalStateException</ExpectedException>"); |
| } |
| |
| |
| // Assert that a different interval is valid |
| // { |
| // assertTrue(firstEvictionAttributes.getAlgorithm().isLRUHeap()); |
| // final EvictionAttributes okHeapLRUea = EvictionAttributes |
| // .createLRUHeapAttributes((int)(firstEvictionAttributes.getInterval() + 100), |
| // firstEvictionAttributes.getAction()); |
| // factory.setEvictionAttributes(okHeapLRUea); |
| // final Region pr = createRootRegion(name, factory.create()); |
| // assertNotNull(pr); |
| // assertIndexDetailsEquals(okHeapLRUea, pr.getAttributes().getEvictionAttributes()); |
| // pr.localDestroyRegion(); |
| // } |
| |
| // Assert that a different maximum is valid |
| // { |
| // assertTrue(firstEvictionAttributes.getAlgorithm().isLRUHeap()); |
| // final EvictionAttributes okHeapLRUea = EvictionAttributes |
| // .createLRUHeapAttributes( |
| // (int)firstEvictionAttributes.getInterval(), |
| // firstEvictionAttributes.getAction()); |
| // factory.setEvictionAttributes(okHeapLRUea); |
| // final Region pr = createRootRegion(name, factory.create()); |
| // assertNotNull(pr); |
| // assertIndexDetailsEquals(okHeapLRUea, pr.getAttributes().getEvictionAttributes()); |
| // pr.localDestroyRegion(); |
| // } |
| |
| // Assert that all attributes can be the same |
| { |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertEquals(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| } |
| } |
| }; |
| testDatastore.invoke(create2); |
| } |
| |
| // Test to validate an accessor can set the initial attributes |
| @Test |
| public void testEvictionValidationWhenInitializedByAccessor() { |
| final Host host = Host.getHost(0); |
| final VM testDatastore = host.getVM(2); |
| final VM accessor = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final String name = uniqName; |
| |
| final EvictionAttributes firstEvictionAttributes = EvictionAttributes |
| .createLRUMemoryAttributes(PartitionAttributesFactory.GLOBAL_MAX_BUCKETS_DEFAULT); |
| accessor.invoke( |
| new CacheSerializableRunnable("Create an Accessor which sets the first PR eviction attrs") { |
| @Override |
| public void run2() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(new PartitionAttributesFactory().setLocalMaxMemory(0) |
| .setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertNotSame(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| assertEquals(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| assertEquals(PartitionAttributesFactory.GLOBAL_MAX_BUCKETS_DEFAULT, |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| } |
| }); |
| |
| testDatastore.invoke( |
| new SerializableRunnable("Create a datastore to test existing eviction attributes") { |
| @Override |
| public void run() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| // Assert that the same attrs is valid |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertNotSame(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| assertNotSame(PartitionAttributesFactory.GLOBAL_MAX_BUCKETS_DEFAULT, |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| assertEquals(pr.getAttributes().getPartitionAttributes().getLocalMaxMemory(), |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| } |
| }); |
| } |
| |
| // Test to validate the Eviction Attribute : HeapLRU Interval |
| @Test |
| public void testEvictionValidationForLRUMemory() { |
| final Host host = Host.getHost(0); |
| final VM firstDatastore = host.getVM(1); |
| final VM testDatastore = host.getVM(2); |
| final VM testAccessor = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final String name = uniqName + "-PR"; |
| final EvictionAttributes firstEvictionAttributes = EvictionAttributes |
| .createLRUMemoryAttributes(PartitionAttributesFactory.GLOBAL_MAX_BUCKETS_DEFAULT * 2); |
| |
| firstDatastore |
| .invoke(new CacheSerializableRunnable("First datastore setting LRU memory eviction attrs") { |
| @Override |
| public void run2() { |
| // Assert that LRUMemory attributes may be lesser than 1 Mb per |
| // bucket |
| // DUnit not required for this test, but its a convenient place |
| // to put it. |
| { |
| final int totalNumBuckets = 11; |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(new PartitionAttributesFactory() |
| .setTotalNumBuckets(totalNumBuckets).setRedundantCopies(0).create()); |
| factory.setEvictionAttributes( |
| EvictionAttributes.createLRUMemoryAttributes((totalNumBuckets / 2))); |
| final PartitionedRegion pr = |
| (PartitionedRegion) createRootRegion(name, factory.create()); |
| final Integer key = new Integer(1); |
| pr.put(key, "testval"); |
| final BucketRegion b; |
| try { |
| b = pr.getDataStore().getInitializedBucketForId(key, |
| new Integer(PartitionedRegionHelper.getHashKey(pr, null, key, null, null))); |
| } catch (final ForceReattemptException e) { |
| fail(); |
| } |
| pr.destroyRegion(); |
| } |
| |
| // Set the "global" eviction attributes |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies).create()); |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertNotSame(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| assertNotSame(PartitionAttributesFactory.GLOBAL_MAX_BUCKETS_DEFAULT, |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| assertEquals(pr.getAttributes().getPartitionAttributes().getLocalMaxMemory(), |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| } |
| }); |
| |
| class PRLRUMemoryRunnable extends CacheSerializableRunnable { |
| private static final long serialVersionUID = 1L; |
| |
| final boolean isAccessor; |
| |
| public PRLRUMemoryRunnable(final boolean accessor) { |
| super("Test LRU memory eviction attrs on a " + (accessor ? " accessor" : " datastore")); |
| this.isAccessor = accessor; |
| } |
| |
| public PartitionAttributes createPartitionAttributes(final int localMaxMemory) { |
| if (this.isAccessor) { |
| return new PartitionAttributesFactory().setLocalMaxMemory(0) |
| .setRedundantCopies(redundantCopies).create(); |
| } else { |
| return new PartitionAttributesFactory().setLocalMaxMemory(localMaxMemory) |
| .setRedundantCopies(redundantCopies).create(); |
| } |
| } |
| |
| @Override |
| public void run2() throws CacheException { |
| // Configure a PR with the same local max mem as the eviction |
| // attributes... and do these tests |
| PartitionAttributes pra = createPartitionAttributes(firstEvictionAttributes.getMaximum()); |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| |
| // Assert that no eviction attributes is invalid |
| try { |
| getCache().getLogger() |
| .info("<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| final RegionAttributes attrs = factory.create(); |
| createRootRegion(name, attrs); |
| fail("Expected a IllegalStateException to be thrown"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info( |
| "<ExpectedException action=remove>" + "IllegalStateException</ExpectedException>"); |
| } |
| |
| // Assert different algo is invalid |
| try { |
| getCache().getLogger() |
| .info("<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(!((EvictionAttributesImpl) firstEvictionAttributes).isLIFOMemory()); |
| final EvictionAttributes badEa = |
| EvictionAttributesImpl.createLIFOMemoryAttributes(100, EvictionAction.LOCAL_DESTROY); |
| assertTrue(!badEa.equals(firstEvictionAttributes)); |
| factory.setEvictionAttributes(badEa); |
| createRootRegion(name, factory.create()); |
| fail("Test to validate the Eviction Attribute : HeapLRU Interval"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info( |
| "<ExpectedException action=remove>" + "IllegalStateException</ExpectedException>"); |
| } |
| |
| // Assert different action is invalid |
| try { |
| getCache().getLogger() |
| .info("<ExpectedException action=add>" + "IllegalStateException</ExpectedException>"); |
| assertTrue(!firstEvictionAttributes.getAction().isOverflowToDisk()); |
| assertTrue(firstEvictionAttributes.getAlgorithm().isLRUMemory()); |
| final EvictionAttributes badEa = |
| EvictionAttributes.createLRUMemoryAttributes(firstEvictionAttributes.getMaximum(), |
| firstEvictionAttributes.getObjectSizer(), EvictionAction.OVERFLOW_TO_DISK); |
| assertTrue(!badEa.equals(firstEvictionAttributes)); |
| factory.setEvictionAttributes(badEa); |
| createRootRegion(name, factory.create()); |
| fail("Test to validate the Eviction Attribute : HeapLRU Interval"); |
| } catch (final IllegalStateException expected) { |
| assertTrue(expected.getMessage().contains( |
| PartitionRegionConfigValidator.EVICTION_ATTRIBUTES_ARE_INCOMPATIBLE_MESSAGE)); |
| } finally { |
| getCache().getLogger().info( |
| "<ExpectedException action=remove>" + "IllegalStateException</ExpectedException>"); |
| } |
| |
| // Assert a smaller eviction maximum than the global is not valid (bug 40419) |
| { |
| assertTrue(firstEvictionAttributes.getAlgorithm().isLRUMemory()); |
| final EvictionAttributes okEa = |
| EvictionAttributes.createLRUMemoryAttributes(firstEvictionAttributes.getMaximum() - 1, |
| firstEvictionAttributes.getObjectSizer(), firstEvictionAttributes.getAction()); |
| if (!this.isAccessor) { |
| assertTrue(okEa.getMaximum() < pra.getLocalMaxMemory()); |
| } |
| assertTrue(!okEa.equals(firstEvictionAttributes)); |
| factory.setEvictionAttributes(okEa); |
| final RegionAttributes attrs = factory.create(); |
| final Region pr = createRootRegion(name, attrs); |
| assertNotNull(pr); |
| assertNotSame(okEa, pr.getAttributes().getEvictionAttributes()); |
| assertEquals(firstEvictionAttributes.getMaximum(), |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| pr.localDestroyRegion(); |
| } |
| |
| // Assert that a larger eviction maximum than the global is not |
| // valid (bug 40419) |
| { |
| assertTrue(firstEvictionAttributes.getAlgorithm().isLRUMemory()); |
| final EvictionAttributes okEa = |
| EvictionAttributes.createLRUMemoryAttributes(firstEvictionAttributes.getMaximum() + 1, |
| firstEvictionAttributes.getObjectSizer(), firstEvictionAttributes.getAction()); |
| assertTrue(!okEa.equals(firstEvictionAttributes)); |
| if (!this.isAccessor) { |
| assertEquals(okEa.getMaximum(), pra.getLocalMaxMemory() + 1); |
| } |
| factory.setEvictionAttributes(okEa); |
| final RegionAttributes attrs = factory.create(); |
| final Region pr = createRootRegion(name, attrs); |
| assertNotNull(pr); |
| assertNotSame(okEa, pr.getAttributes().getEvictionAttributes()); |
| assertEquals(firstEvictionAttributes.getMaximum(), |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| pr.localDestroyRegion(); |
| } |
| |
| // Assert that an eviction maximum larger than the |
| // localMaxMemroy is allowed |
| // and that the local eviction maximum is re-set to the |
| // localMaxMemory value |
| { |
| // lower the localMaxMemory |
| pra = createPartitionAttributes(firstEvictionAttributes.getMaximum() - 1); |
| factory.setPartitionAttributes(pra); |
| if (!this.isAccessor) { |
| assertTrue(firstEvictionAttributes.getMaximum() > pra.getLocalMaxMemory()); |
| } |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final RegionAttributes attrs = factory.create(); |
| final Region pr = createRootRegion(name, attrs); |
| assertNotNull(pr); |
| if (!this.isAccessor) { |
| assertEquals(pr.getAttributes().getPartitionAttributes().getLocalMaxMemory(), |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| } |
| pr.localDestroyRegion(); |
| } |
| |
| // Assert exact same attributes is valid |
| { |
| factory.setEvictionAttributes(firstEvictionAttributes); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| assertNotSame(firstEvictionAttributes, pr.getAttributes().getEvictionAttributes()); |
| assertEquals(pr.getAttributes().getPartitionAttributes().getLocalMaxMemory(), |
| pr.getAttributes().getEvictionAttributes().getMaximum()); |
| pr.localDestroyRegion(); |
| } |
| } |
| } |
| |
| testDatastore.invoke(new PRLRUMemoryRunnable(false)); |
| // testAccessor.invoke(new PRLRUMemoryRunnable(true)); |
| } |
| |
| |
| @Test |
| public void testEvictionValidationForLRUEntry_AccessorFirst() { |
| final Host host = Host.getHost(0); |
| final VM firstAccessor = host.getVM(0); |
| final VM testAccessor = host.getVM(1); |
| final VM testDatastore = host.getVM(2); |
| final VM firstDatastore = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxEntries = 226; |
| final String name = uniqName + "-PR"; |
| |
| final EvictionAttributes firstEvictionAttrs = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY); |
| |
| final EvictionAttributes secondEvictionAttrs = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.OVERFLOW_TO_DISK); |
| |
| final SerializableRunnable createFirstAccessor = |
| new CacheSerializableRunnable("Create an accessor without eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| final SerializableRunnable createFirstDataStore = |
| new CacheSerializableRunnable("Create a data store with eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| |
| final SerializableRunnable createSecondAccessor = |
| new CacheSerializableRunnable("Create an accessor with incorrect eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(secondEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| final SerializableRunnable createSecondDataStore = |
| new CacheSerializableRunnable("Create a data store with eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| firstAccessor.invoke(createFirstAccessor); |
| firstDatastore.invoke(createFirstDataStore); |
| testAccessor.invoke(createSecondAccessor); |
| testDatastore.invoke(createSecondDataStore); |
| } |
| |
| @Test |
| public void testEvictionValidationForLRUEntry_DatastoreFirst() { |
| final Host host = Host.getHost(0); |
| final VM firstAccessor = host.getVM(0); |
| final VM testAccessor = host.getVM(1); |
| final VM testDatastore = host.getVM(2); |
| final VM firstDatastore = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxEntries = 226; |
| final String name = uniqName + "-PR"; |
| |
| final EvictionAttributes firstEvictionAttrs = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY); |
| |
| final EvictionAttributes secondEvictionAttrs = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.OVERFLOW_TO_DISK); |
| |
| final SerializableRunnable createFirstAccessor = |
| new CacheSerializableRunnable("Create an accessor without eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| final SerializableRunnable createFirstDataStore = |
| new CacheSerializableRunnable("Create a data store with eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| |
| final SerializableRunnable createSecondAccessor = |
| new CacheSerializableRunnable("Create an accessor with incorrect eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(secondEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| final SerializableRunnable createSecondDataStore = |
| new CacheSerializableRunnable("Create a data store with eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| firstDatastore.invoke(createFirstDataStore); |
| firstAccessor.invoke(createFirstAccessor); |
| testDatastore.invoke(createSecondDataStore); |
| testAccessor.invoke(createSecondAccessor); |
| } |
| |
| @Test |
| public void testEvictionValidationForLRUEntry_TwoAccessors() { |
| final Host host = Host.getHost(0); |
| final VM firstAccessor = host.getVM(0); |
| final VM testAccessor = host.getVM(1); |
| final VM testDatastore = host.getVM(2); |
| final VM firstDatastore = host.getVM(3); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 1; |
| final int maxEntries = 226; |
| final String name = uniqName + "-PR"; |
| |
| final EvictionAttributes firstEvictionAttrs = |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY); |
| |
| final SerializableRunnable createFirstAccessor = |
| new CacheSerializableRunnable("Create an accessor without eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| final SerializableRunnable createFirstDataStore = |
| new CacheSerializableRunnable("Create a data store with eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| |
| final SerializableRunnable createSecondAccessor = |
| new CacheSerializableRunnable("Create an accessor with correct eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| |
| } |
| }; |
| final SerializableRunnable createSecondDataStore = |
| new CacheSerializableRunnable("Create a data store with eviction attributes") { |
| @Override |
| public void run2() { |
| final PartitionAttributes pra = new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setLocalMaxMemory(0).create(); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(pra); |
| factory.setEvictionAttributes(firstEvictionAttrs); |
| final Region pr = createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| firstAccessor.invoke(createFirstAccessor); |
| testAccessor.invoke(createSecondAccessor); |
| |
| firstDatastore.invoke(createFirstDataStore); |
| testDatastore.invoke(createSecondDataStore); |
| } |
| |
| /** |
| * Test that gets do not need to acquire a lock on the region entry when LRU is enabled. This is |
| * bug 42265 |
| */ |
| @Test |
| public void testEntryLRUDeadlock() { |
| final Host host = Host.getHost(0); |
| final VM vm0 = host.getVM(0); |
| final VM vm1 = host.getVM(1); |
| final String uniqName = getUniqueName(); |
| final int redundantCopies = 0; |
| final int maxBuckets = 8; |
| final int maxEntries = 16; |
| final String name = uniqName + "-PR"; |
| final int extraEntries = 4; |
| |
| // final int heapPercentage = 66; |
| // final int evictorInterval = 100; |
| |
| final SerializableRunnable create = new CacheSerializableRunnable( |
| "Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run2() { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes(new PartitionAttributesFactory() |
| .setRedundantCopies(redundantCopies).setTotalNumBuckets(maxBuckets).create()); |
| factory.setEvictionAttributes( |
| EvictionAttributes.createLRUEntryAttributes(maxEntries, EvictionAction.LOCAL_DESTROY)); |
| final PartitionedRegion pr = (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } |
| }; |
| vm0.invoke(create); |
| |
| final SerializableRunnable create2 = |
| new SerializableRunnable("Create Entry LRU with local destroy on a partitioned Region") { |
| @Override |
| public void run() { |
| try { |
| final AttributesFactory factory = new AttributesFactory(); |
| factory.setOffHeap(isOffHeap()); |
| factory.setPartitionAttributes( |
| new PartitionAttributesFactory().setRedundantCopies(redundantCopies) |
| .setLocalMaxMemory(0).setTotalNumBuckets(maxBuckets).create()); |
| factory |
| .setEvictionAttributes(EvictionAttributes.createLRUEntryAttributes(maxEntries)); |
| factory.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL)); |
| // this listener will cause a deadlock if the get ends up |
| // locking the entry. |
| factory.addCacheListener(new CacheListenerAdapter() { |
| |
| @Override |
| public void afterCreate(EntryEvent event) { |
| Region region = event.getRegion(); |
| Object key = event.getKey(); |
| region.get(key); |
| } |
| |
| }); |
| final PartitionedRegion pr = |
| (PartitionedRegion) createRootRegion(name, factory.create()); |
| assertNotNull(pr); |
| } catch (final CacheException ex) { |
| Assert.fail("While creating Partitioned region", ex); |
| } |
| } |
| }; |
| vm1.invoke(create2); |
| |
| final SerializableRunnable doPuts = new SerializableRunnable("Do Puts") { |
| @Override |
| public void run() { |
| final PartitionedRegion pr = (PartitionedRegion) getRootRegion(name); |
| assertNotNull(pr); |
| for (int counter = 0; counter <= maxEntries + extraEntries; counter++) { |
| pr.put(new Integer(counter), "value"); |
| } |
| } |
| }; |
| vm0.invoke(doPuts); |
| } |
| |
| protected void setEvictionPercentage(float percentage) { |
| getCache().getResourceManager().setEvictionHeapPercentage(percentage); |
| } |
| |
| protected boolean isOffHeap() { |
| return false; |
| } |
| |
| protected ResourceType getMemoryType() { |
| return ResourceType.HEAP_MEMORY; |
| } |
| |
| protected HeapEvictor getEvictor(Region region) { |
| return ((GemFireCacheImpl) region.getRegionService()).getHeapEvictor(); |
| } |
| } |