You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2019/06/04 15:29:04 UTC
[geode] branch develop updated: GEODE-2685: support getStatistics
on PartitionedRegion (#3576)
This is an automated email from the ASF dual-hosted git repository.
dschneider pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new f00fa83 GEODE-2685: support getStatistics on PartitionedRegion (#3576)
f00fa83 is described below
commit f00fa835e20d022b74abf358fca763c955e0d5fa
Author: albertogpz <al...@est.tech>
AuthorDate: Tue Jun 4 17:28:52 2019 +0200
GEODE-2685: support getStatistics on PartitionedRegion (#3576)
getStatistics for a partitioned region that is not a proxy will return a CacheStatistics whose methods always compute their results from local bucket state.
For a proxy partitioned region The CacheStatistics methods will always return 0.
---
.../CacheStatisticsPartitionedRegionDUnitTest.java | 505 +++++++++++++++++++++
.../ShowMetricsCommandIntegrationTest.java | 2 +-
.../main/java/org/apache/geode/cache/Region.java | 4 +-
.../geode/internal/cache/PartitionedRegion.java | 54 ++-
.../dunit/cache/internal/JUnit4CacheTestCase.java | 24 +
5 files changed, 580 insertions(+), 9 deletions(-)
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheStatisticsPartitionedRegionDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheStatisticsPartitionedRegionDUnitTest.java
new file mode 100644
index 0000000..743388a
--- /dev/null
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheStatisticsPartitionedRegionDUnitTest.java
@@ -0,0 +1,505 @@
+/*
+ * 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.cache30;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import org.apache.geode.cache.AttributesFactory;
+import org.apache.geode.cache.CacheException;
+import org.apache.geode.cache.CacheStatistics;
+import org.apache.geode.cache.PartitionAttributesFactory;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.StatisticsDisabledException;
+import org.apache.geode.internal.cache.InternalRegion;
+import org.apache.geode.test.dunit.SerializableRunnableIF;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
+
+/**
+ * Tests the {@link CacheStatistics} that are maintained by a partitioned {@link Region} .
+ *
+ *
+ * @since GemFire 3.0
+ */
+
+public class CacheStatisticsPartitionedRegionDUnitTest extends JUnit4CacheTestCase {
+
+ public CacheStatisticsPartitionedRegionDUnitTest() {
+ super();
+ }
+
+ //////// Helper Methods
+
+ /**
+ * Asserts that two <code>long</code>s are equal concerning a delta.
+ */
+ public static void assertInRange(long start, long end, long actual) {
+ assertTrue("Expected: " + actual + " >= " + start, actual >= start);
+ assertTrue("Expected: " + actual + " <= " + end, actual <= end);
+ }
+
+ //////// Test methods
+
+ /**
+ * Tests that the {@link CacheStatistics#getHitCount hit count} and
+ * {@link CacheStatistics#getMissCount miss count} are updated properly for a partitioned region
+ * with only one server.
+ */
+ @Test
+ public void testHitMissCount() throws CacheException {
+ String name = this.getUniqueName();
+ Object key = "KEY"; // value exists
+ Object key2 = "KEY2"; // no entry
+ Object key3 = "KEY3"; // entry, invalid
+ Object value = "VALUE";
+
+ AttributesFactory factory = new AttributesFactory();
+ factory.setStatisticsEnabled(true);
+
+ Region region = createPartitionedRegion(name, factory.create());
+ CacheStatistics rStats = region.getStatistics();
+ assertEquals(0, rStats.getHitCount());
+ assertEquals(0, rStats.getMissCount());
+ assertEquals(0.0f, rStats.getHitRatio(), 0.0f);
+
+ region.get(key);
+ assertEquals(1, rStats.getMissCount());
+ assertEquals(0, rStats.getHitCount());
+ assertEquals(0.0f, rStats.getHitRatio(), 0.0f);
+
+ region.get(key);
+ assertEquals(2, rStats.getMissCount());
+ assertEquals(0, rStats.getHitCount());
+ assertEquals(0.0f, rStats.getHitRatio(), 0.0f);
+
+ rStats.resetCounts();
+ assertEquals(0, rStats.getMissCount());
+ assertEquals(0, rStats.getHitCount());
+ assertEquals(0.0f, rStats.getHitRatio(), 0.0f);
+
+ region.put(key, value);
+ assertEquals(0, rStats.getHitCount());
+ assertEquals(0, rStats.getMissCount());
+ assertEquals(0.0f, rStats.getHitRatio(), 0.0f);
+
+ region.get(key);
+ assertEquals(1, rStats.getHitCount());
+ assertEquals(0, rStats.getMissCount());
+ assertEquals(1.0f, rStats.getHitRatio(), 0.0f);
+
+ region.get(key2);
+ assertEquals(1, rStats.getMissCount());
+ assertEquals(1, rStats.getHitCount());
+ assertEquals(0.5f, rStats.getHitRatio(), 0.0f);
+
+ region.create(key3, null);
+ region.get(key3); // miss on existing entry
+ assertEquals(2, rStats.getMissCount());
+ assertEquals(1, rStats.getHitCount());
+ assertEquals(0.33f, rStats.getHitRatio(), 0.01f);
+
+ rStats.resetCounts();
+ assertEquals(0, rStats.getMissCount());
+ assertEquals(0, rStats.getHitCount());
+ assertEquals(0.0f, rStats.getHitRatio(), 0.0f);
+
+ region.invalidate(key);
+ region.get(key);
+
+ assertEquals(0, rStats.getHitCount());
+ assertEquals(1, rStats.getMissCount());
+ assertEquals(0.0f, rStats.getHitRatio(), 0.0f);
+ }
+
+ /**
+ * Tests that the {@linkplain CacheStatistics#getLastAccessedTime last access time} and
+ * {@link CacheStatistics#getLastModifiedTime last modified time} are updated appropriately for a
+ * partitioned region with only one server.
+ */
+ @Test
+ public void testTimeStats() throws CacheException, InterruptedException {
+ final long ESTAT_RES = 100; // the resolution, in ms, of entry stats
+ String name = this.getUniqueName();
+ Object key1 = Integer.valueOf(1);
+ Object key2 = Integer.valueOf(2);
+ Object missingKey = Integer.valueOf(999);
+ Object value = "VALUE";
+ long before;
+ long after;
+ long oldBefore;
+ long oldAfter;
+
+ AttributesFactory factory = new AttributesFactory();
+ // factory.setScope(Scope.LOCAL);
+ factory.setStatisticsEnabled(true);
+
+ Region region = createPartitionedRegion(name, factory.create());
+ CacheStatistics rStats = region.getStatistics();
+
+ assertEquals(0, rStats.getLastAccessedTime());
+ assertEquals(0, rStats.getLastModifiedTime());
+
+ before = ((InternalRegion) region).cacheTimeMillis();
+ // When the get is invoked, the lastAccessedTime and lastModified time
+ // are updated as a new BucketRegion is created.
+ region.get(missingKey);
+
+ after = ((InternalRegion) region).cacheTimeMillis();
+
+ assertInRange(before, after, rStats.getLastAccessedTime());
+ assertInRange(before, after, rStats.getLastModifiedTime());
+
+ oldBefore = before;
+ oldAfter = after;
+ waitForClockToChange(region);
+ before = ((InternalRegion) region).cacheTimeMillis();
+ region.get(missingKey);
+
+ after = ((InternalRegion) region).cacheTimeMillis();
+
+ assertInRange(before, after, rStats.getLastAccessedTime());
+ assertInRange(oldBefore, oldAfter, rStats.getLastModifiedTime());
+
+ waitForClockToChange(region);
+ before = ((InternalRegion) region).cacheTimeMillis();
+ region.put(key1, value);
+ CacheStatistics eStats = region.getEntry(key1).getStatistics();
+ after = ((InternalRegion) region).cacheTimeMillis();
+
+ assertInRange(before, after, rStats.getLastModifiedTime());
+ assertInRange(before, after, rStats.getLastAccessedTime());
+
+ assertInRange(before - ESTAT_RES, after + ESTAT_RES, eStats.getLastAccessedTime());
+ assertInRange(before - ESTAT_RES, after + ESTAT_RES, eStats.getLastModifiedTime());
+
+ oldBefore = before;
+ oldAfter = after;
+ waitForClockToChange(region);
+ before = ((InternalRegion) region).cacheTimeMillis();
+ region.get(key1);
+ // eStats must be obtained again. The previous object is not updated.
+ // Seems it just provides a snapshot at the moment it is received.
+ eStats = region.getEntry(key1).getStatistics();
+ after = ((InternalRegion) region).cacheTimeMillis();
+
+ assertInRange(before, after, rStats.getLastAccessedTime());
+ assertInRange(oldBefore, oldAfter, rStats.getLastModifiedTime());
+ assertInRange(before - ESTAT_RES, after + ESTAT_RES, eStats.getLastAccessedTime());
+ assertInRange(oldBefore - ESTAT_RES, oldAfter + ESTAT_RES, eStats.getLastModifiedTime());
+
+ long oldOldBefore = oldBefore;
+ long oldOldAfter = oldAfter;
+ oldBefore = before;
+ oldAfter = after;
+ waitForClockToChange(region, ESTAT_RES);
+ before = ((InternalRegion) region).cacheTimeMillis();
+ region.create(key2, null);
+ region.get(key2);
+ CacheStatistics eStats2 = region.getEntry(key2).getStatistics();
+ after = ((InternalRegion) region).cacheTimeMillis();
+
+ assertInRange(before, after, rStats.getLastModifiedTime());
+ assertInRange(before, after, rStats.getLastAccessedTime());
+
+ assertInRange(oldBefore - ESTAT_RES, oldAfter + ESTAT_RES, eStats.getLastAccessedTime());
+ assertInRange(oldOldBefore - ESTAT_RES, oldOldAfter + ESTAT_RES, eStats.getLastModifiedTime());
+
+ assertInRange(before - ESTAT_RES, after + ESTAT_RES, eStats2.getLastAccessedTime());
+ assertInRange(before - ESTAT_RES, after + ESTAT_RES, eStats2.getLastModifiedTime());
+
+ // Invalidation does not update the modification/access
+ // times
+ region.invalidate(key2);
+
+ assertInRange(before, after, rStats.getLastModifiedTime());
+ assertInRange(before - ESTAT_RES, after + ESTAT_RES, eStats2.getLastAccessedTime());
+ assertInRange(before - ESTAT_RES, after + ESTAT_RES, eStats2.getLastModifiedTime());
+ assertInRange(before, after, rStats.getLastAccessedTime());
+
+ region.destroy(key2);
+
+ assertInRange(before, after, rStats.getLastModifiedTime());
+ assertInRange(before, after, rStats.getLastAccessedTime());
+ }
+
+ private void waitForClockToChange(Region region) {
+ waitForClockToChange(region, 0);
+ }
+
+ /**
+ * Waits for the time in the <code>region</code> to step up
+ * beyond the current time in the region plus the number of
+ * milliseconds passed in the <code>millisecs</code> argument.
+ */
+ private void waitForClockToChange(Region region, long millisecs) {
+ long time = ((InternalRegion) region).cacheTimeMillis();
+ while (time >= ((InternalRegion) region).cacheTimeMillis() + millisecs) {
+ }
+ }
+
+
+ /** The last time an entry was accessed */
+ protected static volatile long lastAccessed;
+ protected static volatile long lastModified;
+
+
+ /**
+ * Tests that the {@link CacheStatistics#getHitCount hit count},
+ * {@link CacheStatistics#getMissCount miss count},
+ * {@linkplain CacheStatistics#getLastAccessedTime last access time}
+ * and {@link CacheStatistics#getLastModifiedTime last modified time} are updated
+ * properly for a partitioned region
+ * with more than one server.
+ */
+ @Test
+ public void testDistributedStats() {
+ final String name = this.getUniqueName();
+ final Object key0 = Integer.valueOf(0);
+ final Object key1 = Integer.valueOf(1);
+ final Object key2 = Integer.valueOf(2);
+ final Object key3 = Integer.valueOf(3);
+ final Object value = "VALUE";
+ final Object value1 = "VALUE1";
+ final Object value2 = "VALUE2";
+ final Object value3 = "VALUE3";
+ final Object notPresentKey1 = "NOT_PRESENT_1";
+ final Object notPresentKey2 = "NOT_PRESENT_2";
+ final Object notPresentKey3 = "NOT_PRESENT_3";
+ final Object notPresentKey4 = "NOT_PRESENT_4";
+
+ VM vm0 = VM.getVM(0);
+ VM vm1 = VM.getVM(1);
+
+ SerializableRunnableIF create = () -> {
+ AttributesFactory factory = new AttributesFactory();
+ factory.setEarlyAck(false);
+ factory.setStatisticsEnabled(true);
+ createPartitionedRegion(name, factory.create());
+ };
+
+ vm0.invoke(create);
+ vm1.invoke(create);
+
+ vm0.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ region.put(key0, value);
+ region.put(key1, value1);
+
+ assertTrue(stats.getLastModifiedTime() > lastModified);
+ assertEquals(0, stats.getHitCount());
+ assertEquals(0, stats.getMissCount());
+ });
+
+ vm1.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ region.put(key2, value3);
+ region.put(key3, value3);
+
+ assertTrue(stats.getLastModifiedTime() > lastModified);
+ assertEquals(0, stats.getHitCount());
+ assertEquals(0, stats.getMissCount());
+ });
+
+ vm0.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ lastAccessed = stats.getLastAccessedTime();
+ lastModified = stats.getLastModifiedTime();
+
+ Object result = region.get(key0);
+ region.get(key1);
+ region.get(key2);
+ region.get(key3);
+ region.get(notPresentKey1);
+ region.get(notPresentKey2);
+ region.get(notPresentKey3);
+ region.get(notPresentKey4);
+
+ assertEquals(value, result);
+ assertEquals(2, stats.getMissCount());
+ assertEquals(2, stats.getHitCount());
+ assertTrue(stats.getLastAccessedTime() > lastAccessed);
+ });
+
+ vm0.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ lastAccessed = stats.getLastAccessedTime();
+
+ Object result = region.get(key0);
+ region.get(key1);
+ region.get(key2);
+ region.get(key3);
+ region.get(notPresentKey1);
+ region.get(notPresentKey2);
+ region.get(notPresentKey3);
+ region.get(notPresentKey4);
+
+ assertEquals(value, result);
+ assertEquals(4, stats.getHitCount());
+ assertEquals(4, stats.getMissCount());
+ assertTrue(stats.getLastAccessedTime() > lastAccessed);
+ });
+
+ vm0.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ long before = ((InternalRegion) region).cacheTimeMillis();
+ region.put(key0, value);
+ region.put(key1, value1);
+ region.put(key2, value2);
+ region.put(key3, value3);
+ long after = ((InternalRegion) region).cacheTimeMillis();
+ assertTrue(before <= stats.getLastModifiedTime());
+ assertTrue(after >= stats.getLastModifiedTime());
+ });
+
+ vm1.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ long before = ((InternalRegion) region).cacheTimeMillis();
+ region.put(key0, value);
+ region.put(key1, value1);
+ region.put(key2, value2);
+ region.put(key3, value3);
+ long after = ((InternalRegion) region).cacheTimeMillis();
+ assertTrue(before <= stats.getLastModifiedTime());
+ assertTrue(after >= stats.getLastModifiedTime());
+ });
+
+ vm0.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ lastAccessed = stats.getLastAccessedTime();
+ lastModified = stats.getLastModifiedTime();
+ region.invalidate(key0);
+ region.invalidate(key1);
+ assertEquals(lastAccessed, stats.getLastAccessedTime());
+ assertEquals(lastModified, stats.getLastModifiedTime());
+ assertEquals(4, stats.getHitCount());
+ assertEquals(4, stats.getMissCount());
+ });
+
+ vm1.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ lastAccessed = stats.getLastAccessedTime();
+ lastModified = stats.getLastModifiedTime();
+ region.invalidate(key2);
+ region.invalidate(key3);
+
+ assertEquals(lastAccessed, stats.getLastAccessedTime());
+ assertEquals(lastModified, stats.getLastModifiedTime());
+ assertEquals(4, stats.getHitCount());
+ assertEquals(4, stats.getMissCount());
+ });
+
+ vm0.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ lastModified = stats.getLastModifiedTime();
+ region.destroy(key0);
+ region.destroy(key1);
+
+ assertEquals(lastModified, stats.getLastModifiedTime());
+ assertEquals(4, stats.getHitCount());
+ assertEquals(4, stats.getMissCount());
+ });
+
+ vm1.invoke(() -> {
+ Region region = getRootRegion(name);
+ CacheStatistics stats = region.getStatistics();
+ lastModified = stats.getLastModifiedTime();
+ region.destroy(key2);
+ region.destroy(key3);
+
+ assertEquals(lastModified, stats.getLastModifiedTime());
+ assertEquals(4, stats.getHitCount());
+ assertEquals(4, stats.getMissCount());
+ });
+
+ }
+
+ /**
+ * Tests that an attempt to get statistics when they are disabled results in a
+ * {@link StatisticsDisabledException}.
+ */
+ @Test
+ public void testDisabledStatistics() throws CacheException {
+ String name = this.getUniqueName();
+ Object key = "KEY";
+ Object value = "VALUE";
+
+ AttributesFactory factory = new AttributesFactory();
+ factory.setStatisticsEnabled(false);
+ Region region = createPartitionedRegion(name, factory.create());
+
+ assertThatThrownBy(() -> region.getStatistics())
+ .isInstanceOf(StatisticsDisabledException.class);
+
+ region.put(key, value);
+ Region.Entry entry = region.getEntry(key);
+
+ assertThatThrownBy(() -> entry.getStatistics()).isInstanceOf(StatisticsDisabledException.class);
+ }
+
+ /**
+ * Tests that the stats values for a Proxy PartitionedRegion are all 0.
+ */
+ @Test
+ public void testProxyRegionStats() throws CacheException {
+ String name = this.getUniqueName();
+ Object key = Integer.valueOf(0);
+ Object missingKey = Integer.valueOf(999);
+ Object value = "VALUE";
+
+ // Create the PARTITION_PROXY region
+ AttributesFactory proxyRegionAttrsFactory = new AttributesFactory();
+ proxyRegionAttrsFactory.setStatisticsEnabled(true);
+ PartitionAttributesFactory paf = new PartitionAttributesFactory();
+ // Setting LocalMaxMemory to 0 makes the region of PROXY type
+ paf.setLocalMaxMemory(0);
+ proxyRegionAttrsFactory.setPartitionAttributes(paf.create());
+ Region region = createPartitionedRegion(name, proxyRegionAttrsFactory.create());
+
+ // Create the region as not proxy on another server to be able to add entries.
+ VM vm0 = VM.getVM(0);
+ vm0.invoke(() -> {
+ AttributesFactory factory = new AttributesFactory();
+ factory.setStatisticsEnabled(true);
+ createPartitionedRegion(name, factory.create());
+ });
+
+ region.put(key, value);
+ region.get(key);
+ region.get(missingKey);
+
+ CacheStatistics stats = region.getStatistics();
+ assertEquals(0, stats.getLastModifiedTime());
+ assertEquals(0, stats.getLastAccessedTime());
+ assertEquals(0, stats.getHitCount());
+ assertEquals(0, stats.getMissCount());
+ assertEquals(0.0f, stats.getHitRatio(), 0.0f);
+
+ // Call reset counts to check that no exception is raised
+ stats.resetCounts();
+ }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommandIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommandIntegrationTest.java
index 77f8973..7e6ccf5 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommandIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommandIntegrationTest.java
@@ -168,6 +168,6 @@ public class ShowMetricsCommandIntegrationTest {
gfsh.executeAndAssertThat(cmd).statusIsSuccess();
String cmd2 = "show metrics --member=" + MEMBER_NAME + " --region=region2";
gfsh.executeAndAssertThat(cmd2).statusIsSuccess().tableHasRowWithValues("Category", "Metric",
- "Value", "", "missCount", "-1");
+ "Value", "", "missCount", "0");
}
}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/Region.java b/geode-core/src/main/java/org/apache/geode/cache/Region.java
index 28f3d71..6413113 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/Region.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/Region.java
@@ -204,11 +204,11 @@ public interface Region<K, V> extends ConcurrentMap<K, V> {
AttributesMutator<K, V> getAttributesMutator();
/**
- * Returns the <code>CacheStatistics</code> for this region.
+ * Returns the <code>CacheStatistics</code> for this region. If the region is a partitioned proxy
+ * region then the values for all the statistics will be 0.
*
* @return the <code>CacheStatistics</code> of this region
* @throws StatisticsDisabledException if statistics have been disabled for this region
- * @throws UnsupportedOperationException If the region is a partitioned region
*/
CacheStatistics getStatistics() throws StatisticsDisabledException;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
index d2941d8..bfe605d 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
@@ -1857,13 +1857,55 @@ public class PartitionedRegion extends LocalRegion
throw new UnsupportedOperationException();
}
- /**
- * @since GemFire 5.0
- * @throws UnsupportedOperationException OVERRIDES
- */
@Override
- public CacheStatistics getStatistics() {
- throw new UnsupportedOperationException();
+ public long getLastModifiedTime() {
+ if (!this.canStoreDataLocally()) {
+ return 0;
+ }
+ Set<BucketRegion> buckets = this.dataStore.getAllLocalBucketRegions();
+ long lastModifiedTime =
+ buckets.stream().map(x -> x.getLastModifiedTime()).reduce(0L, (a, b) -> a > b ? a : b);
+ return lastModifiedTime;
+ }
+
+ @Override
+ public long getLastAccessedTime() {
+ if (!this.canStoreDataLocally()) {
+ return 0;
+ }
+ Set<BucketRegion> buckets = this.dataStore.getAllLocalBucketRegions();
+ long lastAccessedTime =
+ buckets.stream().map(x -> x.getLastAccessedTime()).reduce(0L, (a, b) -> a > b ? a : b);
+ return lastAccessedTime;
+ }
+
+ @Override
+ public long getMissCount() {
+ if (!this.canStoreDataLocally()) {
+ return 0;
+ }
+ Set<BucketRegion> buckets = this.dataStore.getAllLocalBucketRegions();
+ return buckets.stream().map(x -> x.getMissCount()).reduce(0L, (a, b) -> a + b);
+ }
+
+ @Override
+ public long getHitCount() {
+ if (!this.canStoreDataLocally()) {
+ return 0;
+ }
+ Set<BucketRegion> buckets = this.dataStore.getAllLocalBucketRegions();
+ return buckets.stream().map(x -> x.getHitCount()).reduce(0L, (a, b) -> a + b);
+ }
+
+ @Override
+ public void resetCounts() {
+ if (!this.canStoreDataLocally()) {
+ return;
+ }
+ Set<BucketRegion> buckets = this.dataStore.getAllLocalBucketRegions();
+ for (BucketRegion bucket : buckets) {
+ bucket.resetCounts();
+ }
}
/**
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java
index 9a77bf2..954af45 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java
@@ -32,6 +32,7 @@ import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.CacheTransactionManager;
+import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
@@ -399,6 +400,29 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
return createRegion(name, "root", attributes);
}
+ public final <K, V> Region<K, V> createPartitionedRegion(final String rootName,
+ final RegionAttributes<K, V> attributes) throws CacheException {
+ Region<K, V> root = getRootRegion(rootName);
+ if (root == null) {
+ // don't put listeners on root region
+ AttributesFactory<K, V> attributesFactory = new AttributesFactory<>(attributes);
+ ExpirationAttributes expiration = ExpirationAttributes.DEFAULT;
+
+ attributesFactory.setCacheLoader(null);
+ attributesFactory.setCacheWriter(null);
+ attributesFactory.setPoolName(null);
+ attributesFactory.setDataPolicy(DataPolicy.PARTITION);
+ attributesFactory.setRegionTimeToLive(expiration);
+ attributesFactory.setEntryTimeToLive(expiration);
+ attributesFactory.setRegionIdleTimeout(expiration);
+ attributesFactory.setEntryIdleTimeout(expiration);
+
+ RegionAttributes<K, V> rootAttrs = attributesFactory.create();
+ root = createRootRegion(rootName, rootAttrs);
+ }
+ return root;
+ }
+
public final <K, V> Region<K, V> createRegion(final String name, final String rootName,
final RegionAttributes<K, V> attributes) throws CacheException {
Region<K, V> root = getRootRegion(rootName);