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

tkalkirill pushed a commit to branch ignite-25630
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit a469f1172e487d898e3d9a401a98c4e42c145552
Author: Kirill Tkalenko <[email protected]>
AuthorDate: Tue Jun 17 14:49:40 2025 +0300

    IGNITE-25630 wip
---
 .../persistence/PersistentPageMemory.java          |  6 ++
 .../pagememory/AbstractPageMemoryTableStorage.java | 21 ++++---
 .../pagememory/PersistentPageMemoryDataRegion.java | 69 +++++++++++++++++++++-
 .../PersistentPageMemoryStorageEngine.java         |  6 +-
 .../PersistentPageMemoryTableStorage.java          |  7 ++-
 .../pagememory/VolatilePageMemoryTableStorage.java |  2 +-
 .../mv/PersistentPageMemoryMvPartitionStorage.java |  4 ++
 7 files changed, 104 insertions(+), 11 deletions(-)

diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java
index cd32e9d4fbd..23516333e0a 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java
@@ -81,6 +81,7 @@ import 
org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.metrics.IntGauge;
+import org.apache.ignite.internal.metrics.LongGauge;
 import org.apache.ignite.internal.pagememory.FullPageId;
 import org.apache.ignite.internal.pagememory.PageMemory;
 import 
org.apache.ignite.internal.pagememory.configuration.schema.PersistentPageMemoryProfileConfiguration;
@@ -290,6 +291,11 @@ public class PersistentPageMemory implements PageMemory {
         metricSource.addMetric(new IntGauge(
                 "MaxCheckpointBufferPages", "The capacity of checkpoint buffer 
in pages.", this::maxCheckpointBufferPages
         ));
+        metricSource.addMetric(new LongGauge(
+                "MaxSize",
+                "Maximum region size in bytes.",
+                storageProfileView::sizeBytes
+        ));
     }
 
     /**
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/AbstractPageMemoryTableStorage.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/AbstractPageMemoryTableStorage.java
index 6ec4e53d563..1da4f4af9dd 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/AbstractPageMemoryTableStorage.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/AbstractPageMemoryTableStorage.java
@@ -61,8 +61,8 @@ import org.jetbrains.annotations.Nullable;
 /**
  * Abstract table storage implementation based on {@link PageMemory}.
  */
