You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ir...@apache.org on 2019/03/26 20:11:41 UTC
[ignite] branch master updated: IGNITE-10997 Add new property to
DataRegionMetrics: empty pages count in reuseList. - Fixes #6319.
This is an automated email from the ASF dual-hosted git repository.
irakov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new ed9a415 IGNITE-10997 Add new property to DataRegionMetrics: empty pages count in reuseList. - Fixes #6319.
ed9a415 is described below
commit ed9a41522d76e72dc3d529abf8e2dd777c230996
Author: denis-chudov <dc...@gridgain.com>
AuthorDate: Tue Mar 26 21:21:57 2019 +0300
IGNITE-10997 Add new property to DataRegionMetrics: empty pages count in reuseList. - Fixes #6319.
Signed-off-by: Ivan Rakov <ir...@apache.org>
---
.../java/org/apache/ignite/DataRegionMetrics.java | 12 +++
.../apache/ignite/DataRegionMetricsProvider.java | 39 +++++++++
.../cache/persistence/DataRegionMetricsImpl.java | 18 ++--
.../persistence/DataRegionMetricsMXBeanImpl.java | 5 ++
.../persistence/DataRegionMetricsSnapshot.java | 9 ++
.../GridCacheDatabaseSharedManager.java | 43 ++++++++++
.../cache/persistence/GridCacheOffheapManager.java | 24 +++++-
.../IgniteCacheDatabaseSharedManager.java | 41 ++++++++-
.../platform/cluster/PlatformClusterGroup.java | 1 +
.../ignite/mxbean/DataRegionMetricsMXBean.java | 4 +
.../pagemem/UsedPagesMetricAbstractTest.java | 97 ++++++++++++++++++++++
.../persistence/pagemem/UsedPagesMetricTest.java | 58 +++++++++++++
.../pagemem/UsedPagesMetricTestPersistence.java | 91 ++++++++++++++++++++
.../ignite/testsuites/IgnitePdsTestSuite.java | 4 +
.../Apache.Ignite.Core/IDataRegionMetrics.cs | 21 +++--
.../Apache.Ignite.Core/Impl/DataRegionMetrics.cs | 20 +++--
16 files changed, 463 insertions(+), 24 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java b/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java
index 88dcd16..87a9e19 100644
--- a/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java
@@ -64,6 +64,18 @@ public interface DataRegionMetrics {
public long getTotalAllocatedPages();
/**
+ * Gets a total number of pages used for storing the data. It includes allocated pages except of empty
+ * pages that are not used yet or pages that can be reused.
+ * <p>
+ * E. g. data region contains 1000 allocated pages, and 200 pages are used to store some data, this
+ * metric shows 200 used pages. Then the data was partially deleted and 50 pages were totally freed,
+ * hence this metric should show 150 used pages.
+ *
+ * @return Total number of used pages.
+ */
+ public long getTotalUsedPages();
+
+ /**
* Gets a total size of memory allocated in the data region. When persistence is disabled, this
* metric shows the total size of pages in memory. When persistence is enabled, this metric shows the
* total size of pages in memory and on disk.
diff --git a/modules/core/src/main/java/org/apache/ignite/DataRegionMetricsProvider.java b/modules/core/src/main/java/org/apache/ignite/DataRegionMetricsProvider.java
new file mode 100644
index 0000000..4a13039
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/DataRegionMetricsProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite;
+
+
+/**
+ * This interface provides calculated metrics for data region.
+ */
+public interface DataRegionMetricsProvider {
+ /**
+ * Calculates free space of partially filled pages for this data region. It does not include
+ * empty data pages.
+ *
+ * @return free space in bytes.
+ */
+ public long partiallyFilledPagesFreeSpace();
+
+ /**
+ * Calculates empty data pages count for region. It counts only totally free pages that
+ * can be reused (e. g. pages that are contained in reuse bucket of free list).
+ *
+ * @return empty data pages count.
+ */
+ public long emptyDataPages();
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
index 29cfc71..15064c8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
@@ -21,12 +21,12 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import org.apache.ignite.DataRegionMetrics;
+import org.apache.ignite.DataRegionMetricsProvider;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.internal.pagemem.PageMemory;
import org.apache.ignite.internal.processors.cache.CacheGroupMetricsMXBeanImpl.GroupAllocationTracker;
import org.apache.ignite.internal.processors.cache.ratemetrics.HitRateMetrics;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteOutClosure;
import org.jetbrains.annotations.Nullable;
/**
@@ -34,7 +34,7 @@ import org.jetbrains.annotations.Nullable;
*/
public class DataRegionMetricsImpl implements DataRegionMetrics, AllocatedPageTracker {
/** */
- private final IgniteOutClosure<Long> freeSpaceProvider;
+ private final DataRegionMetricsProvider dataRegionMetricsProvider;
/** */
private final LongAdder totalAllocatedPages = new LongAdder();
@@ -105,9 +105,10 @@ public class DataRegionMetricsImpl implements DataRegionMetrics, AllocatedPageTr
/**
* @param memPlcCfg DataRegionConfiguration.
*/
- public DataRegionMetricsImpl(DataRegionConfiguration memPlcCfg, @Nullable IgniteOutClosure<Long> freeSpaceProvider) {
+ public DataRegionMetricsImpl(DataRegionConfiguration memPlcCfg,
+ @Nullable DataRegionMetricsProvider dataRegionMetricsProvider) {
this.memPlcCfg = memPlcCfg;
- this.freeSpaceProvider = freeSpaceProvider;
+ this.dataRegionMetricsProvider = dataRegionMetricsProvider;
metricsEnabled = memPlcCfg.isMetricsEnabled();
@@ -127,6 +128,11 @@ public class DataRegionMetricsImpl implements DataRegionMetrics, AllocatedPageTr
}
/** {@inheritDoc} */
+ @Override public long getTotalUsedPages() {
+ return getTotalAllocatedPages() - dataRegionMetricsProvider.emptyDataPages();
+ }
+
+ /** {@inheritDoc} */
@Override public long getTotalAllocatedSize() {
assert pageMem != null;
@@ -161,10 +167,10 @@ public class DataRegionMetricsImpl implements DataRegionMetrics, AllocatedPageTr
/** {@inheritDoc} */
@Override public float getPagesFillFactor() {
- if (!metricsEnabled || freeSpaceProvider == null)
+ if (!metricsEnabled || dataRegionMetricsProvider == null)
return 0;
- long freeSpace = freeSpaceProvider.apply();
+ long freeSpace = dataRegionMetricsProvider.partiallyFilledPagesFreeSpace();
long totalAllocated = getPageSize() * totalAllocatedPages.longValue();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
index f837168..046593d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
@@ -67,6 +67,11 @@ class DataRegionMetricsMXBeanImpl implements DataRegionMetricsMXBean {
}
/** {@inheritDoc} */
+ @Override public long getTotalUsedPages() {
+ return memMetrics.getTotalUsedPages();
+ }
+
+ /** {@inheritDoc} */
@Override public long getTotalAllocatedSize() {
return memMetrics.getTotalAllocatedSize();
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
index f119419..d182192 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
@@ -30,6 +30,9 @@ public class DataRegionMetricsSnapshot implements DataRegionMetrics {
private long totalAllocatedPages;
/** */
+ private long totalUsedPages;
+
+ /** */
private long totalAllocatedSize;
/** */
@@ -92,6 +95,7 @@ public class DataRegionMetricsSnapshot implements DataRegionMetrics {
public DataRegionMetricsSnapshot(DataRegionMetrics metrics) {
name = metrics.getName();
totalAllocatedPages = metrics.getTotalAllocatedPages();
+ totalUsedPages = metrics.getTotalUsedPages();
totalAllocatedSize = metrics.getTotalAllocatedSize();
allocationRate = metrics.getAllocationRate();
evictionRate = metrics.getEvictionRate();
@@ -124,6 +128,11 @@ public class DataRegionMetricsSnapshot implements DataRegionMetrics {
}
/** {@inheritDoc} */
+ @Override public long getTotalUsedPages() {
+ return totalUsedPages;
+ }
+
+ /** {@inheritDoc} */
@Override public long getTotalAllocatedSize() {
return totalAllocatedSize;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index 4329d31..55fa785 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -67,12 +67,14 @@ import java.util.function.ToLongFunction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+
import org.apache.ignite.DataStorageMetrics;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteInterruptedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.DataRegionMetricsProvider;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.CheckpointWriteOrder;
@@ -855,6 +857,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
}
/** {@inheritDoc} */
+ @Deprecated
@Override protected IgniteOutClosure<Long> freeSpaceProvider(final DataRegionConfiguration dataRegCfg) {
if (!dataRegCfg.isPersistenceEnabled())
return super.freeSpaceProvider(dataRegCfg);
@@ -879,6 +882,46 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
};
}
+ /** {@inheritDoc} */
+ @Override protected DataRegionMetricsProvider dataRegionMetricsProvider(final DataRegionConfiguration dataRegCfg) {
+ if (!dataRegCfg.isPersistenceEnabled())
+ return super.dataRegionMetricsProvider(dataRegCfg);
+
+ final String dataRegName = dataRegCfg.getName();
+
+ return new DataRegionMetricsProvider() {
+ @Override public long partiallyFilledPagesFreeSpace() {
+ long freeSpace = 0L;
+
+ for (CacheGroupContext grpCtx : cctx.cache().cacheGroups()) {
+ if (!grpCtx.dataRegion().config().getName().equals(dataRegName))
+ continue;
+
+ assert grpCtx.offheap() instanceof GridCacheOffheapManager;
+
+ freeSpace += ((GridCacheOffheapManager)grpCtx.offheap()).freeSpace();
+ }
+
+ return freeSpace;
+ }
+
+ @Override public long emptyDataPages() {
+ long emptyDataPages = 0L;
+
+ for (CacheGroupContext grpCtx : cctx.cache().cacheGroups()) {
+ if (!grpCtx.dataRegion().config().getName().equals(dataRegName))
+ continue;
+
+ assert grpCtx.offheap() instanceof GridCacheOffheapManager;
+
+ emptyDataPages += ((GridCacheOffheapManager)grpCtx.offheap()).emptyDataPages();
+ }
+
+ return emptyDataPages;
+ }
+ };
+ }
+
/**
* Restores last valid WAL pointer and resumes logging from that pointer.
* Re-creates metastorage if needed.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
index ccba934..ab48540 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
@@ -1013,7 +1013,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
/**
* Calculates free space of all partition data stores - number of bytes available for use in allocated pages.
*
- * @return Tuple (numenator, denominator).
+ * @return free space size in bytes.
*/
long freeSpace() {
long freeSpace = 0;
@@ -1033,6 +1033,28 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/**
+ * Calculates empty data pages of all partition data stores.
+ *
+ * @return empty data pages count.
+ */
+ long emptyDataPages() {
+ long emptyDataPages = 0;
+
+ for (CacheDataStore store : partDataStores.values()) {
+ assert store instanceof GridCacheDataStore;
+
+ CacheFreeListImpl freeList = ((GridCacheDataStore)store).freeList;
+
+ if (freeList == null)
+ continue;
+
+ emptyDataPages += freeList.emptyDataPages();
+ }
+
+ return emptyDataPages;
+ }
+
+ /**
*
*/
private static class WALHistoricalIterator implements IgniteHistoricalIterator {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
index 7fc70d0..ee19aed 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
@@ -27,11 +27,13 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.InstanceNotFoundException;
+
import org.apache.ignite.DataRegionMetrics;
import org.apache.ignite.DataStorageMetrics;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.DataRegionMetricsProvider;
import org.apache.ignite.configuration.DataPageEvictionMode;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
@@ -352,7 +354,8 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
if (dfltMemPlcName == null)
dfltMemPlcName = DFLT_DATA_REG_DEFAULT_NAME;
- DataRegionMetricsImpl memMetrics = new DataRegionMetricsImpl(dataRegionCfg, freeSpaceProvider(dataRegionCfg));
+ DataRegionMetricsImpl memMetrics =
+ new DataRegionMetricsImpl(dataRegionCfg, dataRegionMetricsProvider(dataRegionCfg));
DataRegion region = initMemory(dataStorageCfg, dataRegionCfg, memMetrics, trackable);
@@ -372,7 +375,10 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
*
* @param dataRegCfg Data region configuration.
* @return Closure.
+ *
+ * @Deprecated use {@link #dataRegionMetricsProvider(DataRegionConfiguration)} instead.
*/
+ @Deprecated
protected IgniteOutClosure<Long> freeSpaceProvider(final DataRegionConfiguration dataRegCfg) {
final String dataRegName = dataRegCfg.getName();
@@ -395,6 +401,39 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
}
/**
+ * Provide that can be used to compute some metrics for provided data region.
+ *
+ * @param dataRegCfg Data region configuration.
+ * @return DataRegionMetricsProvider.
+ */
+ protected DataRegionMetricsProvider dataRegionMetricsProvider(final DataRegionConfiguration dataRegCfg) {
+ final String dataRegName = dataRegCfg.getName();
+
+ return new DataRegionMetricsProvider() {
+ private CacheFreeListImpl freeList;
+
+ private CacheFreeListImpl getFreeList() {
+ if (freeList == null)
+ freeList = freeListMap.get(dataRegName);
+
+ return freeList;
+ }
+
+ @Override public long partiallyFilledPagesFreeSpace() {
+ CacheFreeListImpl freeList0 = getFreeList();
+
+ return freeList0 == null ? 0L : freeList0.freeSpace();
+ }
+
+ @Override public long emptyDataPages() {
+ CacheFreeListImpl freeList0 = getFreeList();
+
+ return freeList0 == null ? 0L : freeList0.emptyDataPages();
+ }
+ };
+ }
+
+ /**
* @param memPlcsCfgs User-defined data region configurations.
*/
private boolean hasCustomDefaultDataRegion(DataRegionConfiguration[] memPlcsCfgs) {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java
index f1c70aa..097833d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java
@@ -549,6 +549,7 @@ public class PlatformClusterGroup extends PlatformAbstractTarget {
writer.writeString(metrics.getName());
writer.writeLong(metrics.getTotalAllocatedPages());
+ writer.writeLong(metrics.getTotalUsedPages());
writer.writeLong(metrics.getTotalAllocatedSize());
writer.writeFloat(metrics.getAllocationRate());
writer.writeFloat(metrics.getEvictionRate());
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/DataRegionMetricsMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/DataRegionMetricsMXBean.java
index 9bb1af6..949daea 100644
--- a/modules/core/src/main/java/org/apache/ignite/mxbean/DataRegionMetricsMXBean.java
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/DataRegionMetricsMXBean.java
@@ -58,6 +58,10 @@ public interface DataRegionMetricsMXBean extends DataRegionMetrics {
@Override public long getTotalAllocatedPages();
/** {@inheritDoc} */
+ @MXBeanDescription("Total number of used pages.")
+ @Override public long getTotalUsedPages();
+
+ /** {@inheritDoc} */
@MXBeanDescription("Allocation rate (pages per second) averaged across rateTimeInternal.")
@Override public float getAllocationRate();
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricAbstractTest.java
new file mode 100644
index 0000000..1a5032a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricAbstractTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.cache.persistence.pagemem;
+
+import org.apache.ignite.DataRegionMetrics;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Abstract class for TotalUsedPages metric tests.
+ */
+public class UsedPagesMetricAbstractTest extends GridCommonAbstractTest {
+ /** */
+ public static final String MY_CACHE = "myCache";
+
+ /** */
+ public static final String DEFAULT_DATA_REGION = "default";
+
+ /** */
+ public static final long LARGE_PRIME = 4294967291L;
+
+ /**
+ * Common scenario for used pages metric test
+ *
+ * @param nodeCnt count of ignite nodes
+ * @param iterations count of check iterations
+ * @param storedEntriesCnt count of key-value pairs in each iteration
+ * @param valSize size of value in bytes
+ * @throws Exception if failed
+ */
+ protected void testFillAndRemove(
+ int nodeCnt,
+ int iterations,
+ int storedEntriesCnt,
+ int valSize
+ ) throws Exception {
+ Ignite node = startGrids(nodeCnt);
+
+ node.cluster().active(true);
+
+ IgniteCache<Long, Object> cache = node.getOrCreateCache(MY_CACHE);
+
+ long beforeFill;
+ long afterFill;
+ long afterRmv;
+
+ for (int iter = 0; iter < iterations; iter++) {
+
+ DataRegionMetrics metricsBeforeFill = node.dataRegionMetrics(DEFAULT_DATA_REGION);
+
+ beforeFill = metricsBeforeFill.getTotalUsedPages();
+
+ for (int i = 0; i < storedEntriesCnt; i++) {
+ final long res = (i * i) % LARGE_PRIME;
+
+ cache.put(res, new byte[valSize]);
+ }
+
+ DataRegionMetrics metricsAfterFill = node.dataRegionMetrics(DEFAULT_DATA_REGION);
+
+ afterFill = metricsAfterFill.getTotalUsedPages();
+
+ for (int i = 0; i < storedEntriesCnt; i++) {
+ final long res = (i * i) % LARGE_PRIME;
+
+ cache.remove(res);
+ }
+
+ DataRegionMetrics metricsAfterRmv = node.dataRegionMetrics(DEFAULT_DATA_REGION);
+
+ afterRmv = metricsAfterRmv.getTotalUsedPages();
+
+ log.info(String.format("Used pages count before fill: %d", beforeFill));
+ log.info(String.format("Used pages count after fill: %d", afterFill));
+ log.info(String.format("Used pages count after remove: %d\n", afterRmv));
+
+ assertTrue(afterFill > beforeFill);
+ assertTrue(afterRmv < afterFill);
+ assertTrue(afterRmv >= beforeFill);
+ }
+ }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricTest.java
new file mode 100644
index 0000000..279ab80
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.cache.persistence.pagemem;
+
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.junit.Test;
+
+/**
+ * TotalUsedPages metric in-memory tests.
+ */
+public class UsedPagesMetricTest extends UsedPagesMetricAbstractTest {
+ /** */
+ public static final int NODES = 2;
+
+ /** */
+ public static final int ITERATIONS = 3;
+
+ /** */
+ public static final int STORED_ENTRIES_COUNT = 50000;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ return super.getConfiguration(igniteInstanceName)
+ .setDataStorageConfiguration(
+ new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+ new DataRegionConfiguration()
+ .setInitialSize(100 * 1024L * 1024L)
+ .setMaxSize(500 * 1024L * 1024L)
+ .setMetricsEnabled(true)
+ ));
+ }
+
+ /**
+ * Tests that totalUsedPages metric for in-memory data region behaves correctly.
+ *
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testFillAndRemoveInMemory() throws Exception {
+ testFillAndRemove(NODES, ITERATIONS, STORED_ENTRIES_COUNT, 256);
+ }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricTestPersistence.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricTestPersistence.java
new file mode 100644
index 0000000..9fabc4b
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/UsedPagesMetricTestPersistence.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.cache.persistence.pagemem;
+
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * TotalUsedPages metric persistence tests.
+ */
+public class UsedPagesMetricTestPersistence extends UsedPagesMetricAbstractTest {
+ /** */
+ public static final int NODES = 1;
+
+ /** */
+ public static final int ITERATIONS = 1;
+
+ /** */
+ public static final int STORED_ENTRIES_COUNT = 50000;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ return super.getConfiguration(igniteInstanceName)
+ .setDataStorageConfiguration(
+ new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+ new DataRegionConfiguration()
+ .setPersistenceEnabled(true)
+ .setInitialSize(100 * 1024L * 1024L)
+ .setMaxSize(500 * 1024L * 1024L)
+ .setMetricsEnabled(true)
+ ));
+ }
+
+ /**
+ *
+ */
+ @Before
+ public void cleanBeforeStart() throws Exception {
+ cleanPersistenceDir();
+ }
+
+ /**
+ *
+ */
+ @After
+ public void stopAndClean() throws Exception {
+ stopAllGrids();
+
+ cleanPersistenceDir();
+ }
+
+ /**
+ * Tests that totalUsedPages metric for data region with enabled persistence
+ * and pages being rotated to disk behaves correctly.
+ *
+ * @throws Exception if failed
+ */
+ @Test
+ public void testFillAndRemovePagesRotation() throws Exception {
+ testFillAndRemove(NODES, ITERATIONS, STORED_ENTRIES_COUNT, 8192);
+ }
+
+ /**
+ * Tests that totalUsedPages metric for data region with enabled persistence
+ * and pages that are not being rotated to disk behaves correctly.
+ *
+ * @throws Exception if failed
+ */
+ @Test
+ public void testFillAndRemoveWithoutPagesRotation() throws Exception {
+ testFillAndRemove(NODES, ITERATIONS, STORED_ENTRIES_COUNT, 256);
+ }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java
index a58b2dd..5a052bb 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java
@@ -45,6 +45,8 @@ import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemor
import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImplTest;
import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryNoStoreLeakTest;
import org.apache.ignite.internal.processors.cache.persistence.pagemem.PagesWriteThrottleSmokeTest;
+import org.apache.ignite.internal.processors.cache.persistence.pagemem.UsedPagesMetricTest;
+import org.apache.ignite.internal.processors.cache.persistence.pagemem.UsedPagesMetricTestPersistence;
import org.apache.ignite.internal.processors.cache.persistence.wal.CpTriggeredWalDeltaConsistencyTest;
import org.apache.ignite.internal.processors.cache.persistence.wal.ExplicitWalDeltaConsistencyTest;
import org.apache.ignite.internal.processors.cache.persistence.wal.SegmentedRingByteBufferTest;
@@ -101,6 +103,8 @@ public class IgnitePdsTestSuite {
// Metrics
GridTestUtils.addTestIfNeeded(suite, FillFactorMetricTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite, UsedPagesMetricTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite, UsedPagesMetricTestPersistence.class, ignoredTests);
// WAL delta consistency
GridTestUtils.addTestIfNeeded(suite, CpTriggeredWalDeltaConsistencyTest.class, ignoredTests);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IDataRegionMetrics.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IDataRegionMetrics.cs
index cd28fa3..107d248 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IDataRegionMetrics.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IDataRegionMetrics.cs
@@ -35,6 +35,11 @@ namespace Apache.Ignite.Core
long TotalAllocatedPages { get; }
/// <summary>
+ /// Gets a total number of pages used for storing the data.
+ /// </summary>
+ long TotalUsedPages { get; }
+
+ /// <summary>
/// Gets the size of allocated pages in bytes.
/// </summary>
long TotalAllocatedSize { get; }
@@ -83,14 +88,14 @@ namespace Apache.Ignite.Core
/// Gets the size of pages loaded to RAM in bytes.
/// </summary>
long PhysicalMemorySize { get; }
-
+
/// <summary>
/// Gets checkpoint buffer size in pages.
/// Deprecated, always returns 0. Use <see cref="UsedCheckpointBufferPages"/> instead.
/// </summary>
[Obsolete("Deprecated, always returns 0. Use UsedCheckpointBufferPages instead.")]
long CheckpointBufferPages { get; }
-
+
/// <summary>
/// Gets checkpoint buffer size in bytes.
/// </summary>
@@ -100,7 +105,7 @@ namespace Apache.Ignite.Core
/// Gets used checkpoint buffer size in pages.
/// </summary>
long UsedCheckpointBufferPages { get; }
-
+
/// <summary>
/// Gets used checkpoint buffer size in bytes.
/// </summary>
@@ -110,27 +115,27 @@ namespace Apache.Ignite.Core
/// Gets memory page size in bytes.
/// </summary>
int PageSize { get; }
-
+
/// <summary>
/// Gets the number of read pages from last restart.
/// </summary>
long PagesRead { get; }
-
+
/// <summary>
/// Gets the number of written pages from last restart.
/// </summary>
long PagesWritten { get; }
-
+
/// <summary>
/// Gets the number of replaced pages from last restart.
/// </summary>
long PagesReplaced { get; }
-
+
/// <summary>
/// Gets total offheap size in bytes.
/// </summary>
long OffHeapSize { get; }
-
+
/// <summary>
/// Gets total used offheap size in bytes.
/// </summary>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataRegionMetrics.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataRegionMetrics.cs
index 4cc4c0d..b121b12 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataRegionMetrics.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataRegionMetrics.cs
@@ -34,6 +34,7 @@ namespace Apache.Ignite.Core.Impl
Name = reader.ReadString();
TotalAllocatedPages = reader.ReadLong();
+ TotalUsedPages = reader.ReadLong();
TotalAllocatedSize = reader.ReadLong();
AllocationRate = reader.ReadFloat();
EvictionRate = reader.ReadFloat();
@@ -62,11 +63,14 @@ namespace Apache.Ignite.Core.Impl
public long TotalAllocatedPages { get; private set; }
/** <inheritdoc /> */
+ public long TotalUsedPages { get; private set; }
+
+ /** <inheritdoc /> */
public long TotalAllocatedSize { get; private set; }
/** <inheritdoc /> */
public float AllocationRate { get; private set; }
-
+
/** <inheritdoc /> */
public float EvictionRate { get; private set; }
@@ -90,8 +94,8 @@ namespace Apache.Ignite.Core.Impl
/** <inheritdoc /> */
public long PhysicalMemorySize { get; private set; }
-
- /** <inheritdoc /> */
+
+ /** <inheritdoc /> */
public long CheckpointBufferPages
{
get
@@ -111,19 +115,19 @@ namespace Apache.Ignite.Core.Impl
/** <inheritdoc /> */
public int PageSize { get; private set; }
-
+
/** <inheritdoc /> */
public long PagesRead { get; private set; }
-
+
/** <inheritdoc /> */
public long PagesWritten { get; private set; }
-
+
/** <inheritdoc /> */
public long PagesReplaced { get; private set; }
-
+
/** <inheritdoc /> */
public long OffHeapSize { get; private set; }
-
+
/** <inheritdoc /> */
public long OffheapUsedSize { get; private set; }
}