You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by mh...@apache.org on 2021/07/13 16:35:46 UTC

[geode] branch feature/GEODE-7665 updated: GEODE-9194: Feature/region stats update (#6430)

This is an automated email from the ASF dual-hosted git repository.

mhanson pushed a commit to branch feature/GEODE-7665
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/feature/GEODE-7665 by this push:
     new 6754d1a  GEODE-9194: Feature/region stats update (#6430)
6754d1a is described below

commit 6754d1a40822e966d9d420443daed84205d051ce
Author: mhansonp <ha...@vmware.com>
AuthorDate: Tue Jul 13 09:34:54 2021 -0700

    GEODE-9194: Feature/region stats update (#6430)
    
    * GEODE-9194: add PR Region Clear statistics
---
 .../cache/RegionClearStatsDistributedTest.java     |  33 ++--
 .../cache/PartitionedRegionClearDUnitTest.java     | 139 ++++++++-------
 ...tionedRegionLocalMaxMemoryOffHeapDUnitTest.java |   2 +-
 .../partitioned/PRQueryCacheClosedJUnitTest.java   | 116 ++++++------
 .../cache/query/partitioned/PRQueryJUnitTest.java  |  51 +++---
 .../partitioned/PRQueryRegionClosedJUnitTest.java  | 131 ++++++--------
 .../PRQueryRegionDestroyedJUnitTest.java           |   5 +-
 .../geode/internal/cache/ColocatedPRJUnitTest.java |   4 +-
 .../cache/PartitionedRegionCreationJUnitTest.java  |   4 +-
 .../cache/PartitionedRegionStatsJUnitTest.java     | 198 ++++++++++++++++++++-
 .../geode/internal/cache/AbstractRegion.java       |   2 +
 .../geode/internal/cache/AbstractRegionMap.java    | 169 +++++++++---------
 .../apache/geode/internal/cache/BucketRegion.java  |  24 ++-
 .../geode/internal/cache/CachePerfStats.java       |  79 ++++----
 .../geode/internal/cache/DummyCachePerfStats.java  |  10 ++
 .../geode/internal/cache/GemFireCacheImpl.java     |  15 +-
 .../apache/geode/internal/cache/LocalRegion.java   |  17 +-
 .../geode/internal/cache/PartitionedRegion.java    |  31 +++-
 .../internal/cache/PartitionedRegionClear.java     |  24 +--
 .../internal/cache/PartitionedRegionStats.java     |  47 +++++
 .../geode/internal/cache/RegionPerfStats.java      |  25 ++-
 .../apache/geode/internal/cache/RegionStats.java   |   4 +-
 .../geode/internal/cache/CachePerfStatsTest.java   |  64 +++----
 .../internal/cache/PartitionedRegionTest.java      |  14 +-
 .../cache/PartitionedRegionTestHelper.java         | 130 +++++++-------
 25 files changed, 775 insertions(+), 563 deletions(-)

diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache/RegionClearStatsDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache/RegionClearStatsDistributedTest.java
index 50cea82..888a996 100755
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache/RegionClearStatsDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache/RegionClearStatsDistributedTest.java
@@ -38,7 +38,6 @@ import org.apache.geode.test.dunit.rules.DistributedRule;
 /**
  * verifies the count of clear operation
  */
-@SuppressWarnings("serial")
 public class RegionClearStatsDistributedTest implements Serializable {
 
   private static final String REGION_NAME = RegionClearStatsDistributedTest.class.getSimpleName();
@@ -58,7 +57,7 @@ public class RegionClearStatsDistributedTest implements Serializable {
   public CacheRule cacheRule = new CacheRule();
 
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
     server1 = getVM(0);
     client1 = getVM(1);
   }
@@ -68,14 +67,14 @@ public class RegionClearStatsDistributedTest implements Serializable {
    */
   @Test
   public void testClearStatsWithNormalRegion() {
-    int port = server1.invoke(() -> createServerCache());
+    int port = server1.invoke(this::createServerCache);
     client1.invoke(() -> createClientCache(getServerHostName(), port));
 
-    client1.invoke(() -> doPutsAndClear());
-    client1.invoke(() -> doPutsAndClear());
+    client1.invoke(this::doPutsAndClear);
+    client1.invoke(this::doPutsAndClear);
 
-    client1.invoke(() -> validateClearCountStat());
-    server1.invoke(() -> validateClearCountStat());
+    client1.invoke(this::validateClearCountStat);
+    server1.invoke(this::validateClearCountStat);
   }
 
   /**
@@ -83,20 +82,20 @@ public class RegionClearStatsDistributedTest implements Serializable {
    */
   @Test
   public void testClearStatsWithDiskRegion() {
-    int port = server1.invoke(() -> createServerCacheWithPersistence());
+    int port = server1.invoke(this::createServerCacheWithPersistence);
     client1.invoke(() -> createClientCacheWithPersistence(getServerHostName(), port));
 
-    client1.invoke(() -> doPutsAndClear());
-    client1.invoke(() -> doPutsAndClear());
+    client1.invoke(this::doPutsAndClear);
+    client1.invoke(this::doPutsAndClear);
 
-    client1.invoke(() -> validateClearCountStat());
-    server1.invoke(() -> validateClearCountStat());
+    client1.invoke(this::validateClearCountStat);
+    server1.invoke(this::validateClearCountStat);
   }
 
   private int createCache(DataPolicy dataPolicy) throws IOException {
     cacheRule.createCache();
 
-    AttributesFactory factory = new AttributesFactory();
+    AttributesFactory<String, String> factory = new AttributesFactory<>();
     factory.setScope(Scope.DISTRIBUTED_ACK);
     factory.setDataPolicy(dataPolicy);
 
@@ -129,7 +128,7 @@ public class RegionClearStatsDistributedTest implements Serializable {
             .setMinConnections(1).setReadTimeout(20000).setPingInterval(10000).setRetryAttempts(1)
             .create(getClass().getSimpleName());
 
-    AttributesFactory factory = new AttributesFactory();
+    AttributesFactory<String, String> factory = new AttributesFactory<>();
     factory.setScope(Scope.DISTRIBUTED_ACK);
     factory.setPoolName(pool.getName());
 
@@ -148,7 +147,7 @@ public class RegionClearStatsDistributedTest implements Serializable {
             .setMinConnections(1).setReadTimeout(20000).setPingInterval(10000).setRetryAttempts(1)
             .create(getClass().getSimpleName());
 
-    AttributesFactory factory = new AttributesFactory();
+    AttributesFactory<String, String> factory = new AttributesFactory<>();
     factory.setScope(Scope.DISTRIBUTED_ACK);
     factory.setPoolName(pool.getName());
     factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
@@ -157,7 +156,7 @@ public class RegionClearStatsDistributedTest implements Serializable {
   }
 
   private void doPutsAndClear() {
-    Region region = cacheRule.getCache().getRegion(REGION_NAME);
+    Region<String, String> region = cacheRule.getCache().getRegion(REGION_NAME);
 
     region.put(KEY1, VALUE1);
     region.put(KEY2, VALUE2);
@@ -169,7 +168,7 @@ public class RegionClearStatsDistributedTest implements Serializable {
   }
 
   private void validateClearCountStat() {
-    assertThat(cacheRule.getCache().getCachePerfStats().getRegionClearCount())
+    assertThat(cacheRule.getCache().getCachePerfStats().getClearCount())
         .isEqualTo(EXPECTED_CLEAR_COUNT_STAT_VALUE);
   }
 }
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionClearDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionClearDUnitTest.java
index b871926..64fb284 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionClearDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionClearDUnitTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.internal.cache;
 
+import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_TIME_STATISTICS;
 import static org.apache.geode.internal.Assert.fail;
 import static org.apache.geode.test.dunit.rules.ClusterStartupRule.getCache;
 import static org.apache.geode.test.dunit.rules.ClusterStartupRule.getClientCache;
@@ -40,10 +41,13 @@ import org.apache.geode.cache.RegionFactory;
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.client.ClientRegionShortcut;
 import org.apache.geode.cache.util.CacheWriterAdapter;
+import org.apache.geode.test.dunit.Invoke;
 import org.apache.geode.test.dunit.SerializableCallableIF;
 import org.apache.geode.test.dunit.rules.ClientVM;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties;
 import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.util.internal.GeodeGlossary;
 
 public class PartitionedRegionClearDUnitTest implements Serializable {
   protected static final String REGION_NAME = "testPR";
@@ -60,10 +64,17 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
   @Rule
   public ClusterStartupRule cluster = new ClusterStartupRule(7);
 
+  @Rule
+  public DistributedRestoreSystemProperties distributedRestoreSystemProperties =
+      new DistributedRestoreSystemProperties();
+
   @Before
   public void setUp() throws Exception {
+    Invoke.invokeInEveryVM(
+        () -> System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "enable-time-statistics", "true"));
     locator = cluster.startLocatorVM(0);
     locatorPort = locator.getPort();
+    getProperties().setProperty(ENABLE_TIME_STATISTICS, "true");
     dataStore1 = cluster.startServerVM(1, getProperties(), locatorPort);
     dataStore2 = cluster.startServerVM(2, getProperties(), locatorPort);
     dataStore3 = cluster.startServerVM(3, getProperties(), locatorPort);
@@ -79,11 +90,10 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
   }
 
   protected Properties getProperties() {
-    Properties properties = new Properties();
-    return properties;
+    return new Properties();
   }
 
-  private Region getRegion(boolean isClient) {
+  private <K, V> Region<K, V> getRegion(boolean isClient) {
     if (isClient) {
       return getClientCache().getRegion(REGION_NAME);
     } else {
@@ -96,15 +106,16 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
   }
 
   private void initClientCache() {
-    Region region = getClientCache().createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY)
-        .create(REGION_NAME);
+    Region<Object, Object> region =
+        getClientCache().createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY)
+            .create(REGION_NAME);
     region.registerInterestForAllKeys(InterestResultPolicy.KEYS);
   }
 
   private void initDataStore(boolean withWriter) {
-    RegionFactory factory = getCache().createRegionFactory(getRegionShortCut())
+    RegionFactory<Object, Object> factory = getCache().createRegionFactory(getRegionShortCut())
         .setPartitionAttributes(
-            new PartitionAttributesFactory().setTotalNumBuckets(TOTAL_BUCKET_NUM).create());
+            new PartitionAttributesFactory<>().setTotalNumBuckets(TOTAL_BUCKET_NUM).create());
     if (withWriter) {
       factory.setCacheWriter(new CountingCacheWriter());
     }
@@ -128,10 +139,10 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
         fail("Wrong region type:" + shortcut);
       }
     }
-    RegionFactory factory = getCache().createRegionFactory(shortcut)
+    RegionFactory<Object, Object> factory = getCache().createRegionFactory(shortcut)
         .setPartitionAttributes(
-            new PartitionAttributesFactory().setTotalNumBuckets(10).setLocalMaxMemory(0).create())
-        .setPartitionAttributes(new PartitionAttributesFactory().setTotalNumBuckets(10).create());
+            new PartitionAttributesFactory<>().setTotalNumBuckets(10).setLocalMaxMemory(0).create())
+        .setPartitionAttributes(new PartitionAttributesFactory<>().setTotalNumBuckets(10).create());
     if (withWriter) {
       factory.setCacheWriter(new CountingCacheWriter());
     }
@@ -140,9 +151,9 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     destroysByRegion = new HashMap<>();
   }
 
-  private void feed(boolean isClient) {
-    Region region = getRegion(isClient);
-    IntStream.range(0, NUM_ENTRIES).forEach(i -> region.put(i, "value" + i));
+  private void putRecords(boolean isClient, int numEntries) {
+    Region<Object, Object> region = getRegion(isClient);
+    IntStream.range(0, numEntries).forEach(i -> region.put(i, "value" + i));
   }
 
   private void verifyServerRegionSize(int expectedNum) {
@@ -160,43 +171,28 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
 
       for (BucketRegion bucket : region.getDataStore().getAllLocalBucketRegions()) {
         if (clearCount == 0) {
-          clearCount = bucket.getCachePerfStats().getBucketClearCount();
+          clearCount = bucket.getPartitionedRegion().getPrStats().getBucketClearCount();
         }
-        assertThat(bucket.getCachePerfStats().getBucketClearCount()).isEqualTo(bucketCount);
+        assertThat(bucket.getPartitionedRegion().getPrStats().getBucketClearCount())
+            .isEqualTo(bucketCount);
       }
 
-      CachePerfStats stats = region.getRegionCachePerfStats();
-
-      assertThat(stats.getRegionClearCount()).isEqualTo(1);
-      assertThat(stats.getPartitionedRegionClearLocalDuration())
-          .isGreaterThan(0);
+      CachePerfStats stats = region.getCachePerfStats();
       if (isCoordinator) {
-        assertThat(stats.getPartitionedRegionClearTotalDuration())
-            .isGreaterThan(0);
-      } else {
-        assertThat(stats.getPartitionedRegionClearTotalDuration())
-            .isEqualTo(0);
+        assertThat(stats.getClearCount()).isEqualTo(1);
       }
     });
   }
 
   private void verifyClientRegionSize(int expectedNum) {
     client1.invoke(() -> verifyRegionSize(true, expectedNum));
-    // TODO: notify register clients
-    // client2.invoke(()->verifyRegionSize(true, expectedNum));
   }
 
-  SerializableCallableIF<Integer> getWriterClears = () -> {
-    int clears =
-        clearsByRegion.get(REGION_NAME) == null ? 0 : clearsByRegion.get(REGION_NAME).get();
-    return clears;
-  };
+  SerializableCallableIF<Integer> getWriterClears =
+      () -> clearsByRegion.get(REGION_NAME) == null ? 0 : clearsByRegion.get(REGION_NAME).get();
 
-  SerializableCallableIF<Integer> getWriterDestroys = () -> {
-    int destroys =
-        destroysByRegion.get(REGION_NAME) == null ? 0 : destroysByRegion.get(REGION_NAME).get();
-    return destroys;
-  };
+  SerializableCallableIF<Integer> getWriterDestroys =
+      () -> destroysByRegion.get(REGION_NAME) == null ? 0 : destroysByRegion.get(REGION_NAME).get();
 
   SerializableCallableIF<Integer> getBucketRegionWriterClears = () -> {
     int clears = 0;
@@ -225,11 +221,11 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     accessor.invoke(() -> initAccessor(accessorWithWriter));
     // make sure only datastore3 has cacheWriter
     dataStore1.invoke(() -> {
-      Region region = getRegion(false);
+      Region<Object, Object> region = getRegion(false);
       region.getAttributesMutator().setCacheWriter(null);
     });
     dataStore2.invoke(() -> {
-      Region region = getRegion(false);
+      Region<Object, Object> region = getRegion(false);
       region.getAttributesMutator().setCacheWriter(null);
     });
   }
@@ -240,14 +236,14 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     client1.invoke(this::initClientCache);
     client2.invoke(this::initClientCache);
 
-    accessor.invoke(() -> feed(false));
+    accessor.invoke(() -> putRecords(false, NUM_ENTRIES));
     verifyServerRegionSize(NUM_ENTRIES);
     dataStore3.invoke(() -> getRegion(false).clear());
     verifyServerRegionSize(0);
 
     // do the region destroy to compare that the same callbacks will be triggered
     dataStore3.invoke(() -> {
-      Region region = getRegion(false);
+      Region<Object, Object> region = getRegion(false);
       region.destroyRegion();
     });
 
@@ -271,14 +267,14 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     client1.invoke(this::initClientCache);
     client2.invoke(this::initClientCache);
 
-    accessor.invoke(() -> feed(false));
+    accessor.invoke(() -> putRecords(false, NUM_ENTRIES));
     verifyServerRegionSize(NUM_ENTRIES);
     dataStore1.invoke(() -> getRegion(false).clear());
     verifyServerRegionSize(0);
 
     // do the region destroy to compare that the same callbacks will be triggered
     dataStore1.invoke(() -> {
-      Region region = getRegion(false);
+      Region<Object, Object> region = getRegion(false);
       region.destroyRegion();
     });
 
@@ -302,14 +298,14 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     client1.invoke(this::initClientCache);
     client2.invoke(this::initClientCache);
 
-    accessor.invoke(() -> feed(false));
+    accessor.invoke(() -> putRecords(false, NUM_ENTRIES));
     verifyServerRegionSize(NUM_ENTRIES);
     accessor.invoke(() -> getRegion(false).clear());
     verifyServerRegionSize(0);
 
     // do the region destroy to compare that the same callbacks will be triggered
     accessor.invoke(() -> {
-      Region region = getRegion(false);
+      Region<Object, Object> region = getRegion(false);
       region.destroyRegion();
     });
 
@@ -333,14 +329,14 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     client1.invoke(this::initClientCache);
     client2.invoke(this::initClientCache);
 
-    accessor.invoke(() -> feed(false));
+    accessor.invoke(() -> putRecords(false, NUM_ENTRIES));
     verifyServerRegionSize(NUM_ENTRIES);
     accessor.invoke(() -> getRegion(false).clear());
     verifyServerRegionSize(0);
 
     // do the region destroy to compare that the same callbacks will be triggered
     accessor.invoke(() -> {
-      Region region = getRegion(false);
+      Region<Object, Object> region = getRegion(false);
       region.destroyRegion();
     });
 
@@ -369,12 +365,12 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
       PartitionedRegion region = (PartitionedRegion) getRegion(false);
 
       for (BucketRegion bucket : region.getDataStore().getAllLocalBucketRegions()) {
-        long clearCount = bucket.getCachePerfStats().getRegionClearCount();
+        long clearCount = bucket.getCachePerfStats().getClearCount();
         assertThat(clearCount).isEqualTo(0);
       }
     });
 
-    accessor.invoke(() -> feed(false));
+    accessor.invoke(() -> putRecords(false, NUM_ENTRIES));
     verifyServerRegionSize(NUM_ENTRIES);
     dataStore1.invoke(() -> getRegion(false).clear());
     verifyServerRegionSize(0);
@@ -388,11 +384,7 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     // The accessor shouldn't increment the region clear count
     accessor.invoke(() -> {
       PartitionedRegion region = (PartitionedRegion) getRegion(false);
-
-      assertThat(region.getRegionCachePerfStats()).isNull();
-      assertThat(region.getCachePerfStats().getRegionClearCount()).isEqualTo(0);
-      assertThat(region.getCachePerfStats().getPartitionedRegionClearLocalDuration()).isEqualTo(0);
-      assertThat(region.getCachePerfStats().getPartitionedRegionClearTotalDuration()).isEqualTo(0);
+      assertThat(region.getCachePerfStats().getClearCount()).isZero();
     });
   }
 