-public abstract class AbstractPageMemoryTableStorage implements MvTableStorage 
{
-    private final MvPartitionStorages<AbstractPageMemoryMvPartitionStorage> 
mvPartitionStorages;
+public abstract class AbstractPageMemoryTableStorage<T extends 
AbstractPageMemoryMvPartitionStorage> implements MvTableStorage {
+    final MvPartitionStorages<T> mvPartitionStorages;
 
     private final IgniteSpinBusyLock busyLock = new IgniteSpinBusyLock();
 
@@ -112,6 +112,8 @@ public abstract class AbstractPageMemoryTableStorage 
implements MvTableStorage {
 
         busyLock.block();
 
+        beforeCloseOrDestroy();
+
         return mvPartitionStorages.getAllForCloseOrDestroy()
                 .thenCompose(storages -> 
allOf(storages.stream().map(this::destroyMvPartitionStorage).toArray(CompletableFuture[]::new)))
                 .whenComplete((unused, throwable) -> {
@@ -132,7 +134,7 @@ public abstract class AbstractPageMemoryTableStorage 
implements MvTableStorage {
      * @param partitionId Partition ID.
      * @throws StorageException If there is an error while creating the mv 
partition storage.
      */
-    public abstract AbstractPageMemoryMvPartitionStorage 
createMvPartitionStorage(int partitionId) throws StorageException;
+    public abstract T createMvPartitionStorage(int partitionId) throws 
StorageException;
 
     /**
      * Destroys the partition multi-version storage and all its indexes.
@@ -145,7 +147,7 @@ public abstract class AbstractPageMemoryTableStorage 
implements MvTableStorage {
     @Override
     public CompletableFuture<MvPartitionStorage> createMvPartition(int 
partitionId) {
         return busy(() -> mvPartitionStorages.create(partitionId, partId -> {
-            AbstractPageMemoryMvPartitionStorage partition = 
createMvPartitionStorage(partitionId);
+            T partition = createMvPartitionStorage(partitionId);
 
             partition.start();
 
@@ -202,7 +204,7 @@ public abstract class AbstractPageMemoryTableStorage 
implements MvTableStorage {
         }
 
         try {
-            List<AbstractPageMemoryMvPartitionStorage> storages = 
mvPartitionStorages.getAll();
+            List<T> storages = mvPartitionStorages.getAll();
 
             var destroyFutures = new CompletableFuture[storages.size()];
 
@@ -247,9 +249,10 @@ public abstract class AbstractPageMemoryTableStorage 
implements MvTableStorage {
 
         busyLock.block();
 
+        beforeCloseOrDestroy();
+
         try {
-            CompletableFuture<List<AbstractPageMemoryMvPartitionStorage>> 
allForCloseOrDestroy
-                    = mvPartitionStorages.getAllForCloseOrDestroy();
+            CompletableFuture<List<T>> allForCloseOrDestroy = 
mvPartitionStorages.getAllForCloseOrDestroy();
 
             // 10 seconds is taken by analogy with shutdown of thread pool, in 
general this should be fairly fast.
             IgniteUtils.closeAllManually(allForCloseOrDestroy.get(10, 
TimeUnit.SECONDS).stream());
@@ -392,4 +395,8 @@ public abstract class AbstractPageMemoryTableStorage 
implements MvTableStorage {
     public StorageTableDescriptor getTableDescriptor() {
         return tableDescriptor;
     }
+
+    protected void beforeCloseOrDestroy() {
+        // No-op.
+    }
 }
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
index 0edbb82b4f7..d70bd6577bc 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
@@ -27,6 +27,8 @@ import static org.apache.ignite.internal.util.Constants.MiB;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Function;
@@ -35,23 +37,27 @@ import 
org.apache.ignite.internal.configuration.SystemPropertyView;
 import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.metrics.LongGauge;
 import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.pagememory.DataRegion;
 import org.apache.ignite.internal.pagememory.FullPageId;
 import 
org.apache.ignite.internal.pagememory.configuration.schema.PersistentPageMemoryProfileConfiguration;
 import 
org.apache.ignite.internal.pagememory.configuration.schema.PersistentPageMemoryProfileView;
 import org.apache.ignite.internal.pagememory.io.PageIoRegistry;
+import org.apache.ignite.internal.pagememory.persistence.GroupPartitionId;
 import org.apache.ignite.internal.pagememory.persistence.PartitionMetaManager;
 import org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory;
 import 
org.apache.ignite.internal.pagememory.persistence.PersistentPageMemoryMetricSource;
 import 
org.apache.ignite.internal.pagememory.persistence.checkpoint.CheckpointManager;
 import 
org.apache.ignite.internal.pagememory.persistence.checkpoint.CheckpointProgress;
+import org.apache.ignite.internal.pagememory.persistence.store.FilePageStore;
 import 
org.apache.ignite.internal.pagememory.persistence.store.FilePageStoreManager;
 import 
org.apache.ignite.internal.pagememory.persistence.throttling.PagesWriteSpeedBasedThrottle;
 import 
org.apache.ignite.internal.pagememory.persistence.throttling.PagesWriteThrottlePolicy;
 import 
org.apache.ignite.internal.pagememory.persistence.throttling.TargetRatioPagesWriteThrottle;
 import 
org.apache.ignite.internal.pagememory.persistence.throttling.ThrottlingType;
 import org.apache.ignite.internal.storage.StorageException;
+import 
org.apache.ignite.internal.storage.pagememory.mv.PersistentPageMemoryMvPartitionStorage;
 import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.jetbrains.annotations.Nullable;
 
@@ -98,7 +104,9 @@ class PersistentPageMemoryDataRegion implements 
DataRegion<PersistentPageMemory>
 
     private volatile AtomicLong pageListCacheLimit;
 
-    private PersistentPageMemoryMetricSource metricSource;
+    private final PersistentPageMemoryMetricSource metricSource;
+
+    private final Collection<PersistentPageMemoryTableStorage> tableStorages = 
ConcurrentHashMap.newKeySet();
 
     /**
      * Constructor.
@@ -158,6 +166,8 @@ class PersistentPageMemoryDataRegion implements 
DataRegion<PersistentPageMemory>
 
         pageMemory.start();
 
+        initMetrics();
+
         metricManager.registerSource(metricSource);
         metricManager.enable(metricSource);
 
@@ -395,4 +405,61 @@ class PersistentPageMemoryDataRegion implements 
DataRegion<PersistentPageMemory>
             throw new StorageException("Data region not started");
         }
     }
+
+    void addTableStorage(PersistentPageMemoryTableStorage tableStorage) {
+        boolean add = tableStorages.add(tableStorage);
+
+        assert add : tableStorage.getTableId();
+    }
+
+    void removeTableStorage(PersistentPageMemoryTableStorage tableStorage) {
+        boolean removed = tableStorages.remove(tableStorage);
+
+        assert removed : tableStorage.getTableId();
+    }
+
+    private void initMetrics() {
+        metricSource.addMetric(new LongGauge(
+                "TotalAllocatedSize",
+                "Total size of allocated pages on disk in bytes.",
+                this::totalAllocatedPagesSizeOnDiskInBytes
+        ));
+        metricSource.addMetric(new LongGauge(
+                "TotalUsedSize",
+                "Total size of non-empty allocated pages on disk in bytes.",
+                this::totalNonEmptyAllocatedPagesSizeOnDiskInBytes
+        ));
+    }
+
+    private long totalAllocatedPagesSizeOnDiskInBytes() {
+        long pageCount = 0;
+
+        for (PersistentPageMemoryTableStorage tableStorage : tableStorages) {
+            for (PersistentPageMemoryMvPartitionStorage partitionStorage : 
tableStorage.mvPartitionStorages.getAll()) {
+                pageCount += 
allocatedPageCountOnDisk(tableStorage.getTableId(), 
partitionStorage.partitionId());
+            }
+        }
+
+        return pageCount * pageSize;
+    }
+
+    private long totalNonEmptyAllocatedPagesSizeOnDiskInBytes() {
+        long pageCount = 0;
+
+        for (PersistentPageMemoryTableStorage tableStorage : tableStorages) {
+            for (PersistentPageMemoryMvPartitionStorage partitionStorage : 
tableStorage.mvPartitionStorages.getAll()) {
+                pageCount += 
allocatedPageCountOnDisk(tableStorage.getTableId(), 
partitionStorage.partitionId());
+
+                pageCount -= partitionStorage.emptyDataPageCountInFreeList();
+            }
+        }
+
+        return pageCount * pageSize;
+    }
+
+    private long allocatedPageCountOnDisk(int tableId, int partitionId) {
+        FilePageStore store = filePageStoreManager.getStore(new 
GroupPartitionId(tableId, partitionId));
+
+        return store == null ? 0 : store.pages();
+    }
 }
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
index 8312b58d5bc..e297713a0c4 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
@@ -280,7 +280,7 @@ public class PersistentPageMemoryStorageEngine extends 
AbstractPageMemoryStorage
 
         assert dataRegion != null : "tableId=" + tableDescriptor.getId() + ", 
dataRegion=" + tableDescriptor.getStorageProfile();
 
-        return new PersistentPageMemoryTableStorage(
+        var tableStorage = new PersistentPageMemoryTableStorage(
                 tableDescriptor,
                 indexDescriptorSupplier,
                 this,
@@ -288,6 +288,10 @@ public class PersistentPageMemoryStorageEngine extends 
AbstractPageMemoryStorage
                 destructionExecutor,
                 failureManager
         );
+
+        dataRegion.addTableStorage(tableStorage);
+
+        return tableStorage;
     }
 
     @Override
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
index 97390ad496c..dd052d1bffc 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
@@ -50,7 +50,7 @@ import org.jetbrains.annotations.Nullable;
 /**
  * Implementation of {@link AbstractPageMemoryTableStorage} for persistent 
case.
  */
-public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableStorage {
+public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableStorage<PersistentPageMemoryMvPartitionStorage> {
     /** Storage engine instance. */
     private final PersistentPageMemoryStorageEngine engine;
 
@@ -466,4 +466,9 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
             );
         }
     }
+
+    @Override
+    protected void beforeCloseOrDestroy() {
+        dataRegion.removeTableStorage(this);
+    }
 }
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
index 19704aa7c0d..5dec337b499 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
@@ -37,7 +37,7 @@ import 
org.apache.ignite.internal.storage.pagememory.mv.gc.GcQueue;
 /**
  * Implementation of {@link AbstractPageMemoryTableStorage} for in-memory case.
  */
-public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStorage {
+public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStorage<VolatilePageMemoryMvPartitionStorage> {
     private final VolatilePageMemoryStorageEngine engine;
 
     private final VolatilePageMemoryDataRegion dataRegion;
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
index ce1a4583408..30616c563c3 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
@@ -556,4 +556,8 @@ public class PersistentPageMemoryMvPartitionStorage extends 
AbstractPageMemoryMv
     public void decrementEstimatedSize() {
         updateMeta((lastCheckpointId, meta) -> 
meta.decrementEstimatedSize(lastCheckpointId));
     }
+
+    public int emptyDataPageCountInFreeList() {
+        return renewableState.freeList().emptyDataPages();
+    }
 }

Reply via email to