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

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


The following commit(s) were added to refs/heads/main by this push:
     new 22624571d4 IGNITE-22505 Reuse pages where possible (#3933)
22624571d4 is described below

commit 22624571d499ba10a26ef3456868dbf6c03b2a73
Author: Phillippko <[email protected]>
AuthorDate: Tue Jun 18 12:10:10 2024 +0400

    IGNITE-22505 Reuse pages where possible (#3933)
---
 .../tree/AbstractBplusTreePageMemoryTest.java      |  2 +-
 .../tree/ItBplusTreeReplaceRemoveRaceTest.java     |  2 +-
 .../internal/pagememory/PageIdAllocator.java       | 89 +++++++++++++++++++++-
 .../pagememory/datastructure/DataStructure.java    | 47 +-----------
 .../internal/pagememory/freelist/FreeListImpl.java |  2 +-
 .../pagememory/inmemory/VolatilePageMemory.java    | 20 +----
 .../pagememory/mem/IgniteOutOfMemoryException.java |  2 +-
 .../persistence/PersistentPageMemory.java          |  2 +-
 .../pagememory/freelist/FreeListImplTest.java      |  2 +-
 .../AbstractPageMemoryNoLoadSelfTest.java          |  2 +-
 .../PersistentPageMemoryTableStorage.java          |  8 +-
 .../pagememory/VolatilePageMemoryDataRegion.java   |  2 +-
 .../pagememory/VolatilePageMemoryTableStorage.java | 10 +--
 .../storage/pagememory/mv/IndexStorageFactory.java |  2 +-
 .../VolatilePageMemoryMvTableStorageTest.java      | 13 ++++
 .../storage/pagememory/mv/BlobStorageTest.java     |  8 +-
 16 files changed, 126 insertions(+), 87 deletions(-)

diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
index d89d0875d9..a0f77f5bc4 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
@@ -2713,7 +2713,7 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
     }
 
     private FullPageId allocateMetaPage() throws Exception {
-        return new FullPageId(pageMem.allocatePage(GROUP_ID, 0, FLAG_AUX), 
GROUP_ID);
+        return new FullPageId(pageMem.allocatePage(reuseList, GROUP_ID, 0, 
FLAG_AUX), GROUP_ID);
     }
 
     /**
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
index fffa0d028d..39493bdf22 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
@@ -108,7 +108,7 @@ public class ItBplusTreeReplaceRemoveRaceTest extends 
BaseIgniteAbstractTest {
     }
 
     private FullPageId allocateMetaPage() throws 
IgniteInternalCheckedException {
-        return new FullPageId(pageMem.allocatePage(GROUP_ID, 0, FLAG_AUX), 
GROUP_ID);
+        return new FullPageId(pageMem.allocatePageNoReuse(GROUP_ID, 0, 
FLAG_AUX), GROUP_ID);
     }
 
     /**
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/PageIdAllocator.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/PageIdAllocator.java
index 3c88cf14e5..0f062a91bd 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/PageIdAllocator.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/PageIdAllocator.java
@@ -17,7 +17,16 @@
 
 package org.apache.ignite.internal.pagememory;
 
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.flag;
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.itemId;
+import static 
org.apache.ignite.internal.pagememory.util.PageIdUtils.partitionId;
+import static 
org.apache.ignite.internal.pagememory.util.PageIdUtils.toDetailString;
+
 import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
+import org.apache.ignite.internal.pagememory.reuse.ReuseBag;
+import org.apache.ignite.internal.pagememory.reuse.ReuseList;
+import org.apache.ignite.internal.pagememory.util.PageIdUtils;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Class responsible for allocating/freeing page IDs.
@@ -39,14 +48,92 @@ public interface PageIdAllocator {
     // TODO IGNITE-16350 Use constant from the table configuration.
     int MAX_PARTITION_ID = 65500;
 
+    /**
+     * Allocates a page from the space for the given partition ID and the 
given flags. Does not reuse pages.
+     *
+     * @param groupId Group ID.
+     * @param partitionId Partition ID.
+     * @return Allocated page ID.
+     */
+    long allocatePageNoReuse(int groupId, int partitionId, byte flags) throws 
IgniteInternalCheckedException;
+
+    /**
+     * Allocates a page from the space for the given partition ID and the 
given flags. If reuse list is provided, tries to reuse page.
+     *
+     * @param reuseList Reuse list to reuse pages from.
+     * @param groupId Group ID.
+     * @param partitionId Partition ID.
+     * @return Allocated page ID.
+     */
+    default long allocatePage(@Nullable ReuseList reuseList, int groupId, int 
partitionId, byte flags)
+            throws IgniteInternalCheckedException {
+        return allocatePage(reuseList, null, true, groupId, partitionId, 
flags);
+    }
+
     /**
      * Allocates a page from the space for the given partition ID and the 
given flags.
      *
+     * @param reuseList Reuse list to reuse pages from.
+     * @param bag Reuse Bag.
+     * @param useRecycled Use recycled page.
      * @param groupId Group ID.
      * @param partitionId Partition ID.
      * @return Allocated page ID.
      */
-    long allocatePage(int groupId, int partitionId, byte flags) throws 
IgniteInternalCheckedException;
+    default long allocatePage(
+            @Nullable ReuseList reuseList,
+            @Nullable ReuseBag bag,
+            boolean useRecycled,
+            int groupId,
+            int partitionId,
+            byte flags
+    ) throws IgniteInternalCheckedException {
+        long pageId = 0;
+
+        if (useRecycled && reuseList != null) {
+            pageId = bag != null ? bag.pollFreePage() : 0;
+
+            if (pageId == 0) {
+                pageId = reuseList.takeRecycledPage();
+            }
+
+            // Recycled. "pollFreePage" result should be reinitialized to move 
rotatedId to itemId.
+            if (pageId != 0) {
+                // Replace the partition ID, because the reused page might 
have come from a different data structure if the reuse
+                // list is shared between them.
+                pageId = replacePartitionId(pageId, partitionId);
+
+                pageId = reuseList.initRecycledPage(pageId, flags, null);
+            }
+        }
+
+        if (pageId == 0) {
+            pageId = allocatePageNoReuse(groupId, partitionId, flags);
+        }
+
+        assert pageId != 0;
+
+        assert partitionId(pageId) >= 0 && partitionId(pageId) <= 
MAX_PARTITION_ID : toDetailString(pageId);
+
+        assert flag(pageId) != FLAG_DATA || itemId(pageId) == 0 : 
toDetailString(pageId);
+
+        return pageId;
+    }
+
+    /**
+     * Replaces the "partition ID" part of the given page ID with given 
partition ID.
+     *
+     * @param pageId Original page ID.
+     * @param partId Partition id to replace with.
+     * @return Page ID with replaced partition ID.
+     */
+    private static long replacePartitionId(long pageId, int partId) {
+        long partitionIdZeroMask = ~(PageIdUtils.PART_ID_MASK << 
PageIdUtils.PAGE_IDX_SIZE);
+
+        long partitionIdMask = ((long) partId) << PageIdUtils.PAGE_IDX_SIZE;
+
+        return pageId & partitionIdZeroMask | partitionIdMask;
+    }
 
     /**
      * Frees the given page.
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
index 5007a62081..b768a4f5c8 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
@@ -155,50 +155,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @throws IgniteInternalCheckedException If failed.
      */
     protected final long allocatePage(@Nullable ReuseBag bag, boolean 
useRecycled) throws IgniteInternalCheckedException {
-        long pageId = 0;
-
-        if (useRecycled && reuseList != null) {
-            pageId = bag != null ? bag.pollFreePage() : 0;
-
-            if (pageId == 0) {
-                pageId = reuseList.takeRecycledPage();
-            }
-
-            // Recycled. "pollFreePage" result should be reinitialized to move 
rotatedId to itemId.
-            if (pageId != 0) {
-                // Replace the partition ID, because the reused page might 
have come from a different data structure if the reuse
-                // list is shared between them.
-                pageId = replacePartitionId(pageId);
-
-                pageId = reuseList.initRecycledPage(pageId, defaultPageFlag, 
null);
-            }
-        }
-
-        if (pageId == 0) {
-            pageId = allocatePageNoReuse();
-        }
-
-        assert pageId != 0;
-
-        assert partitionId(pageId) >= 0 && partitionId(pageId) <= 
MAX_PARTITION_ID : toDetailString(pageId);
-
-        assert flag(pageId) != FLAG_DATA || itemId(pageId) == 0 : 
toDetailString(pageId);
-
-        return pageId;
-    }
-
-    /**
-     * Replaces the "partition ID" part of the given page ID with the 
partition ID that his data structure is responsible for.
-     *
-     * @param pageId Original page ID.
-     * @return Page ID with replaced partition ID.
-     */
-    private long replacePartitionId(long pageId) {
-        long partitionIdZeroMask = ~(PageIdUtils.PART_ID_MASK << 
PageIdUtils.PAGE_IDX_SIZE);
-
-        long partitionIdMask = ((long) partId) << PageIdUtils.PAGE_IDX_SIZE;
-
-        return pageId & partitionIdZeroMask | partitionIdMask;
+        return pageMem.allocatePage(reuseList, bag, useRecycled, grpId, 
partId, defaultPageFlag);
     }
 
     /**
@@ -208,7 +165,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @throws IgniteInternalCheckedException If failed.
      */
     protected long allocatePageNoReuse() throws IgniteInternalCheckedException 
{
-        return pageMem.allocatePage(grpId, partId, defaultPageFlag);
+        return pageMem.allocatePageNoReuse(grpId, partId, defaultPageFlag);
     }
 
     /**
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
index e812f2272c..f89222d727 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
@@ -489,7 +489,7 @@ public class FreeListImpl extends PagesList implements 
FreeList, ReuseList {
     private long allocateDataPage(int part) throws 
IgniteInternalCheckedException {
         assert part <= PageIdAllocator.MAX_PARTITION_ID;
 
-        return pageMem.allocatePage(grpId, part, FLAG_DATA);
+        return pageMem.allocatePage(reuseList, grpId, part, FLAG_DATA);
     }
 
     @Override
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
index 81e90d88c5..240e3e354b 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
@@ -268,13 +268,11 @@ public class VolatilePageMemory implements PageMemory {
         }
     }
 
-    /** {@inheritDoc} */
     @Override public ByteBuffer pageBuffer(long pageAddr) {
         return wrapPointer(pageAddr, pageSize());
     }
 
-    /** {@inheritDoc} */
-    @Override public long allocatePage(int grpId, int partId, byte flags) {
+    @Override public long allocatePageNoReuse(int grpId, int partId, byte 
flags) {
         assert started;
 
         long relPtr = borrowFreePage();
@@ -335,7 +333,6 @@ public class VolatilePageMemory implements PageMemory {
         return pageId;
     }
 
-    /** {@inheritDoc} */
     @Override public boolean freePage(int grpId, long pageId) {
         assert started;
 
@@ -344,22 +341,18 @@ public class VolatilePageMemory implements PageMemory {
         return true;
     }
 
-    /** {@inheritDoc} */
     @Override public int pageSize() {
         return sysPageSize - PAGE_OVERHEAD;
     }
 
-    /** {@inheritDoc} */
     @Override public int systemPageSize() {
         return sysPageSize;
     }
 
-    /** {@inheritDoc} */
     @Override public int realPageSize(int grpId) {
         return pageSize();
     }
 
-    /** {@inheritDoc} */
     @Override public long loadedPages() {
         return allocatedPages.get();
     }
@@ -444,12 +437,10 @@ public class VolatilePageMemory implements PageMemory {
 
     // *** PageSupport methods ***
 
-    /** {@inheritDoc} */
     @Override public long acquirePage(int cacheId, long pageId) {
         return acquirePage(cacheId, pageId, IoStatisticsHolderNoOp.INSTANCE);
     }
 
-    /** {@inheritDoc} */
     @Override public long acquirePage(int cacheId, long pageId, 
IoStatisticsHolder statHolder) {
         assert started;
 
@@ -464,7 +455,6 @@ public class VolatilePageMemory implements PageMemory {
         return absPtr;
     }
 
-    /** {@inheritDoc} */
     @Override public void releasePage(int cacheId, long pageId, long page) {
         assert started;
 
@@ -475,7 +465,6 @@ public class VolatilePageMemory implements PageMemory {
         }
     }
 
-    /** {@inheritDoc} */
     @Override public long readLock(int cacheId, long pageId, long page) {
         assert started;
 
@@ -486,7 +475,6 @@ public class VolatilePageMemory implements PageMemory {
         return 0L;
     }
 
-    /** {@inheritDoc} */
     @Override public long readLockForce(int cacheId, long pageId, long page) {
         assert started;
 
@@ -497,14 +485,12 @@ public class VolatilePageMemory implements PageMemory {
         return 0L;
     }
 
-    /** {@inheritDoc} */
     @Override public void readUnlock(int cacheId, long pageId, long page) {
         assert started;
 
         rwLock.readUnlock(page + LOCK_OFFSET);
     }
 
-    /** {@inheritDoc} */
     @Override public long writeLock(int cacheId, long pageId, long page) {
         assert started;
 
@@ -515,7 +501,6 @@ public class VolatilePageMemory implements PageMemory {
         return 0L;
     }
 
-    /** {@inheritDoc} */
     @Override public long tryWriteLock(int cacheId, long pageId, long page) {
         assert started;
 
@@ -526,7 +511,6 @@ public class VolatilePageMemory implements PageMemory {
         return 0L;
     }
 
-    /** {@inheritDoc} */
     @Override
     public void writeUnlock(
             int cacheId,
@@ -541,13 +525,11 @@ public class VolatilePageMemory implements PageMemory {
         rwLock.writeUnlock(page + LOCK_OFFSET, PageIdUtils.tag(actualId));
     }
 
-    /** {@inheritDoc} */
     @Override public boolean isDirty(int cacheId, long pageId, long page) {
         // always false for page no store.
         return false;
     }
 
-    /** {@inheritDoc} */
     @Override
     public PageIoRegistry ioRegistry() {
         return ioRegistry;
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/mem/IgniteOutOfMemoryException.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/mem/IgniteOutOfMemoryException.java
index fe245fc614..cb885b21c6 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/mem/IgniteOutOfMemoryException.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/mem/IgniteOutOfMemoryException.java
@@ -24,7 +24,7 @@ import org.apache.ignite.internal.pagememory.PageMemory;
 /**
  * Exception that signifies that there's no more available page in the data 
region.
  *
- * @see PageMemory#allocatePage(int, int, byte)
+ * @see PageMemory#allocatePageNoReuse(int, int, byte)
  */
 public class IgniteOutOfMemoryException extends IgniteInternalException {
     /** Serial version uid. */
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 0e8af508e9..2b0230c51f 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
@@ -504,7 +504,7 @@ public class PersistentPageMemory implements PageMemory {
 
     /** {@inheritDoc} */
     @Override
-    public long allocatePage(int grpId, int partId, byte flags) throws 
IgniteInternalCheckedException {
+    public long allocatePageNoReuse(int grpId, int partId, byte flags) throws 
IgniteInternalCheckedException {
         assert partId >= 0 && partId <= MAX_PARTITION_ID : partId;
 
         assert started;
diff --git 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
index 6ce5889e12..5ce7ebfdbe 100644
--- 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
+++ 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
@@ -140,7 +140,7 @@ public class FreeListImplTest extends 
BaseIgniteAbstractTest {
 
         pageMemory.start();
 
-        long metaPageId = pageMemory.allocatePage(1, 1, FLAG_DATA);
+        long metaPageId = pageMemory.allocatePageNoReuse(1, 1, FLAG_DATA);
 
         return new FreeListImpl(
                 0,
diff --git 
a/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/AbstractPageMemoryNoLoadSelfTest.java
 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/AbstractPageMemoryNoLoadSelfTest.java
index b25e4bdd6b..862979673b 100644
--- 
a/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/AbstractPageMemoryNoLoadSelfTest.java
+++ 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/AbstractPageMemoryNoLoadSelfTest.java
@@ -346,6 +346,6 @@ public abstract class AbstractPageMemoryNoLoadSelfTest 
extends BaseIgniteAbstrac
      * @throws IgniteInternalCheckedException If failed.
      */
     public static FullPageId allocatePage(PageIdAllocator mem) throws 
IgniteInternalCheckedException {
-        return new FullPageId(mem.allocatePage(GRP_ID, PARTITION_ID, 
PageIdAllocator.FLAG_DATA), GRP_ID);
+        return new FullPageId(mem.allocatePageNoReuse(GRP_ID, PARTITION_ID, 
PageIdAllocator.FLAG_DATA), GRP_ID);
     }
 }
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 9c56ab04bb..930c614cc0 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
@@ -164,7 +164,7 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
             boolean initNew = false;
 
             if (meta.freeListRootPageId() == 0) {
-                long rootPageId = pageMemory.allocatePage(getTableId(), 
partId, FLAG_AUX);
+                long rootPageId = pageMemory.allocatePageNoReuse(getTableId(), 
partId, FLAG_AUX);
 
                 meta.freeListRootPageId(lastCheckpointId(), rootPageId);
 
@@ -207,7 +207,7 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
             boolean initNew = false;
 
             if (meta.versionChainTreeRootPageId() == 0) {
-                long rootPageId = pageMemory.allocatePage(getTableId(), 
partId, FLAG_AUX);
+                long rootPageId = pageMemory.allocatePage(reuseList, 
getTableId(), partId, FLAG_AUX);
 
                 meta.versionChainTreeRootPageId(lastCheckpointId(), 
rootPageId);
 
@@ -249,7 +249,7 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
             boolean initNew = false;
 
             if (meta.indexTreeMetaPageId() == 0) {
-                long rootPageId = pageMemory.allocatePage(getTableId(), 
partitionId, FLAG_AUX);
+                long rootPageId = pageMemory.allocatePage(reuseList, 
getTableId(), partitionId, FLAG_AUX);
 
                 meta.indexTreeMetaPageId(lastCheckpointId(), rootPageId);
 
@@ -291,7 +291,7 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
             boolean initNew = false;
 
             if (meta.gcQueueMetaPageId() == 0) {
-                long rootPageId = pageMemory.allocatePage(getTableId(), 
partitionId, FLAG_AUX);
+                long rootPageId = pageMemory.allocatePage(reuseList, 
getTableId(), partitionId, FLAG_AUX);
 
                 meta.gcQueueMetaPageId(lastCheckpointId(), rootPageId);
 
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
index d84622c640..0133c4f293 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
@@ -89,7 +89,7 @@ public class VolatilePageMemoryDataRegion implements 
DataRegion<VolatilePageMemo
     private FreeListImpl createFreeList(
             PageMemory pageMemory
     ) throws IgniteInternalCheckedException {
-        long metaPageId = pageMemory.allocatePage(FREE_LIST_GROUP_ID, 
FREE_LIST_PARTITION_ID, FLAG_AUX);
+        long metaPageId = pageMemory.allocatePageNoReuse(FREE_LIST_GROUP_ID, 
FREE_LIST_PARTITION_ID, FLAG_AUX);
 
         return new FreeListImpl(
                 FREE_LIST_GROUP_ID,
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 4da30fa12f..f9e717c77b 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
@@ -86,9 +86,9 @@ public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStora
     }
 
     private IndexMetaTree createIndexMetaTree(int partitionId) {
-        long metaPageId = dataRegion.pageMemory().allocatePage(getTableId(), 
partitionId, FLAG_AUX);
-
         try {
+            long metaPageId = 
dataRegion.pageMemory().allocatePage(dataRegion.reuseList(), getTableId(), 
partitionId, FLAG_AUX);
+
             return new IndexMetaTree(
                     getTableId(),
                     Integer.toString(getTableId()),
@@ -106,9 +106,9 @@ public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStora
     }
 
     private GcQueue createGarbageCollectionTree(int partitionId) {
-        long metaPageId = dataRegion.pageMemory().allocatePage(getTableId(), 
partitionId, FLAG_AUX);
-
         try {
+            long metaPageId = 
dataRegion.pageMemory().allocatePage(dataRegion().reuseList(), getTableId(), 
partitionId, FLAG_AUX);
+
             return new GcQueue(
                     getTableId(),
                     Integer.toString(getTableId()),
@@ -143,7 +143,7 @@ public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStora
      */
     private VersionChainTree createVersionChainTree(int partId) throws 
StorageException {
         try {
-            long metaPageId = 
dataRegion.pageMemory().allocatePage(getTableId(), partId, FLAG_AUX);
+            long metaPageId = 
dataRegion.pageMemory().allocatePage(dataRegion().reuseList(), getTableId(), 
partId, FLAG_AUX);
 
             return new VersionChainTree(
                     getTableId(),
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
index b239c6c4ea..f47183a360 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
@@ -274,7 +274,7 @@ class IndexStorageFactory {
         try {
             PageMemory pageMemory = tableStorage.dataRegion().pageMemory();
 
-            long metaPageId = 
pageMemory.allocatePage(tableStorage.getTableId(), partitionId, 
PageIdAllocator.FLAG_AUX);
+            long metaPageId = pageMemory.allocatePage(freeList, 
tableStorage.getTableId(), partitionId, PageIdAllocator.FLAG_AUX);
 
             T tree = treeConstructor.createTree(metaPageId);
 
diff --git 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryMvTableStorageTest.java
 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryMvTableStorageTest.java
index fc2e96c61f..21478b0f53 100644
--- 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryMvTableStorageTest.java
+++ 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryMvTableStorageTest.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.storage.pagememory;
 import static 
org.apache.ignite.internal.catalog.CatalogService.DEFAULT_STORAGE_PROFILE;
 import static 
org.apache.ignite.internal.catalog.commands.CatalogUtils.DEFAULT_PARTITION_COUNT;
 import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.waitForCondition;
+import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willSucceedFast;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -222,6 +223,18 @@ public class VolatilePageMemoryMvTableStorageTest extends 
AbstractMvTableStorage
         assertIndexDataDestructionCompletes(emptyIndexPagesBeforeDestroy);
     }
 
+    @Test
+    public void testDestroyTablesNoLeakages() {
+        int limit = 100000;
+        for (int i = 1; i < limit; i++) {
+            MvTableStorage mvTableStorage = createMvTableStorage();
+
+            getOrCreateMvPartition(mvTableStorage, PARTITION_ID);
+
+            assertThat(mvTableStorage.destroy(), willCompleteSuccessfully());
+        }
+    }
+
     private VolatilePageMemoryDataRegion dataRegion() {
         return ((VolatilePageMemoryTableStorage) tableStorage).dataRegion();
     }
diff --git 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
index 8c44c07298..dfaf676108 100644
--- 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
+++ 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
@@ -98,7 +98,7 @@ class BlobStorageTest extends BaseIgniteAbstractTest {
     void allocatesOnlyRequiredNumberOfPages() throws Exception {
         blobStorage.addBlob(new byte[(int) (PAGE_SIZE * 1.5)]);
 
-        verify(pageMemory, times(2)).allocatePage(anyInt(), anyInt(), 
anyByte());
+        verify(pageMemory, times(2)).allocatePageNoReuse(anyInt(), anyInt(), 
anyByte());
     }
 
     @Test
@@ -107,7 +107,7 @@ class BlobStorageTest extends BaseIgniteAbstractTest {
 
         blobStorage.updateBlob(pageId, new byte[(int) (PAGE_SIZE * 2.5)]);
 
-        verify(pageMemory, times(3)).allocatePage(anyInt(), anyInt(), 
anyByte());
+        verify(pageMemory, times(3)).allocatePageNoReuse(anyInt(), anyInt(), 
anyByte());
     }
 
     @Test
@@ -116,7 +116,7 @@ class BlobStorageTest extends BaseIgniteAbstractTest {
 
         blobStorage.updateBlob(pageId, new byte[(int) (PAGE_SIZE * 0.5)]);
 
-        verify(pageMemory, times(2)).allocatePage(anyInt(), anyInt(), 
anyByte());
+        verify(pageMemory, times(2)).allocatePageNoReuse(anyInt(), anyInt(), 
anyByte());
     }
 
     @Test
@@ -162,7 +162,7 @@ class BlobStorageTest extends BaseIgniteAbstractTest {
 
         blobStorage.updateBlob(pageId, new byte[0]);
 
-        verify(pageMemory, times(3)).allocatePage(anyInt(), anyInt(), 
anyByte());
+        verify(pageMemory, times(3)).allocatePageNoReuse(anyInt(), anyInt(), 
anyByte());
 
         verify(reuseList).addForRecycle(reuseBagCaptor.capture());
 

Reply via email to