@@ -402,7 +394,7 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     client1.invoke(this::initClientCache);
     client2.invoke(this::initClientCache);
 
-    client1.invoke(() -> feed(true));
+    client1.invoke(() -> putRecords(true, NUM_ENTRIES));
     verifyClientRegionSize(NUM_ENTRIES);
     verifyServerRegionSize(NUM_ENTRIES);
 
@@ -412,7 +404,7 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
 
     // do the region destroy to compare that the same callbacks will be triggered
     client1.invoke(() -> {
-      Region region = getRegion(true);
+      Region<Object, Object> region = getRegion(true);
       region.destroyRegion();
     });
 
@@ -430,13 +422,38 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
         .isEqualTo(0);
   }
 
+  @Test
+  public void testClearCount() {
+    configureServers(false, true);
+    client1.invoke(this::initClientCache);
+    client2.invoke(this::initClientCache);
+
+    accessor.invoke(() -> putRecords(false, NUM_ENTRIES));
+    verifyServerRegionSize(NUM_ENTRIES);
+    dataStore1.invoke(() -> {
+      PartitionedRegion partitionedRegion = (PartitionedRegion) getRegion(false);
+      assertThat(partitionedRegion.getCachePerfStats().getClearCount()).isEqualTo(0L);
+    });
+    dataStore1.invoke(() -> getRegion(false).clear());
+    verifyServerRegionSize(0);
+    dataStore1.invoke(() -> {
+      PartitionedRegion partitionedRegion = (PartitionedRegion) getRegion(false);
+      assertThat(partitionedRegion.getCachePerfStats().getClearCount()).isEqualTo(1L);
+    });
+
+    verifyDatastoreStats(dataStore1, true);
+    verifyDatastoreStats(dataStore2, false);
+    verifyDatastoreStats(dataStore3, false);
+  }
+
+
   public static HashMap<String, AtomicInteger> clearsByRegion = new HashMap<>();
   public static HashMap<String, AtomicInteger> destroysByRegion = new HashMap<>();
 
-  private static class CountingCacheWriter extends CacheWriterAdapter {
+  private static class CountingCacheWriter extends CacheWriterAdapter<Object, Object> {
     @Override
-    public void beforeRegionClear(RegionEvent event) throws CacheWriterException {
-      Region region = event.getRegion();
+    public void beforeRegionClear(RegionEvent<Object, Object> event) throws CacheWriterException {
+      Region<Object, Object> region = event.getRegion();
       AtomicInteger clears = clearsByRegion.get(region.getName());
       if (clears == null) {
         clears = new AtomicInteger(1);
@@ -449,8 +466,8 @@ public class PartitionedRegionClearDUnitTest implements Serializable {
     }
 
     @Override
-    public void beforeRegionDestroy(RegionEvent event) throws CacheWriterException {
-      Region region = event.getRegion();
+    public void beforeRegionDestroy(RegionEvent<Object, Object> event) throws CacheWriterException {
+      Region<Object, Object> region = event.getRegion();
       AtomicInteger destroys = destroysByRegion.get(region.getName());
       if (destroys == null) {
         destroys = new AtomicInteger(1);
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionLocalMaxMemoryOffHeapDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionLocalMaxMemoryOffHeapDUnitTest.java
index 9e11092..00a9b34 100755
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionLocalMaxMemoryOffHeapDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/PartitionedRegionLocalMaxMemoryOffHeapDUnitTest.java
@@ -61,7 +61,7 @@ public class PartitionedRegionLocalMaxMemoryOffHeapDUnitTest
       long recoveryDelay, EvictionAttributes evictionAttributes) {
     RegionAttributes<?, ?> regionAttributes = PartitionedRegionTestHelper.createRegionAttrsForPR(
         redundancy, localMaxMemory, recoveryDelay, evictionAttributes, null);
-    AttributesFactory attributesFactory = new AttributesFactory(regionAttributes);
+    AttributesFactory<?, ?> attributesFactory = new AttributesFactory<>(regionAttributes);
     attributesFactory.setOffHeap(true);
     return attributesFactory.create();
   }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryCacheClosedJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryCacheClosedJUnitTest.java
index b0758fd..4821a99 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryCacheClosedJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryCacheClosedJUnitTest.java
@@ -85,7 +85,7 @@ public class PRQueryCacheClosedJUnitTest {
    *
    */
   @Test
-  public void testQueryOnSingleDataStoreWithCacheClose() throws Exception {
+  public void testQueryOnSingleDataStoreWithCacheClose() {
 
     logger.info(
         "PRQueryRegionDestroyedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: Test Started  ");
@@ -93,12 +93,13 @@ public class PRQueryCacheClosedJUnitTest {
     logger.info(
         "PRQueryRegionDestroyedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: creating PR Region ");
 
-    final Region region =
+    final Region<Integer, PortfolioData> region =
         PartitionedRegionTestHelper.createPartitionedRegion(regionName, localMaxMemory, redundancy);
 
-    final Region localRegion = PartitionedRegionTestHelper.createLocalRegion(localRegionName);
+    final Region<Integer, PortfolioData> localRegion =
+        PartitionedRegionTestHelper.createLocalRegion(localRegionName);
 
-    final StringBuffer errorBuf = new StringBuffer("");
+    final StringBuffer errorBuf = new StringBuffer();
 
     PortfolioData[] portfolios = new PortfolioData[dataSize];
 
@@ -121,83 +122,71 @@ public class PRQueryCacheClosedJUnitTest {
       logger.info(
           "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: Creating a Thread which will fire queries on the datastore");
 
-      Thread t1 = new Thread(new Runnable() {
-        @Override
-        public void run() {
-          final String expectedCacheClosedException = CacheClosedException.class.getName();
+      Thread t1 = new Thread(() -> {
+        final String expectedCacheClosedException = CacheClosedException.class.getName();
 
-          logger.info("<ExpectedException action=add>" + expectedCacheClosedException
-              + "</ExpectedException>");
+        logger.info("<ExpectedException action=add>" + expectedCacheClosedException
+            + "</ExpectedException>");
 
-          for (int i = 0; i < queryString.length; i++) {
+        for (String s : queryString) {
 
-            try {
-
-              SelectResults resSetPR = region.query(queryString[i]);
-
-              SelectResults resSetLocal = localRegion.query(queryString[i]);
-
-              String failureString =
-                  PartitionedRegionTestHelper.compareResultSets(resSetPR, resSetLocal);
-              Thread.sleep(delayQuery);
-              if (failureString != null) {
-                errorBuf.append(failureString);
-                throw (new Exception(failureString));
-
-              }
+          try {
 
-            } catch (InterruptedException ie) {
-              fail("interrupted");
+            SelectResults<PortfolioData> resSetPR = region.query(s);
 
-            }
+            SelectResults<PortfolioData> resSetLocal = localRegion.query(s);
 
-            catch (CancelException cce) {
-              logger.info(
-                  "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: CancelException as Expected "
-                      + cce);
+            String failureString =
+                PartitionedRegionTestHelper.compareResultSets(resSetPR, resSetLocal);
+            Thread.sleep(delayQuery);
+            if (failureString != null) {
+              errorBuf.append(failureString);
+              throw (new Exception(failureString));
 
             }
-            // it's also possible to get a RegionNotFoundException
-            catch (RegionNotFoundException rnfe) {
-              logger.info(
-                  "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: RegionNotFoundException as Expected "
-                      + rnfe);
-            }
-
 
-            catch (Exception qe) {
-              logger.info(
-                  "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: Unexpected Exception "
-                      + qe);
+          } catch (InterruptedException ie) {
+            fail("interrupted");
 
-              encounteredException = true;
-              StringWriter sw = new StringWriter();
-              qe.printStackTrace(new PrintWriter(sw, true));
-              errorBuf.append(sw);
+          } catch (CancelException cce) {
+            logger.info(
+                "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: CancelException as Expected "
+                    + cce);
 
-            }
+          }
+          // it's also possible to get a RegionNotFoundException
+          catch (RegionNotFoundException rnfe) {
+            logger.info(
+                "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: RegionNotFoundException as Expected "
+                    + rnfe);
+          } catch (Exception qe) {
+            logger.info(
+                "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: Unexpected Exception "
+                    + qe);
+
+            encounteredException = true;
+            StringWriter sw = new StringWriter();
+            qe.printStackTrace(new PrintWriter(sw, true));
+            errorBuf.append(sw);
 
           }
-          logger.info("<ExpectedException action=remove>" + expectedCacheClosedException
-              + "</ExpectedException>");
 
         }
+        logger.info("<ExpectedException action=remove>" + expectedCacheClosedException
+            + "</ExpectedException>");
+
       });
       logger.info(
           "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: Creating a Thread which will call cache.close() on the datastore ");
 
-      Thread t2 = new Thread(new Runnable() {
-        @Override
-        public void run() {
-          PartitionedRegionTestHelper.closeCache();
-          try {
-            Thread.sleep(delayCC);
-          } catch (InterruptedException ie) {
-            fail("interrupted");
-          }
-          PartitionedRegionTestHelper.createCache();
-
+      Thread t2 = new Thread(() -> {
+        PartitionedRegionTestHelper.closeCache();
+        try {
+          Thread.sleep(delayCC);
+        } catch (InterruptedException ie) {
+          fail("interrupted");
         }
+        PartitionedRegionTestHelper.createCache();
 
       });
 
@@ -224,7 +213,6 @@ public class PRQueryCacheClosedJUnitTest {
       fail(
           "PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: Test failed because of exception "
               + e);
-
     }
 
     logger.info("PRQueryCacheClosedJUnitTest#testQueryOnSingleDataStoreWithCacheClose: Test Ended");
@@ -235,10 +223,10 @@ public class PRQueryCacheClosedJUnitTest {
    * Populates the region with the Objects stores in the data Object array.
    *
    */
-  private void populateData(Region region, Object[] data) {
+  private void populateData(Region<Integer, PortfolioData> region, PortfolioData[] data) {
     logger.info("PRQueryCacheClosedJUnitTest#populateData: Populating Data in the PR Region ");
     for (int j = 0; j < data.length; j++) {
-      region.put(new Integer(j), data[j]);
+      region.put(j, data[j]);
     }
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryJUnitTest.java
index 97e96fb..00c78fd 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryJUnitTest.java
@@ -25,16 +25,15 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.LogWriter;
-import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.cache.query.CacheUtils;
 import org.apache.geode.cache.query.Query;
 import org.apache.geode.cache.query.QueryService;
 import org.apache.geode.cache.query.SelectResults;
 import org.apache.geode.cache.query.data.PortfolioData;
 import org.apache.geode.internal.Assert;
+import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.PartitionedRegionTestHelper;
+import org.apache.geode.pdx.PdxInstance;
 import org.apache.geode.test.junit.categories.OQLQueryTest;
 
 /**
@@ -44,15 +43,16 @@ import org.apache.geode.test.junit.categories.OQLQueryTest;
  */
 @Category({OQLQueryTest.class})
 public class PRQueryJUnitTest {
-  String regionName = "portfolios";
+  final String regionName = "portfolios";
 
   LogWriter logger = null;
 
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
     if (logger == null) {
       logger = PartitionedRegionTestHelper.getLogger();
     }
+
   }
 
   /**
@@ -63,7 +63,8 @@ public class PRQueryJUnitTest {
    */
   @Test
   public void testQueryOnSingleDataStore() throws Exception {
-    Region region = PartitionedRegionTestHelper.createPartitionedRegion(regionName, "100", 0);
+    Region<Integer, Object> region =
+        PartitionedRegionTestHelper.createPartitionedRegion(regionName, "100", 0);
     PortfolioData[] portfolios = new PortfolioData[100];
     for (int j = 0; j < 100; j++) {
       portfolios[j] = new PortfolioData(j);
@@ -72,7 +73,7 @@ public class PRQueryJUnitTest {
       populateData(region, portfolios);
 
       String queryString = "ID < 5";
-      SelectResults resSet = region.query(queryString);
+      SelectResults<PortfolioData> resSet = region.query(queryString);
       Assert.assertTrue(resSet.size() == 5);
 
       queryString = "ID > 5 and ID <=15";
@@ -85,24 +86,26 @@ public class PRQueryJUnitTest {
 
   @Test
   public void testQueryWithNullProjectionValue() throws Exception {
-    Region region = PartitionedRegionTestHelper.createPartitionedRegion(regionName, "100", 0);
+    Region<String, HashMap<String, String>> region =
+        PartitionedRegionTestHelper.createPartitionedRegion(regionName, "100", 0);
     int size = 10;
-    HashMap value = null;
+    HashMap<String, String> value;
     for (int j = 0; j < size; j++) {
-      value = new HashMap();
+      value = new HashMap<>();
       value.put("account" + j, "account" + j);
       region.put("" + j, value);
     }
 
     String queryString = "Select p.get('account') from " + SEPARATOR + region.getName() + " p ";
-    Query query = region.getCache().getQueryService().newQuery(queryString);
-    SelectResults sr = (SelectResults) query.execute();
+    Query query = PartitionedRegionTestHelper.getCache().getQueryService().newQuery(queryString);
+    SelectResults<HashMap<String, String>> sr =
+        (SelectResults<HashMap<String, String>>) query.execute();
     Assert.assertTrue(sr.size() == size);
 
     try {
       queryString = "Select p.get('acc') from " + SEPARATOR + region.getName() + " p ";
-      query = region.getCache().getQueryService().newQuery(queryString);
-      sr = (SelectResults) query.execute();
+      query = PartitionedRegionTestHelper.getCache().getQueryService().newQuery(queryString);
+      sr = (SelectResults<HashMap<String, String>>) query.execute();
       Assert.assertTrue(sr.size() == 10);
       for (Object r : sr.asList()) {
         if (r != null) {
@@ -116,10 +119,11 @@ public class PRQueryJUnitTest {
 
   @Test
   public void testOrderByQuery() throws Exception {
-    Region region = PartitionedRegionTestHelper.createPartitionedRegion(regionName, "100", 0);
+    Region<Integer, Object> region =
+        PartitionedRegionTestHelper.createPartitionedRegion(regionName, "100", 0);
     String[] values = new String[100];
     for (int j = 0; j < 100; j++) {
-      values[j] = new String("" + j);
+      values[j] = "" + j;
     }
 
     try {
@@ -127,7 +131,7 @@ public class PRQueryJUnitTest {
 
       String queryString =
           "Select distinct p from " + SEPARATOR + region.getName() + " p order by p";
-      Query query = region.getCache().getQueryService().newQuery(queryString);
+      Query query = PartitionedRegionTestHelper.getCache().getQueryService().newQuery(queryString);
       SelectResults sr = (SelectResults) query.execute();
 
       Assert.assertTrue(sr.size() == 100);
@@ -138,9 +142,12 @@ public class PRQueryJUnitTest {
 
   @Test
   public void testNestedPRQuery() throws Exception {
-    Cache cache = CacheUtils.getCache();
-    QueryService queryService = CacheUtils.getCache().getQueryService();
-    Region region = cache.createRegionFactory(RegionShortcut.PARTITION).create("TEST_REGION");
+
+    Region<String, PdxInstance> region =
+        PartitionedRegionTestHelper.createPartitionedRegion("TEST_REGION");
+
+    InternalCache cache = PartitionedRegionTestHelper.getCache();
+    QueryService queryService = cache.getQueryService();
     Query query = queryService.newQuery(
         "SELECT distinct COUNT(*) FROM (SELECT DISTINCT tr.id, tr.domain FROM " + SEPARATOR
             + "TEST_REGION tr)");
@@ -178,9 +185,9 @@ public class PRQueryJUnitTest {
    * Populates the region with the Objects stores in the data Object array.
    *
    */
-  private void populateData(Region region, Object[] data) {
+  private void populateData(Region<Integer, Object> region, Object[] data) {
     for (int j = 0; j < data.length; j++) {
-      region.put(new Integer(j), data[j]);
+      region.put(j, data[j]);
     }
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionClosedJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionClosedJUnitTest.java
index 476e49f..090aa39 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionClosedJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionClosedJUnitTest.java
@@ -55,8 +55,6 @@ public class PRQueryRegionClosedJUnitTest {
   boolean encounteredException = false;
   static final int delayQuery = 1000;
 
-
-
   @Before
   public void setUp() throws Exception {
     if (logger == null) {
@@ -75,18 +73,17 @@ public class PRQueryRegionClosedJUnitTest {
    *
    */
   @Test
-  public void testQueryingWithRegionClose() throws Exception {
+  public void testQueryingWithRegionClose() {
 
     logger.info("PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: Test Started  ");
 
     logger.info("PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: creating PR Region ");
 
-    final Region region =
+    final Region<Integer, PortfolioData> region =
         PartitionedRegionTestHelper.createPartitionedRegion(regionName, localMaxMemory, redundancy);
 
-    final Region localRegion = PartitionedRegionTestHelper.createLocalRegion(localRegionName);
-
-    final StringBuffer errorBuf = new StringBuffer("");
+    final Region<Integer, PortfolioData> localRegion =
+        PartitionedRegionTestHelper.createLocalRegion(localRegionName);
 
     PortfolioData[] portfolios = new PortfolioData[100];
 
@@ -109,85 +106,69 @@ public class PRQueryRegionClosedJUnitTest {
       logger.info(
           "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: Creating a Thread which will fire queries on the datastore");
 
-      Thread t1 = new Thread(new Runnable() {
-        @Override
-        public void run() {
-          final String expectedRegionDestroyedException = RegionDestroyedException.class.getName();
-
-          logger.info("<ExpectedException action=add>" + expectedRegionDestroyedException
-              + "</ExpectedException>");
-
-          for (int i = 0; i < queryString.length; i++) {
-
-            try {
-
-              SelectResults resSetPR = region.query(queryString[i]);
-              SelectResults resSetLocal = localRegion.query(queryString[i]);
-              String failureString =
-                  PartitionedRegionTestHelper.compareResultSets(resSetPR, resSetLocal);
-              Thread.sleep(delayQuery);
-              if (failureString != null) {
-                errorBuf.append(failureString);
-                throw (new Exception(failureString));
-
-              }
-            } catch (InterruptedException ie) {
-              fail("interrupted");
-            }
-
-            catch (RegionDestroyedException rde) {
-              logger.info(
-                  "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: RegionDestroyedException as Expected "
-                      + rde);
-
-            } catch (RegionNotFoundException rnfe) {
-              logger.info(
-                  "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: RegionNotFoundException as Expected "
-                      + rnfe);
-
-            }
+      Thread t1 = new Thread(() -> {
+        final String expectedRegionDestroyedException = RegionDestroyedException.class.getName();
 
-            catch (QueryInvocationTargetException qite) {
-              logger.info(
-                  "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: QueryInvocationTargetException as Expected "
-                      + qite);
+        logger.info("<ExpectedException action=add>" + expectedRegionDestroyedException
+            + "</ExpectedException>");
 
-            } catch (Exception qe) {
-              logger.info(
-                  "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: Unexpected Exception "
-                      + qe);
+        for (String s : queryString) {
 
-              encounteredException = true;
-              StringWriter sw = new StringWriter();
-              qe.printStackTrace(new PrintWriter(sw));
-              errorBuf.append(sw);
+          try {
 
+            SelectResults<PortfolioData> resSetPR = region.query(s);
+            SelectResults<PortfolioData> resSetLocal = localRegion.query(s);
+            String failureString =
+                PartitionedRegionTestHelper.compareResultSets(resSetPR, resSetLocal);
+            Thread.sleep(delayQuery);
+            if (failureString != null) {
+              throw (new Exception(failureString));
             }
-
+          } catch (InterruptedException ie) {
+            fail("interrupted");
+          } catch (RegionDestroyedException rde) {
+            logger.info(
+                "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: RegionDestroyedException as Expected "
+                    + rde);
+
+          } catch (RegionNotFoundException rnfe) {
+            logger.info(
+                "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: RegionNotFoundException as Expected "
+                    + rnfe);
+
+          } catch (QueryInvocationTargetException qite) {
+            logger.info(
+                "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: QueryInvocationTargetException as Expected "
+                    + qite);
+
+          } catch (Exception qe) {
+            logger.info(
+                "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: Unexpected Exception "
+                    + qe);
+
+            encounteredException = true;
+            StringWriter sw = new StringWriter();
+            qe.printStackTrace(new PrintWriter(sw));
           }
-          logger.info("<ExpectedException action=remove>" + expectedRegionDestroyedException
-              + "</ExpectedException>");
-
         }
+        logger.info("<ExpectedException action=remove>" + expectedRegionDestroyedException
+            + "</ExpectedException>");
+
       });
       logger.info(
           "PRQueryRegionClosedJUnitTest#testQueryingWithRegionClose: Creating a Thread which will call Region.destroyRegion() on the datastore ");
 
-      Thread t2 = new Thread(new Runnable() {
-        @Override
-        public void run() {
-          try {
-            Thread.sleep(2500);
-          } catch (InterruptedException ie) {
-            fail("interrupted");
-          }
-          region.close();
-
-          logger.info(
-              "PROperationWithQueryDUnitTest#getCacheSerializableRunnableForRegionClose: Region Closed on VM ");
+      Thread t2 = new Thread(() -> {
+        try {
+          Thread.sleep(2500);
+        } catch (InterruptedException ie) {
+          fail("interrupted");
+        }
+        region.close();
 
+        logger.info(
+            "PROperationWithQueryDUnitTest#getCacheSerializableRunnableForRegionClose: Region Closed on VM ");
 
-        }
 
       });
 
@@ -226,10 +207,10 @@ public class PRQueryRegionClosedJUnitTest {
    * Populates the region with the Objects stores in the data Object array.
    *
    */
-  private void populateData(Region region, Object[] data) {
+  private void populateData(Region<Integer, PortfolioData> region, PortfolioData[] data) {
     logger.info("PRQueryRegionClosedJUnitTest#populateData: Populating Data in the PR Region ");
     for (int j = 0; j < data.length; j++) {
-      region.put(new Integer(j), data[j]);
+      region.put(j, data[j]);
     }
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionDestroyedJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionDestroyedJUnitTest.java
index c07c0e5..45bbc66 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionDestroyedJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRQueryRegionDestroyedJUnitTest.java
@@ -83,10 +83,11 @@ public class PRQueryRegionDestroyedJUnitTest {
 
     logger.info("PRQueryRegionDestroyedJUnitTest#testQueryOnSingleDataStore: creating PR Region ");
 
-    final Region region =
+    final Region<Integer, PortfolioData> region =
         PartitionedRegionTestHelper.createPartitionedRegion(regionName, localMaxMemory, redundancy);
 
-    final Region localRegion = PartitionedRegionTestHelper.createLocalRegion(localRegionName);
+    final Region<Integer, PortfolioData> localRegion =
+        PartitionedRegionTestHelper.createLocalRegion(localRegionName);
 
     final StringBuffer errorBuf = new StringBuffer("");
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ColocatedPRJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ColocatedPRJUnitTest.java
index edf4ce9..871249e 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ColocatedPRJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ColocatedPRJUnitTest.java
@@ -31,13 +31,13 @@ public class ColocatedPRJUnitTest {
   @Test
   public void destroyColocatedPRCheckForLeak() {
     PartitionedRegion parent =
-        (PartitionedRegion) PartitionedRegionTestHelper.createPartionedRegion("PARENT");
+        (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion("PARENT");
     List<PartitionedRegion> colocatedList = parent.getColocatedByList();
     assertEquals(0, colocatedList.size());
     PartitionAttributes PRatts =
         new PartitionAttributesFactory().setColocatedWith(SEPARATOR + "PARENT").create();
     PartitionedRegion child =
-        (PartitionedRegion) PartitionedRegionTestHelper.createPartionedRegion("CHILD", PRatts);
+        (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion("CHILD", PRatts);
     assertTrue(colocatedList.contains(child));
     child.destroyRegion();
     assertFalse(colocatedList.contains(child));
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionCreationJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionCreationJUnitTest.java
index b0aa84c..ff3306f 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionCreationJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionCreationJUnitTest.java
@@ -275,7 +275,7 @@ public class PartitionedRegionCreationJUnitTest {
   @Test
   public void testPartionedRegionInitialization() throws RegionExistsException {
     String PRName = "testpartionedRegionInitialization";
-    PartitionedRegionTestHelper.createPartionedRegion(PRName);
+    PartitionedRegionTestHelper.createPartitionedRegion(PRName);
 
     Region root = (PartitionedRegionTestHelper
         .getExistingRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME));
@@ -373,7 +373,7 @@ public class PartitionedRegionCreationJUnitTest {
     public void run() {
       String prName = "PartitionedRegionCreationJUnitTest_" + getPRNumber();
       try {
-        Region region = PartitionedRegionTestHelper.createPartionedRegion(prName);
+        Region region = PartitionedRegionTestHelper.createPartitionedRegion(prName);
         PRRegionList.add(region);
         updatePRCreate();
       } catch (RegionExistsException rex) {
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionStatsJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionStatsJUnitTest.java
index 46b7d64..24b3023 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionStatsJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionStatsJUnitTest.java
@@ -15,14 +15,23 @@
 
 package org.apache.geode.internal.cache;
 
-import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.apache.geode.internal.cache.PartitionedRegionStats.bucketClearsId;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.Random;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.IntStream;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.logging.log4j.Logger;
@@ -35,10 +44,12 @@ import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.DataPolicy;
 import org.apache.geode.cache.EvictionAction;
 import org.apache.geode.cache.EvictionAttributes;
+import org.apache.geode.cache.Operation;
 import org.apache.geode.cache.PartitionAttributesFactory;
 import org.apache.geode.cache.PartitionedRegionStorageException;
 import org.apache.geode.cache.RegionExistsException;
 import org.apache.geode.cache.RegionFactory;
+import org.apache.geode.internal.statistics.StatisticsClock;
 import org.apache.geode.logging.internal.log4j.api.LogService;
 
 /**
@@ -48,6 +59,7 @@ import org.apache.geode.logging.internal.log4j.api.LogService;
  */
 public class PartitionedRegionStatsJUnitTest {
   private static final File DISK_DIR = new File("PRStatsTest");
+  public static final int NUMBER_OF_BUCKETS = 13;
   Logger logger = null;
 
   @Before
@@ -61,12 +73,10 @@ public class PartitionedRegionStatsJUnitTest {
     FileUtils.deleteDirectory(DISK_DIR);
   }
 
-  private PartitionedRegion createPR(String name, int lmax) {
+  private PartitionedRegion createPRWithCache(String name, int lmax, Cache cache) {
     PartitionAttributesFactory<Object, Object> paf = new PartitionAttributesFactory<>();
-    paf.setLocalMaxMemory(lmax).setRedundantCopies(0).setTotalNumBuckets(13); // set low to
-                                                                              // reduce
-                                                                              // logging
-    Cache cache = PartitionedRegionTestHelper.createCache();
+    // set low to reduce logging
+    paf.setLocalMaxMemory(lmax).setRedundantCopies(0).setTotalNumBuckets(NUMBER_OF_BUCKETS);
     PartitionedRegion pr;
     try {
       RegionFactory<Object, Object> regionFactory = cache.createRegionFactory();
@@ -78,13 +88,21 @@ public class PartitionedRegionStatsJUnitTest {
     return pr;
   }
 
+  private PartitionedRegion createPR(String name, int lmax) {
+    PartitionAttributesFactory<Object, Object> paf = new PartitionAttributesFactory<>();
+    // set low to reduce logging
+    paf.setLocalMaxMemory(lmax).setRedundantCopies(0).setTotalNumBuckets(NUMBER_OF_BUCKETS);
+
+    Cache cache = PartitionedRegionTestHelper.createCache();
+    return createPRWithCache(name, lmax, cache);
+  }
+
   private PartitionedRegion createPRWithEviction(String name, int lmax,
       boolean diskSync,
       boolean persistent) {
     PartitionAttributesFactory<Object, Object> paf = new PartitionAttributesFactory<>();
-    paf.setLocalMaxMemory(lmax).setRedundantCopies(0).setTotalNumBuckets(13); // set low to
-                                                                              // reduce
-                                                                              // logging
+    paf.setLocalMaxMemory(lmax).setRedundantCopies(0).setTotalNumBuckets(NUMBER_OF_BUCKETS);
+
     Cache cache = PartitionedRegionTestHelper.createCache();
     RegionFactory<Object, Object> regionFactory = cache.createRegionFactory();
     regionFactory.setPartitionAttributes(paf.create());
@@ -485,4 +503,166 @@ public class PartitionedRegionStatsJUnitTest {
 
     return bytes;
   }
+
+  @Test
+  public void incBucketClearCountIncrementsClears() {
+    String regionName = "testStats";
+    int localMaxMemory = 100;
+    PartitionedRegion pr = createPR(regionName + 1, localMaxMemory);
+
+    final long startTime = pr.getPrStats().startBucketClear();
+    pr.getPrStats().endBucketClear(startTime);
+
+    assertThat(pr.getPrStats().getStats().getLong(bucketClearsId)).isEqualTo(1L);
+    assertThat(pr.getCachePerfStats().getClearCount()).isEqualTo(0L);
+  }
+
+  @Test
+  public void bucketClearsWrapsFromMaxLongToNegativeValue() {
+    String regionName = "testStats";
+    int localMaxMemory = 100;
+    PartitionedRegion pr = createPR(regionName + 1, localMaxMemory);
+    PartitionedRegionStats partitionedRegionStats = pr.getPrStats();
+    partitionedRegionStats.getStats().incLong(bucketClearsId, Long.MAX_VALUE);
+
+    final long startTime = 1L;
+    partitionedRegionStats.endBucketClear(startTime);
+    assertThat(partitionedRegionStats.getBucketClearCount()).isNegative();
+  }
+
+  @Test
+  public void testPartitionedRegionClearStats() {
+    String regionName = "testStats";
+    int localMaxMemory = 100;
+    PartitionedRegion pr = createPR(regionName + 1, localMaxMemory);
+
+    final int bucketMax = pr.getTotalNumberOfBuckets();
+    for (long i = 0L; i < 10000; i++) {
+      try {
+        pr.put(i, i);
+      } catch (PartitionedRegionStorageException ex) {
+        this.logger.warn(ex);
+      }
+    }
+
+    assertThat(pr.getPrStats().getTotalBucketCount()).isEqualTo(bucketMax);
+    assertThat(pr.size()).isEqualTo(10000);
+    pr.clear();
+    assertThat(pr.size()).isEqualTo(0);
+    assertThat(pr.getPrStats().getStats().getLong(bucketClearsId)).isEqualTo(bucketMax);
+  }
+
+  @Test
+  public void testBasicPartitionedRegionClearTimeStat() {
+    String regionName = "testStats";
+    int localMaxMemory = 100;
+    PartitionedRegion pr = createPR(regionName + 1, localMaxMemory);
+    assertThat(pr.getPrStats().getBucketClearTime()).isEqualTo(0L);
+
+    long startTime = pr.getPrStats().startBucketClear();
+    startTime -= 137L;
+    pr.getPrStats().endBucketClear(startTime);
+    assertThat(pr.getPrStats().getBucketClearTime()).isGreaterThanOrEqualTo(137L);
+  }
+
+  private void putRecords(PartitionedRegion pr) {
+    IntStream.range(0, 1000).forEach(i -> pr.put(i, i));
+  }
+
+
+  @Test
+  public void testFullPartitionedRegionClearTimeStat() {
+    String regionName = "testStats";
+    final int localMaxMemory = 700;
+    final int LOTS_OF_RECORDS = 1000;
+    AtomicLong fakeTime = new AtomicLong(System.nanoTime());
+
+    // If one optimizes the code and converts to a lambda spy will fail
+    @SuppressWarnings({"Anonymous2MethodRef", "Convert2Lambda"})
+    StatisticsClock statisticsClock = spy(new StatisticsClock() {
+      @Override
+      public long getTime() {
+        return fakeTime.getAndIncrement();
+      }
+    });
+    InternalCache cache = PartitionedRegionTestHelper.createCache();
+    when(cache.getStatisticsClock()).thenReturn(statisticsClock);
+    PartitionedRegion pr = spy(createPR(regionName + 1, localMaxMemory));
+    when(pr.getStatisticsClock()).thenReturn(statisticsClock);
+
+    putRecords(pr);
+
+    assertThat(pr.size()).isEqualTo(LOTS_OF_RECORDS);
+
+    assertThat(pr.getPrStats().getBucketClearCount()).isEqualTo(0L);
+
+    assertThat(pr.getPrStats().getBucketClearTime()).isEqualTo(0L);
+
+
+    pr.clear();
+
+    // We know the clock should be called 7189 times if everything is working as expected
+    verify(statisticsClock, times(7189)).getTime();
+
+    assertThat(pr.getPrStats().getBucketClearCount()).isGreaterThan(0L);
+    assertThat(pr.getPrStats().getBucketClearTime())
+        .describedAs(
+            "Bucket Clear Time should be the number of buckets "
+                + "because of the fake clock that just increments")
+        .isEqualTo(NUMBER_OF_BUCKETS);
+  }
+
+  @Test
+  public void testBasicPartitionedRegionClearsInProgressStat() {
+    String regionName = "testStats";
+    int localMaxMemory = 100;
+    PartitionedRegion pr = createPR(regionName + 1, localMaxMemory);
+    assertThat(pr.getPrStats().getBucketClearsInProgress()).isEqualTo(0L);
+
+    final long startTime = pr.getPrStats().startBucketClear();
+    assertThat(pr.getPrStats().getBucketClearsInProgress()).isEqualTo(1L);
+    pr.getPrStats().endBucketClear(startTime);
+    assertThat(pr.getPrStats().getBucketClearsInProgress()).isEqualTo(0L);
+  }
+
+  @Test
+  public void testFullPartitionedRegionClearsInProgressStat() {
+    String regionName = "testStats";
+    int localMaxMemory = 100;
+    PartitionedRegion pr = spy(createPR(regionName + 1, localMaxMemory));
+    for (long i = 0L; i < 100; i++) {
+      try {
+        pr.put(i, i);
+      } catch (PartitionedRegionStorageException ex) {
+        this.logger.warn(ex);
+      }
+    }
+    PartitionedRegionStats partitionedRegionStats = spy(pr.getPrStats());
+    when(pr.getPrStats()).thenReturn(partitionedRegionStats);
+
+    BucketRegion actualBucketRegion = pr.getBucketRegion(0L);
+    assertThat((Object) actualBucketRegion).isNotNull();
+    InternalRegionArguments arguments = mock(InternalRegionArguments.class);
+    when(arguments.getPartitionedRegion()).thenReturn(pr);
+    when(arguments.getBucketAdvisor()).thenReturn(actualBucketRegion.getBucketAdvisor());
+    when(arguments.getPartitionedRegionBucketRedundancy())
+        .thenReturn(actualBucketRegion.getRedundancyLevel());
+    when(arguments.isUsedForPartitionedRegionBucket()).thenReturn(true);
+
+    BucketRegion bucketRegion =
+        new BucketRegion(pr.getName(), pr.getBucketRegion(0L).getAttributes(), pr.getRoot(),
+            PartitionedRegionTestHelper.getCache(), arguments,
+            pr.getStatisticsClock());
+    bucketRegion = spy(bucketRegion);
+
+
+    assertThat(pr.size()).isEqualTo(100);
+    RegionEventImpl event = new RegionEventImpl(bucketRegion, Operation.REGION_CLEAR, null,
+        false, bucketRegion.getMyId(), bucketRegion.generateEventID());
+    bucketRegion.basicClear(event);
+    assertThat(bucketRegion.getPartitionedRegion().getPrStats().getBucketClearCount())
+        .isEqualTo(1L);
+    verify(partitionedRegionStats, times(1)).startBucketClear();
+    verify(partitionedRegionStats, times(1)).endBucketClear(anyLong());
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegion.java
index 9ea780d..a8271c4 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegion.java
@@ -505,6 +505,8 @@ public abstract class AbstractRegion implements InternalRegion, AttributesMutato
     checkForLimitedOrNoAccess();
     RegionEventImpl regionEvent = new RegionEventImpl(this, Operation.REGION_CLEAR, null, false,
         getMyId(), generateEventID());
+
+
     basicClear(regionEvent);
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
index ee13a0a..5c3a5eb 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.internal.cache;
 
+
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -340,20 +341,6 @@ public abstract class AbstractRegionMap extends BaseRegionMap
     }
   }
 
-  void incClearCount(LocalRegion lr) {
-    if (lr != null && !(lr instanceof HARegion)) {
-      CachePerfStats stats = lr.getCachePerfStats();
-      if (stats != null) {
-        if (lr.isUsedForPartitionedRegionBucket()) {
-          stats.incBucketClearCount();
-        } else {
-          stats.incRegionClearCount();
-        }
-
-      }
-    }
-  }
-
   private void _mapClear() {
     Executor executor = null;
     InternalCache cache = this.owner.getCache();
@@ -388,90 +375,96 @@ public abstract class AbstractRegionMap extends BaseRegionMap
     if (logger.isDebugEnabled()) {
       logger.debug("Clearing entries for {} rvv={}", _getOwner(), rvv);
     }
-    LocalRegion lr = _getOwner();
+    final LocalRegion lr = _getOwner();
     RegionVersionVector localRvv = lr.getVersionVector();
-    incClearCount(lr);
-    // lock for size calcs if the region might have tombstones
-    Object lockObj = lr.getConcurrencyChecksEnabled() ? lr.getSizeGuard() : new Object();
-    synchronized (lockObj) {
-      if (rvv == null) {
-        int delta = 0;
-        try {
-          delta = sizeInVM(); // TODO soplog need to determine if stats should
-                              // reflect only size in memory or the complete thing
-        } catch (GemFireIOException e) {
-          // ignore rather than throwing an exception during cache close
-        }
-        int tombstones = lr.getTombstoneCount();
-        _mapClear();
-        _getOwner().updateSizeOnClearRegion(delta - tombstones);
-        _getOwner().incTombstoneCount(-tombstones);
-        if (delta != 0) {
-          incEntryCount(-delta);
-        }
-      } else {
-        int delta = 0;
-        int tombstones = 0;
-        VersionSource myId = _getOwner().getVersionMember();
-        if (localRvv != rvv) {
-          localRvv.recordGCVersions(rvv);
-        }
-        final boolean isTraceEnabled = logger.isTraceEnabled();
-        for (RegionEntry re : regionEntries()) {
-          synchronized (re) {
-            Token value = re.getValueAsToken();
-            // if it's already being removed or the entry is being created we leave it alone
-            if (value == Token.REMOVED_PHASE1 || value == Token.REMOVED_PHASE2) {
-              continue;
-            }
 
-            VersionSource id = re.getVersionStamp().getMemberID();
-            if (id == null) {
-              id = myId;
-            }
-            if (rvv.contains(id, re.getVersionStamp().getRegionVersion())) {
-              if (isTraceEnabled) {
-                logger.trace("region clear op is removing {} {}", re.getKey(),
-                    re.getVersionStamp());
+    final long startTime = lr.startClear();
+
+    try {
+      // lock for size calcs if the region might have tombstones
+      Object lockObj = lr.getConcurrencyChecksEnabled() ? lr.getSizeGuard() : new Object();
+      synchronized (lockObj) {
+        if (rvv == null) {
+          int delta = 0;
+          try {
+            delta = sizeInVM(); // TODO soplog need to determine if stats should
+            // reflect only size in memory or the complete thing
+          } catch (GemFireIOException e) {
+            // ignore rather than throwing an exception during cache close
+          }
+          int tombstones = lr.getTombstoneCount();
+          _mapClear();
+          _getOwner().updateSizeOnClearRegion(delta - tombstones);
+          _getOwner().incTombstoneCount(-tombstones);
+          if (delta != 0) {
+            incEntryCount(-delta);
+          }
+        } else {
+          int delta = 0;
+          int tombstones = 0;
+          VersionSource myId = _getOwner().getVersionMember();
+          if (localRvv != rvv) {
+            localRvv.recordGCVersions(rvv);
+          }
+          final boolean isTraceEnabled = logger.isTraceEnabled();
+          for (RegionEntry re : regionEntries()) {
+            synchronized (re) {
+              Token value = re.getValueAsToken();
+              // if it's already being removed or the entry is being created we leave it alone
+              if (value == Token.REMOVED_PHASE1 || value == Token.REMOVED_PHASE2) {
+                continue;
               }
 
-              boolean tombstone = re.isTombstone();
-              // note: it.remove() did not reliably remove the entry so we use remove(K,V) here
-              if (getEntryMap().remove(re.getKey(), re)) {
-                if (OffHeapClearRequired.doesClearNeedToCheckForOffHeap()) {
-                  GatewaySenderEventImpl.release(re.getValue()); // OFFHEAP _getValue ok
-                }
-                // If this is an overflow only region, we need to free the entry on
-                // disk at this point.
-                try {
-                  re.removePhase1(lr, true);
-                } catch (RegionClearedException e) {
-                  // do nothing, it's already cleared.
+              VersionSource id = re.getVersionStamp().getMemberID();
+              if (id == null) {
+                id = myId;
+              }
+              if (rvv.contains(id, re.getVersionStamp().getRegionVersion())) {
+                if (isTraceEnabled) {
+                  logger.trace("region clear op is removing {} {}", re.getKey(),
+                      re.getVersionStamp());
                 }
-                re.removePhase2();
-                lruEntryDestroy(re);
-                if (tombstone) {
-                  _getOwner().incTombstoneCount(-1);
-                  tombstones += 1;
-                } else {
-                  delta += 1;
+
+                boolean tombstone = re.isTombstone();
+                // note: it.remove() did not reliably remove the entry so we use remove(K,V) here
+                if (getEntryMap().remove(re.getKey(), re)) {
+                  if (OffHeapClearRequired.doesClearNeedToCheckForOffHeap()) {
+                    GatewaySenderEventImpl.release(re.getValue()); // OFFHEAP _getValue ok
+                  }
+                  // If this is an overflow only region, we need to free the entry on
+                  // disk at this point.
+                  try {
+                    re.removePhase1(lr, true);
+                  } catch (RegionClearedException e) {
+                    // do nothing, it's already cleared.
+                  }
+                  re.removePhase2();
+                  lruEntryDestroy(re);
+                  if (tombstone) {
+                    _getOwner().incTombstoneCount(-1);
+                    tombstones += 1;
+                  } else {
+                    delta += 1;
+                  }
                 }
+              } else { // rvv does not contain this entry so it is retained
+                result.add(id);
               }
-            } else { // rvv does not contain this entry so it is retained
-              result.add(id);
             }
           }
-        }
-        _getOwner().updateSizeOnClearRegion(delta);
-        incEntryCount(-delta);
-        incEntryCount(-tombstones);
-        if (logger.isDebugEnabled()) {
-          logger.debug("Size after clearing = {}", getEntryMap().size());
-        }
-        if (isTraceEnabled && getEntryMap().size() < 20) {
-          _getOwner().dumpBackingMap();
+          _getOwner().updateSizeOnClearRegion(delta);
+          incEntryCount(-delta);
+          incEntryCount(-tombstones);
+          if (logger.isDebugEnabled()) {
+            logger.debug("Size after clearing = {}", getEntryMap().size());
+          }
+          if (isTraceEnabled && getEntryMap().size() < 20) {
+            _getOwner().dumpBackingMap();
+          }
         }
       }
+    } finally {
+      lr.endClear(startTime);
     }
     return result;
   }
@@ -699,7 +692,7 @@ public abstract class AbstractRegionMap extends BaseRegionMap
         }
         // incEntryCount is called for a tombstone because scheduleTombstone does entryCount--.
         incEntryCount(1); // we are creating an entry that was recovered from disk including
-                          // tombstone
+        // tombstone
       }
       lruEntryUpdate(newRe);
       needsCallback = true;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java
index 38d352f..a7a0714 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java
@@ -578,8 +578,8 @@ public class BucketRegion extends DistributedRegion implements Bucket {
     // get rvvLock
     Set<InternalDistributedMember> participants =
         getCacheDistributionAdvisor().adviseInvalidateRegion();
-
     try {
+
       obtainWriteLocksForClear(regionEvent, participants);
       // no need to dominate my own rvv.
       // Clear is on going here, there won't be GII for this member
@@ -2142,13 +2142,6 @@ public class BucketRegion extends DistributedRegion implements Bucket {
 
   @Override
   void updateSizeOnClearRegion(int sizeBeforeClear) {
-    // This method is only called when the bucket is destroyed. If we
-    // start supporting clear of partitioned regions, this logic needs to change
-    // we can't just set these counters to zero, because there could be
-    // concurrent operations that are also updating these stats. For example,
-    // a destroy could have already been applied to the map, and then updates
-    // the stat after we reset it, making the state negative.
-
     final PartitionedRegionDataStore prDs = partitionedRegion.getDataStore();
     long oldMemValue;
 
@@ -2542,4 +2535,19 @@ public class BucketRegion extends DistributedRegion implements Bucket {
     basicClear(regionEvent, false);
   }
 
+  @Override
+  public long startClear() {
+    return getPartitionedRegion().getPrStats().startBucketClear();
+  }
+
+  @Override
+  public void endClear(long startTime) {
+    getPartitionedRegion().getPrStats().endBucketClear(startTime);
+  }
+
+  @Override
+  public void clear() {
+    throw new UnsupportedOperationException("BucketRegion.clear should never be called");
+  }
+
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java b/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java
index 6f18b55..5a92124 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java
@@ -118,11 +118,9 @@ public class CachePerfStats {
   static final int indexUpdateInProgressId;
   static final int indexUpdateCompletedId;
   static final int indexUpdateTimeId;
-  static final int bucketClearsId;
-  static final int regionClearsId;
-  static final int partitionedRegionClearLocalDurationId;
-  static final int partitionedRegionClearTotalDurationId;
-
+  static final int clearsId;
+  static final int clearTimeId;
+  static final int clearsInProgressId;
   private static final int indexInitializationInProgressId;
   private static final int indexInitializationCompletedId;
   private static final int indexInitializationTimeId;
@@ -292,14 +290,12 @@ public class CachePerfStats {
         "Current number of regions configured for reliablity that are missing required roles with Limited access";
     final String reliableRegionsMissingNoAccessDesc =
         "Current number of regions configured for reliablity that are missing required roles with No access";
-    final String regionClearsDesc =
+    final String clearsDesc =
         "The total number of times a clear has been done on this cache.";
-    final String bucketClearsDesc =
-        "The total number of times a clear has been done on this region and it's bucket regions";
-    final String partitionedRegionClearLocalDurationDesc =
-        "The time in nanoseconds partitioned region clear has been running for the region on this member";
-    final String partitionedRegionClearTotalDurationDesc =
-        "The time in nanoseconds partitioned region clear has been running for the region with this member as coordinator.";
+    final String clearTimeDesc =
+        "The total time spent performing clears in nanoseconds.";
+    final String clearsInProgressDesc =
+        "The number of clears currently in progress.";
     final String metaDataRefreshCountDesc =
         "Total number of times the meta data is refreshed due to hopping observed.";
     final String conflatedEventsDesc =
@@ -481,13 +477,10 @@ public class CachePerfStats {
             f.createLongCounter("retries",
                 "Number of times a concurrent destroy followed by a create has caused an entry operation to need to retry.",
                 "operations"),
-            f.createLongCounter("regionClears", regionClearsDesc, "operations"),
-            f.createLongCounter("bucketClears", bucketClearsDesc, "operations"),
-            f.createLongCounter("partitionedRegionClearLocalDuration",
-                partitionedRegionClearLocalDurationDesc, "nanoseconds"),
-            f.createLongCounter("partitionedRegionClearTotalDuration",
-                partitionedRegionClearTotalDurationDesc, "nanoseconds"),
-            f.createLongGauge("diskTasksWaiting",
+            f.createLongCounter("clears", clearsDesc, "operations"),
+            f.createLongGauge("clearsInProgress", clearsInProgressDesc, "operations"),
+            f.createLongCounter("clearTime", clearTimeDesc, "nanoseconds"),
+            f.createIntGauge("diskTasksWaiting",
                 "Current number of disk tasks (oplog compactions, asynchronous recoveries, etc) that are waiting for a thread to run the operation",
                 "operations"),
             f.createLongCounter("conflatedEvents", conflatedEventsDesc, "operations"),
@@ -630,11 +623,9 @@ public class CachePerfStats {
     eventsQueuedId = type.nameToId("eventsQueued");
 
     retriesId = type.nameToId("retries");
-    regionClearsId = type.nameToId("regionClears");
-    bucketClearsId = type.nameToId("bucketClears");
-    partitionedRegionClearLocalDurationId = type.nameToId("partitionedRegionClearLocalDuration");
-    partitionedRegionClearTotalDurationId = type.nameToId("partitionedRegionClearTotalDuration");
-
+    clearsId = type.nameToId("clears");
+    clearTimeId = type.nameToId("clearTime");
+    clearsInProgressId = type.nameToId("clearsInProgress");
     diskTasksWaitingId = type.nameToId("diskTasksWaiting");
     evictorJobsStartedId = type.nameToId("evictorJobsStarted");
     evictorJobsCompletedId = type.nameToId("evictorJobsCompleted");
@@ -1423,36 +1414,32 @@ public class CachePerfStats {
     };
   }
 
-  public long getRegionClearCount() {
-    return stats.getLong(regionClearsId);
-  }
-
-  public long getBucketClearCount() {
-    return stats.getLong(bucketClearsId);
-  }
-
-  public long getPartitionedRegionClearLocalDuration() {
-    return stats.getLong(partitionedRegionClearLocalDurationId);
+  public long getClearCount() {
+    return stats.getLong(clearsId);
   }
 
-  public long getPartitionedRegionClearTotalDuration() {
-    return stats.getLong(partitionedRegionClearTotalDurationId);
-  }
-
-  public void incRegionClearCount() {
-    stats.incLong(regionClearsId, 1L);
+  public long startClear() {
+    stats.incLong(clearsInProgressId, 1L);
+    return getTime();
   }
 
-  public void incBucketClearCount() {
-    stats.incLong(bucketClearsId, 1L);
+  public long endClear(long startTime) {
+    long timeTaken = 0L;
+    if (clock.isEnabled()) {
+      timeTaken = getTime() - startTime;
+      stats.incLong(clearTimeId, timeTaken);
+    }
+    stats.incLong(clearsInProgressId, -1L);
+    stats.incLong(clearsId, 1L);
+    return timeTaken;
   }
 
-  public void incPartitionedRegionClearLocalDuration(long durationNanos) {
-    stats.incLong(partitionedRegionClearLocalDurationId, durationNanos);
+  public long getClearTime() {
+    return stats.getLong(clearTimeId);
   }
 
-  public void incPartitionedRegionClearTotalDuration(long durationNanos) {
-    stats.incLong(partitionedRegionClearTotalDurationId, durationNanos);
+  public long getClearsInProgress() {
+    return stats.getLong(clearsInProgressId);
   }
 
   public long getConflatedEventsCount() {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/DummyCachePerfStats.java b/geode-core/src/main/java/org/apache/geode/internal/cache/DummyCachePerfStats.java
index 1e3d30b..3b6a7bb 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/DummyCachePerfStats.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/DummyCachePerfStats.java
@@ -374,4 +374,14 @@ public class DummyCachePerfStats extends CachePerfStats {
     };
   }
 
+  @Override
+  public long startClear() {
+    return 0L;
+  }
+
+  @Override
+  public long endClear(long startTime) {
+    return 0L;
+  }
+
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
index 2ad8336..f143e19 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
@@ -1012,9 +1012,9 @@ public class GemFireCacheImpl implements InternalCache, InternalClientCache, Has
       // Create the CacheStatistics
       statisticsClock = StatisticsClockFactory.clock(system.getConfig().getEnableTimeStatistics());
       cachePerfStats = cachePerfStatsFactory.create(
-          internalDistributedSystem.getStatisticsManager(), statisticsClock);
+          internalDistributedSystem.getStatisticsManager(), getStatisticsClock());
 
-      transactionManager = txManagerImplFactory.create(cachePerfStats, this, statisticsClock);
+      transactionManager = txManagerImplFactory.create(cachePerfStats, this, getStatisticsClock());
       dm.addMembershipListener(transactionManager);
 
       creationDate = new Date();
@@ -2102,7 +2102,7 @@ public class GemFireCacheImpl implements InternalCache, InternalClientCache, Has
     synchronized (heapEvictorLock) {
       stopper.checkCancelInProgress(null);
       if (heapEvictor == null) {
-        heapEvictor = heapEvictorFactory.create(this, statisticsClock);
+        heapEvictor = heapEvictorFactory.create(this, getStatisticsClock());
       }
       return heapEvictor;
     }
@@ -2114,7 +2114,7 @@ public class GemFireCacheImpl implements InternalCache, InternalClientCache, Has
     synchronized (offHeapEvictorLock) {
       stopper.checkCancelInProgress(null);
       if (offHeapEvictor == null) {
-        offHeapEvictor = new OffHeapEvictor(this, statisticsClock);
+        offHeapEvictor = new OffHeapEvictor(this, getStatisticsClock());
       }
       return offHeapEvictor;
     }
@@ -3057,7 +3057,7 @@ public class GemFireCacheImpl implements InternalCache, InternalClientCache, Has
               region = internalRegionArgs.getInternalMetaRegion();
             } else if (isPartitionedRegion) {
               region = new PartitionedRegion(name, attrs, null, this, internalRegionArgs,
-                  statisticsClock, ColocationLoggerFactory.create());
+                  getStatisticsClock(), ColocationLoggerFactory.create());
             } else {
               // Abstract region depends on the default pool existing so lazily initialize it
               // if necessary.
@@ -3066,10 +3066,11 @@ public class GemFireCacheImpl implements InternalCache, InternalClientCache, Has
               }
               if (attrs.getScope().isLocal()) {
                 region =
-                    new LocalRegion(name, attrs, null, this, internalRegionArgs, statisticsClock);
+                    new LocalRegion(name, attrs, null, this, internalRegionArgs,
+                        getStatisticsClock());
               } else {
                 region = new DistributedRegion(name, attrs, null, this, internalRegionArgs,
-                    statisticsClock);
+                    getStatisticsClock());
               }
             }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
index fd240ce..c9f373e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
@@ -8437,7 +8437,6 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory,
 
     RegionEventImpl event = new ClientRegionEventImpl(this, Operation.REGION_CLEAR, callbackArg,
         false, client.getDistributedMember(), client, eventId);
-
     basicClear(event, true);
   }
 
@@ -8631,7 +8630,12 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory,
   @Override
   void basicLocalClear(RegionEventImpl rEvent) {
     getDataView().checkSupportsRegionClear();
-    cmnClearRegion(rEvent, false/* cacheWrite */, false/* useRVV */);
+    final long startTime = startClear();
+    try {
+      cmnClearRegion(rEvent, false/* cacheWrite */, false/* useRVV */);
+    } finally {
+      endClear(startTime);
+    }
   }
 
   @Override
@@ -10876,6 +10880,15 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory,
     }
   }
 
+  public long startClear() {
+    return getCachePerfStats().startClear();
+  }
+
+  public void endClear(long startTime) {
+    getCachePerfStats().endClear(startTime);
+  }
+
+
   @Override
   public long getVersionForMember(VersionSource member) {
     throw new IllegalStateException("Operation only implemented for disk region");
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 e6cbf95..f29b3c6 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
@@ -571,13 +571,6 @@ public class PartitionedRegion extends LocalRegion
     return this.partitionListeners;
   }
 
-  public CachePerfStats getRegionCachePerfStats() {
-    if (dataStore != null && dataStore.getAllLocalBucketRegions().size() > 0) {
-      BucketRegion bucket = dataStore.getAllLocalBucketRegions().iterator().next();
-      return bucket.getCachePerfStats();
-    }
-    return null;
-  }
 
   /**
    * Return canonical representation for a bucket (for logging)
@@ -8083,6 +8076,11 @@ public class PartitionedRegion extends LocalRegion
       this.maxTimeInRetry = maxTime;
     }
 
+    public RetryTimeKeeper(long maxTime) {
+      this.maxTimeInRetry = maxTime;
+    }
+
+
     /**
      * wait for {@link PartitionedRegionHelper#DEFAULT_WAIT_PER_RETRY_ITERATION}, updating the total
      * wait time. Use this method when the same node has been selected for consecutive attempts with
@@ -10150,10 +10148,25 @@ public class PartitionedRegion extends LocalRegion
   }
 
   @Override
+  public void endClear(long startTime) {
+    getCachePerfStats().endClear(startTime);
+  }
+
+  @Override
+  public long startClear() {
+    return getCachePerfStats().startClear();
+  }
+
+  @Override
   void cmnClearRegion(RegionEventImpl regionEvent, boolean cacheWrite, boolean useRVV) {
     // Synchronized to avoid other threads invoking clear on this vm/node.
-    synchronized (clearLock) {
-      partitionedRegionClear.doClear(regionEvent, cacheWrite);
+    final long startTime = startClear();
+    try {
+      synchronized (clearLock) {
+        partitionedRegionClear.doClear(regionEvent, cacheWrite);
+      }
+    } finally {
+      endClear(startTime);
     }
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionClear.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionClear.java
index 8403306..cd9cef2 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionClear.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionClear.java
@@ -19,6 +19,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.logging.log4j.Logger;
 
@@ -46,9 +47,7 @@ public class PartitionedRegionClear {
   private static final Logger logger = LogService.getLogger();
 
   protected static final String CLEAR_OPERATION = "_clearOperation";
-
-  private final int retryTime = 2 * 60 * 1000;
-
+  private static final long RETRY_TIME = TimeUnit.MINUTES.toMillis(2);
   private final PartitionedRegion partitionedRegion;
 
   private final DistributedLockService distributedLockService;
@@ -194,7 +193,7 @@ public class PartitionedRegionClear {
    */
   public Set<Integer> clearRegionLocal(RegionEventImpl regionEvent) {
     Set<Integer> clearedBuckets = new HashSet<>();
-    long clearStartTime = System.nanoTime();
+
     setMembershipChange(false);
     // Synchronized to handle the requester departure.
     synchronized (lockForListenerAndClientNotification) {
@@ -203,7 +202,7 @@ public class PartitionedRegionClear {
         try {
           boolean retry;
           do {
-            waitForPrimary(new PartitionedRegion.RetryTimeKeeper(retryTime));
+            waitForPrimary(new PartitionedRegion.RetryTimeKeeper(RETRY_TIME));
             RegionEventImpl bucketRegionEvent;
             for (BucketRegion localPrimaryBucketRegion : partitionedRegion.getDataStore()
                 .getAllLocalPrimaryBucketRegions()) {
@@ -228,11 +227,7 @@ public class PartitionedRegionClear {
           doAfterClear(regionEvent);
         } finally {
           partitionedRegion.getDataStore().unlockBucketCreationForRegionClear();
-          if (clearedBuckets.size() != 0 && partitionedRegion.getCachePerfStats() != null) {
-            partitionedRegion.getRegionCachePerfStats().incRegionClearCount();
-            partitionedRegion.getRegionCachePerfStats()
-                .incPartitionedRegionClearLocalDuration(System.nanoTime() - clearStartTime);
-          }
+
         }
       } else {
         // Non data-store with client queue and listener
@@ -435,14 +430,12 @@ public class PartitionedRegionClear {
 
   void doClear(RegionEventImpl regionEvent, boolean cacheWrite) {
     String lockName = CLEAR_OPERATION + partitionedRegion.getName();
-    long clearStartTime = 0;
 
     allServerVersionsSupportPartitionRegionClear();
 
     try {
       // distributed lock to make sure only one clear op is in progress in the cluster.
       acquireDistributedClearLock(lockName);
-      clearStartTime = System.nanoTime();
 
       // Force all primary buckets to be created before clear.
       assignAllPrimaryBuckets();
@@ -483,11 +476,6 @@ public class PartitionedRegionClear {
       }
     } finally {
       releaseDistributedClearLock(lockName);
-      CachePerfStats stats = partitionedRegion.getRegionCachePerfStats();
-      if (stats != null) {
-        partitionedRegion.getRegionCachePerfStats()
-            .incPartitionedRegionClearTotalDuration(System.nanoTime() - clearStartTime);
-      }
     }
   }
 
@@ -514,7 +502,7 @@ public class PartitionedRegionClear {
     }
   }
 
-  class LockForListenerAndClientNotification {
+  static class LockForListenerAndClientNotification {
 
     private boolean locked = false;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionStats.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionStats.java
index 01080bb..68828ee 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionStats.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionStats.java
@@ -176,8 +176,17 @@ public class PartitionedRegionStats {
   private static final int prMetaDataSentCountId;
 
   private static final int localMaxMemoryId;
+  static final int bucketClearsId;
+  static final int bucketClearTimeId;
+  static final int bucketClearsInProgressId;
 
   static {
+    final String bucketClearsDesc =
+        "The total number of times a bucket of this partitioned region has been cleared";
+    final String bucketClearTimeDesc =
+        "The total amount of time, in nanoseconds, spent clearing buckets on this partitioned region";
+    final String bucketClearsInProgressDesc =
+        "The current number bucket clears on this partitioned region that are in progress";
 
     StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();
     type = f.createType("PartitionedRegionStats",
@@ -426,6 +435,9 @@ public class PartitionedRegionStats {
 
             f.createLongGauge("localMaxMemory",
                 "local max memory in bytes for this region on this member", "bytes"),
+            f.createLongCounter("bucketClears", bucketClearsDesc, "operations"),
+            f.createLongCounter("bucketClearTime", bucketClearTimeDesc, "nanoseconds"),
+            f.createLongCounter("bucketClearsInProgress", bucketClearsInProgressDesc, "operations")
         });
 
     bucketCountId = type.nameToId("bucketCount");
@@ -530,6 +542,10 @@ public class PartitionedRegionStats {
     prMetaDataSentCountId = type.nameToId("prMetaDataSentCount");
 
     localMaxMemoryId = type.nameToId("localMaxMemory");
+
+    bucketClearsId = type.nameToId("bucketClears");
+    bucketClearsInProgressId = type.nameToId("bucketClearsInProgress");
+    bucketClearTimeId = type.nameToId("bucketClearTime");
   }
 
   private final Statistics stats;
@@ -1191,6 +1207,20 @@ public class PartitionedRegionStats {
     stats.incLong(putLocalTimeId, delta);
   }
 
+  public long startBucketClear() {
+    stats.incLong(bucketClearsInProgressId, 1L);
+    return clock.getTime();
+  }
+
+  public void endBucketClear(long start) {
+    stats.incLong(bucketClearsId, 1);
+    stats.incLong(bucketClearsInProgressId, -1L);
+    if (clock.isEnabled()) {
+      long delta = clock.getTime() - start;
+      stats.incLong(bucketClearTimeId, delta);
+    }
+  }
+
   public void incPRMetaDataSentCount() {
     this.stats.incLong(prMetaDataSentCountId, 1);
   }
@@ -1198,4 +1228,21 @@ public class PartitionedRegionStats {
   public long getPRMetaDataSentCount() {
     return this.stats.getLong(prMetaDataSentCountId);
   }
+
+  public long getBucketClearCount() {
+    return stats.getLong(bucketClearsId);
+  }
+
+  public void incBucketClearTime(Long nanoseconds) {
+    stats.incLong(bucketClearTimeId, nanoseconds);
+  }
+
+  public long getBucketClearTime() {
+    return stats.getLong(bucketClearTimeId);
+  }
+
+  public long getBucketClearsInProgress() {
+    return stats.getLong(bucketClearsInProgressId);
+  }
+
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/RegionPerfStats.java b/geode-core/src/main/java/org/apache/geode/internal/cache/RegionPerfStats.java
index cfdc8b6..54c7e1d 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/RegionPerfStats.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/RegionPerfStats.java
@@ -519,16 +519,29 @@ class RegionPerfStats extends CachePerfStats implements RegionStats {
     cachePerfStats.incEvictWorkTime(delta);
   }
 
+  private void startClearLocal() {
+    stats.incLong(clearsInProgressId, 1L);
+  }
+
+  private void endClearLocal(long timeTaken) {
+    stats.incLong(clearsInProgressId, -1L);
+    stats.incLong(clearsId, 1L);
+    if (clock.isEnabled()) {
+      stats.incLong(clearTimeId, timeTaken);
+    }
+  }
+
   @Override
-  public void incRegionClearCount() {
-    stats.incLong(regionClearsId, 1L);
-    cachePerfStats.incRegionClearCount();
+  public long startClear() {
+    startClearLocal();
+    return cachePerfStats.startClear();
   }
 
   @Override
-  public void incBucketClearCount() {
-    stats.incLong(bucketClearsId, 1L);
-    cachePerfStats.incBucketClearCount();
+  public long endClear(long startTime) {
+    long timeTaken = cachePerfStats.endClear(startTime);
+    endClearLocal(timeTaken);
+    return timeTaken;
   }
 
   @Override
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/RegionStats.java b/geode-core/src/main/java/org/apache/geode/internal/cache/RegionStats.java
index 8f1e0a4..6898f6d 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/RegionStats.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/RegionStats.java
@@ -135,9 +135,9 @@ public interface RegionStats {
 
   void incEvictWorkTime(long delta);
 
-  void incBucketClearCount();
+  long startClear();
 
-  void incRegionClearCount();
+  long endClear(long startTime);
 
   void incPRQueryRetries();
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java
index a80e667..c9b9126 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java
@@ -14,9 +14,10 @@
  */
 package org.apache.geode.internal.cache;
 
-import static org.apache.geode.internal.cache.CachePerfStats.bucketClearsId;
 import static org.apache.geode.internal.cache.CachePerfStats.cacheListenerCallsCompletedId;
 import static org.apache.geode.internal.cache.CachePerfStats.cacheWriterCallsCompletedId;
+import static org.apache.geode.internal.cache.CachePerfStats.clearTimeId;
+import static org.apache.geode.internal.cache.CachePerfStats.clearsId;
 import static org.apache.geode.internal.cache.CachePerfStats.createsId;
 import static org.apache.geode.internal.cache.CachePerfStats.deltaFailedUpdatesId;
 import static org.apache.geode.internal.cache.CachePerfStats.deltaFullValuesRequestedId;
@@ -43,14 +44,11 @@ import static org.apache.geode.internal.cache.CachePerfStats.loadsCompletedId;
 import static org.apache.geode.internal.cache.CachePerfStats.missesId;
 import static org.apache.geode.internal.cache.CachePerfStats.netloadsCompletedId;
 import static org.apache.geode.internal.cache.CachePerfStats.netsearchesCompletedId;
-import static org.apache.geode.internal.cache.CachePerfStats.partitionedRegionClearLocalDurationId;
-import static org.apache.geode.internal.cache.CachePerfStats.partitionedRegionClearTotalDurationId;
 import static org.apache.geode.internal.cache.CachePerfStats.previouslySeenEventsId;
 import static org.apache.geode.internal.cache.CachePerfStats.putAllsId;
 import static org.apache.geode.internal.cache.CachePerfStats.putTimeId;
 import static org.apache.geode.internal.cache.CachePerfStats.putsId;
 import static org.apache.geode.internal.cache.CachePerfStats.queryExecutionsId;
-import static org.apache.geode.internal.cache.CachePerfStats.regionClearsId;
 import static org.apache.geode.internal.cache.CachePerfStats.removeAllsId;
 import static org.apache.geode.internal.cache.CachePerfStats.retriesId;
 import static org.apache.geode.internal.cache.CachePerfStats.txCommitChangesId;
@@ -432,60 +430,30 @@ public class CachePerfStatsTest {
 
   @Test
   public void getClearsDelegatesToStatistics() {
-    statistics.incLong(regionClearsId, Long.MAX_VALUE);
+    statistics.incLong(clearsId, Long.MAX_VALUE);
 
-    assertThat(cachePerfStats.getRegionClearCount()).isEqualTo(Long.MAX_VALUE);
+    assertThat(cachePerfStats.getClearCount()).isEqualTo(Long.MAX_VALUE);
   }
 
   @Test
   public void incRegionClearCountIncrementsClears() {
-    cachePerfStats.incRegionClearCount();
+    cachePerfStats.stats.incLong(clearsId, 1L);
 
-    assertThat(statistics.getLong(regionClearsId)).isEqualTo(1L);
+    assertThat(statistics.getLong(clearsId)).isEqualTo(1L);
   }
 
-  @Test
-  public void incBucketClearCountIncrementsClears() {
-    cachePerfStats.incBucketClearCount();
-
-    assertThat(statistics.getLong(bucketClearsId)).isEqualTo(1L);
-  }
-
-  @Test
-  public void incPartitionedRegionClearLocalDurationIncrementsPartitionedRegionClearLocalDuration() {
-    cachePerfStats.incPartitionedRegionClearLocalDuration(100L);
-
-    assertThat(statistics.getLong(partitionedRegionClearLocalDurationId)).isEqualTo(100L);
-  }
-
-
-
-  @Test
-  public void incPartitionedRegionClearTotalDurationIncrementsPartitionedRegionClearTotalDuration() {
-    cachePerfStats.incPartitionedRegionClearTotalDuration(100L);
 
-    assertThat(statistics.getLong(partitionedRegionClearTotalDurationId)).isEqualTo(100L);
-  }
 
   /**
    * Characterization test: {@code clears} currently wraps to negative from max long value.
    */
   @Test
   public void regionClearsWrapsFromMaxLongToNegativeValue() {
-    statistics.incLong(regionClearsId, Long.MAX_VALUE);
-
-    cachePerfStats.incRegionClearCount();
-
-    assertThat(cachePerfStats.getRegionClearCount()).isNegative();
-  }
-
-  @Test
-  public void bucketClearsWrapsFromMaxLongToNegativeValue() {
-    statistics.incLong(bucketClearsId, Long.MAX_VALUE);
+    statistics.incLong(clearsId, Long.MAX_VALUE);
 
-    cachePerfStats.incBucketClearCount();
+    cachePerfStats.stats.incLong(clearsId, 1L);
 
-    assertThat(cachePerfStats.getBucketClearCount()).isNegative();
+    assertThat(cachePerfStats.getClearCount()).isNegative();
   }
 
   @Test
@@ -1282,4 +1250,18 @@ public class CachePerfStatsTest {
 
     assertThat(statistics.getLong(previouslySeenEventsId)).isEqualTo(1L);
   }
+
+  @Test
+  public void testBasicClearTime() {
+    assertThat(cachePerfStats.getStats().getLong(clearTimeId)).isEqualTo(0L);
+    assertThat(cachePerfStats.getClearTime()).isEqualTo(0L);
+
+    cachePerfStats.getStats().incLong(clearTimeId, 1L);
+    assertThat(cachePerfStats.getStats().getLong(clearTimeId)).isEqualTo(1L);
+    assertThat(cachePerfStats.getClearTime()).isEqualTo(1L);
+
+    cachePerfStats.stats.incLong(clearTimeId, 1L);
+    assertThat(cachePerfStats.getStats().getLong(clearTimeId)).isEqualTo(2L);
+    assertThat(cachePerfStats.getClearTime()).isEqualTo(2L);
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java
index 2a2897d..3541400 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java
@@ -75,15 +75,12 @@ import org.apache.geode.internal.cache.control.InternalResourceManager;
 import org.apache.geode.internal.cache.partitioned.colocation.ColocationLoggerFactory;
 
 @RunWith(JUnitParamsRunner.class)
-@SuppressWarnings({"deprecation", "unchecked", "unused"})
 public class PartitionedRegionTest {
 
   private InternalCache cache;
   private InternalDistributedSystem system;
   private DistributionManager distributionManager;
-  private InternalResourceManager resourceManager;
   private AttributesFactory attributesFactory;
-
   private PartitionedRegion partitionedRegion;
 
   @Rule
@@ -97,9 +94,9 @@ public class PartitionedRegionTest {
     InternalResourceManager resourceManager = mock(InternalResourceManager.class);
 
     cache = mock(InternalCache.class);
-    attributesFactory = new AttributesFactory();
+    attributesFactory = new AttributesFactory<>();
     attributesFactory.setPartitionAttributes(
-        new PartitionAttributesFactory().setTotalNumBuckets(1).setRedundantCopies(1).create());
+        new PartitionAttributesFactory<>().setTotalNumBuckets(1).setRedundantCopies(1).create());
 
     when(cache.getDistributedSystem())
         .thenReturn(system);
@@ -199,6 +196,7 @@ public class PartitionedRegionTest {
     verify(spyPartitionedRegion)
         .updatePRConfig(partitionRegionConfig, false);
 
+    assertThat(verifyOurNode).isNotNull();
     assertThat(verifyOurNode.isCacheLoaderAttached())
         .isEqualTo(cacheLoader != null);
     assertThat(verifyOurNode.isCacheWriterAttached())
@@ -219,7 +217,6 @@ public class PartitionedRegionTest {
     // ARRANGE
     EntryEventImpl clientEvent = mock(EntryEventImpl.class);
     InternalDistributedMember primaryMember = mock(InternalDistributedMember.class);
-    InternalDistributedMember secondaryMember = mock(InternalDistributedMember.class);
     PartitionedRegion spyPartitionedRegion = spy(partitionedRegion);
 
     when(clientEvent.getOperation())
@@ -244,7 +241,6 @@ public class PartitionedRegionTest {
   public void getBucketNodeForReadOrWriteReturnsSecondaryNodeForNonRegisterInterest() {
     // ARRANGE
     EntryEventImpl clientEvent = mock(EntryEventImpl.class);
-    InternalDistributedMember primaryMember = mock(InternalDistributedMember.class);
     InternalDistributedMember secondaryMember = mock(InternalDistributedMember.class);
     PartitionedRegion spyPartitionedRegion = spy(partitionedRegion);
 
@@ -269,7 +265,6 @@ public class PartitionedRegionTest {
   @Test
   public void getBucketNodeForReadOrWriteReturnsSecondaryNodeWhenClientEventIsNotPresent() {
     // ARRANGE
-    InternalDistributedMember primaryMember = mock(InternalDistributedMember.class);
     InternalDistributedMember secondaryMember = mock(InternalDistributedMember.class);
     PartitionedRegion spyPartitionedRegion = spy(partitionedRegion);
 
@@ -291,7 +286,6 @@ public class PartitionedRegionTest {
   @Test
   public void getBucketNodeForReadOrWriteReturnsSecondaryNodeWhenClientEventOperationIsNotPresent() {
     // ARRANGE
-    InternalDistributedMember primaryMember = mock(InternalDistributedMember.class);
     InternalDistributedMember secondaryMember = mock(InternalDistributedMember.class);
     PartitionedRegion spyPartitionedRegion = spy(partitionedRegion);
 
@@ -314,7 +308,6 @@ public class PartitionedRegionTest {
   public void updateBucketMapsForInterestRegistrationWithSetOfKeysFetchesPrimaryBucketsForRead() {
     // ARRANGE
     InternalDistributedMember primaryMember = mock(InternalDistributedMember.class);
-    InternalDistributedMember secondaryMember = mock(InternalDistributedMember.class);
     PartitionedRegion spyPartitionedRegion = spy(partitionedRegion);
 
     doReturn(primaryMember)
@@ -334,7 +327,6 @@ public class PartitionedRegionTest {
   public void updateBucketMapsForInterestRegistrationWithAllKeysFetchesPrimaryBucketsForRead() {
     // ARRANGE
     InternalDistributedMember primaryMember = mock(InternalDistributedMember.class);
-    InternalDistributedMember secondaryMember = mock(InternalDistributedMember.class);
     PartitionedRegion spyPartitionedRegion = spy(partitionedRegion);
 
     doReturn(primaryMember)
diff --git a/geode-junit/src/main/java/org/apache/geode/internal/cache/PartitionedRegionTestHelper.java b/geode-junit/src/main/java/org/apache/geode/internal/cache/PartitionedRegionTestHelper.java
index ef1b91b..97c1b18 100644
--- a/geode-junit/src/main/java/org/apache/geode/internal/cache/PartitionedRegionTestHelper.java
+++ b/geode-junit/src/main/java/org/apache/geode/internal/cache/PartitionedRegionTestHelper.java
@@ -14,8 +14,10 @@
  */
 package org.apache.geode.internal.cache;
 
+import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_TIME_STATISTICS;
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
+import static org.mockito.Mockito.spy;
 
 import java.io.Serializable;
 import java.util.Objects;
@@ -35,10 +37,10 @@ import org.apache.geode.cache.PartitionResolver;
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionAttributes;
 import org.apache.geode.cache.RegionExistsException;
+import org.apache.geode.cache.RegionFactory;
 import org.apache.geode.cache.Scope;
 import org.apache.geode.cache.query.SelectResults;
 import org.apache.geode.cache.query.types.ObjectType;
-import org.apache.geode.distributed.DistributedSystem;
 
 
 /**
@@ -52,29 +54,33 @@ public class PartitionedRegionTestHelper
 {
   static InternalCache cache = null;
 
+  public static InternalCache getCache() {
+    return cache;
+  }
+
   /**
    * This method creates a partitioned region with all the default values. The cache created is a
    * loner, so this is only suitable for single VM tests.
    *
    */
 
-  public static Region createPartionedRegion(String regionname) throws RegionExistsException {
-    return createPartionedRegion(regionname, new PartitionAttributesFactory().create());
+  public static <K, V> Region<K, V> createPartitionedRegion(String regionName)
+      throws RegionExistsException {
+    return createPartitionedRegion(regionName, new PartitionAttributesFactory<K, V>().create());
   }
 
   /**
    * This method creates a partitioned region with the given PR attributes. The cache created is a
    * loner, so this is only suitable for single VM tests.
    */
-  public static Region createPartionedRegion(String regionname, PartitionAttributes prattribs)
+  public static <K, V> Region<K, V> createPartitionedRegion(String regionName,
+      PartitionAttributes<K, V> partitionAttributes)
       throws RegionExistsException {
-    AttributesFactory attribFactory = new AttributesFactory();
-    attribFactory.setDataPolicy(DataPolicy.PARTITION);
-    attribFactory.setPartitionAttributes(prattribs);
-    RegionAttributes regionAttribs = attribFactory.create();
-
-    Region partitionedregion = createCache().createRegion(regionname, regionAttribs);
-    return partitionedregion;
+    createCache();
+    RegionFactory<K, V> regionFactory = cache.createRegionFactory();
+    regionFactory.setDataPolicy(DataPolicy.PARTITION);
+    regionFactory.setPartitionAttributes(partitionAttributes);
+    return regionFactory.create(regionName);
   }
 
 
@@ -83,14 +89,12 @@ public class PartitionedRegionTestHelper
    * so this is only suitable for single VM tests.
    */
 
-  public static Region createLocalRegion(String regionName) throws RegionExistsException {
-
-    AttributesFactory attr = new AttributesFactory();
-
-    attr.setScope(Scope.LOCAL);
-    Region localRegion = createCache().createRegion(regionName, attr.create());
-
-    return localRegion;
+  public static <K, V> Region<K, V> createLocalRegion(String regionName)
+      throws RegionExistsException {
+    createCache();
+    RegionFactory<K, V> regionFactory = cache.createRegionFactory();
+    regionFactory.setScope(Scope.LOCAL);
+    return regionFactory.create(regionName);
   }
 
   /**
@@ -98,8 +102,6 @@ public class PartitionedRegionTestHelper
    * SelectResults#CollectionType#ElementType()
    */
   public static String compareResultSets(SelectResults sr1, SelectResults sr2) {
-
-
     ObjectType type1, type2;
     String failureString = null;
     type1 = sr1.getCollectionType().getElementType();
@@ -117,13 +119,10 @@ public class PartitionedRegionTestHelper
     } else {
       getLogger().error("PartitionedRegionTestHelper#compareTwoQueryResults: Classes are : "
           + type1.getClass().getName() + " " + type2.getClass().getName());
-      failureString =
-          "PartitionedRegionTestHelper#compareResultSets: FAILED:Search result Type is different in both the cases"
-              + type1.getClass().getName() + " " + type2.getClass().getName();
-
       Assert.fail(
           "PartitionedRegionTestHelper#compareResultSets: FAILED:Search result Type is different in both the cases");
-      return failureString;
+      return "PartitionedRegionTestHelper#compareResultSets: FAILED:Search result Type is different in both the cases"
+          + type1.getClass().getName() + " " + type2.getClass().getName();
     }
     if ((sr1.size()) == (sr2.size())) {
       getLogger().info(
@@ -133,18 +132,19 @@ public class PartitionedRegionTestHelper
     } else {
       getLogger().error(
           "PartitionedRegionTestHelper#compareResultSets: FAILED:Search resultSet size are different in both the cases");
-      failureString =
-          "PartitionedRegionTestHelper#compareResultSets: FAILED:Search resultSet size are different in both the cases"
-              + sr1.size() + " " + sr2.size();
+
       Assert.fail(
           "PartitionedRegionTestHelper#compareResultSets: FAILED:Search resultSet size are different in both the cases");
 
+      return "PartitionedRegionTestHelper#compareResultSets: FAILED:Search resultSet size are different in both the cases"
+          + sr1.size() + " " + sr2.size();
+
     }
-    return failureString;
+    return null;
   }
 
   /**
-   * This is a function to create partitioned region with following paramaters:
+   * This is a function to create partitioned region with following parameters:
    * </p>
    * 1) name
    * </p>
@@ -155,13 +155,9 @@ public class PartitionedRegionTestHelper
    * The cache created is a loner, so this is only suitable for single VM tests.
    */
 
-  public static Region createPartitionedRegion(String regionName, String localMaxMemory,
+  public static <K, V> Region<K, V> createPartitionedRegion(String regionName,
+      String localMaxMemory,
       int redundancy) {
-    Region pr = null;
-    PartitionAttributes pa;
-    PartitionAttributesFactory paf = new PartitionAttributesFactory();
-    AttributesFactory af = new AttributesFactory();
-    RegionAttributes ra;
     // setting property
     // setting partition attributes to partitionAttributesFactory
     int lmax;
@@ -171,16 +167,19 @@ public class PartitionedRegionTestHelper
       throw new IllegalArgumentException(
           "localMaxMemory must be an integer (" + localMaxMemory + ")");
     }
-    pa = paf.setLocalMaxMemory(lmax).setRedundantCopies(redundancy).create();
-    // setting attribute factor
-    af.setPartitionAttributes(pa);
-    // creating region attributes
-    ra = af.create();
     cache = createCache();
+    RegionFactory<K, V> regionFactory = cache.createRegionFactory();
+    PartitionAttributesFactory<K, V> paf = new PartitionAttributesFactory<>();
+    paf.setLocalMaxMemory(lmax);
+    paf.setRedundantCopies(redundancy);
+    regionFactory.setPartitionAttributes(paf.create());
+
+    Region<K, V> pr;
+
     try {
-      pr = cache.createRegion(regionName, ra);
+      pr = regionFactory.create(regionName);
     } catch (RegionExistsException rex) {
-      pr = cache.getRegion(regionName);
+      pr = regionFactory.create(regionName);
     }
     return pr;
   }
@@ -190,8 +189,7 @@ public class PartitionedRegionTestHelper
    *
    */
   public static SerializableObject createPRSerializableObject(String name, int id) {
-    Object obj = new SerializableObject(name, id);
-    return (SerializableObject) obj;
+    return new SerializableObject(name, id);
 
   }
 
@@ -205,13 +203,12 @@ public class PartitionedRegionTestHelper
       Properties dsp = new Properties();
       dsp.setProperty(MCAST_PORT, "0");
       dsp.setProperty(LOCATORS, "");
-      DistributedSystem sys = DistributedSystem.connect(dsp);
+      dsp.setProperty(ENABLE_TIME_STATISTICS, "true");
+      CacheFactory cacheFactory = new CacheFactory(dsp);
       try {
-        cache = (InternalCache) CacheFactory.create(sys);
-      } catch (CacheExistsException exp) {
-        cache = (InternalCache) CacheFactory.getInstance(sys);
-      } catch (RegionExistsException rex) {
-        cache = (InternalCache) CacheFactory.getInstance(sys);
+        cache = spy((InternalCache) cacheFactory.create());
+      } catch (CacheExistsException | RegionExistsException exp) {
+        cache = spy((InternalCache) cacheFactory.create()); // hmm not happy here.
       }
     }
     return cache;
@@ -233,7 +230,7 @@ public class PartitionedRegionTestHelper
    * This method is used to return existing region.
    *
    */
-  public static Region getExistingRegion(String PRName) {
+  public static <K, V> Region<K, V> getExistingRegion(String PRName) {
     createCache();
     return cache.getRegion(PRName);
   }
@@ -247,34 +244,28 @@ public class PartitionedRegionTestHelper
     return createCache().getLogger();
   }
 
-  public static RegionAttributes createRegionAttrsForPR(int red, int localMaxMem) {
+  public static <K, V> RegionAttributes<K, V> createRegionAttrsForPR(int red, int localMaxMem) {
     return createRegionAttrsForPR(red, localMaxMem,
         PartitionAttributesFactory.RECOVERY_DELAY_DEFAULT);
   }
 
-  public static RegionAttributes createRegionAttrsForPR(int red, int localMaxMem,
-      PartitionResolver resolver) {
-    return createRegionAttrsForPR(red, localMaxMem,
-        PartitionAttributesFactory.RECOVERY_DELAY_DEFAULT, null, resolver);
-  }
-
   /**
-   * This function creates Region attributes with provided scope,redundancy and localmaxMemory
+   * This function creates Region attributes with provided scope,redundancy and localMaxMemory
    */
-  public static RegionAttributes createRegionAttrsForPR(int red, int localMaxMem,
+  public static <K, V> RegionAttributes<K, V> createRegionAttrsForPR(int red, int localMaxMem,
       long recoveryDelay) {
     return createRegionAttrsForPR(red, localMaxMem, recoveryDelay, null, null);
   }
 
   /**
-   * This function creates Region attributes with provided scope,redundancy and localmaxMemory
+   * This function creates Region attributes with provided scope,redundancy and localMaxMemory
    */
-  public static RegionAttributes createRegionAttrsForPR(int red, int localMaxMem,
-      long recoveryDelay, EvictionAttributes evictionAttrs, PartitionResolver resolver) {
+  public static <K, V> RegionAttributes<K, V> createRegionAttrsForPR(int red, int localMaxMem,
+      long recoveryDelay, EvictionAttributes evictionAttrs, PartitionResolver<K, V> resolver) {
 
-    AttributesFactory attr = new AttributesFactory();
+    AttributesFactory<K, V> attr = new AttributesFactory<>();
     attr.setDataPolicy(DataPolicy.PARTITION);
-    PartitionAttributesFactory paf = new PartitionAttributesFactory();
+    PartitionAttributesFactory<K, V> paf = new PartitionAttributesFactory<>();
     paf.setRedundantCopies(red).setLocalMaxMemory(localMaxMem).setRecoveryDelay(recoveryDelay);
     if (resolver != null) {
       paf.setPartitionResolver(resolver);
@@ -284,7 +275,6 @@ public class PartitionedRegionTestHelper
     attr.setEvictionAttributes(evictionAttrs);
     return attr.create();
   }
-
 }
 
 
@@ -293,9 +283,9 @@ public class PartitionedRegionTestHelper
  */
 
 class SerializableObject implements Serializable {
-  String str;
+  final String str;
 
-  int i;
+  final int i;
 
   public SerializableObject(String str, int i) {
     this.str = str;