You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2022/06/28 08:37:58 UTC
[ignite] branch master updated: IGNITE-17181 Add free size calculation to index-reader (#10102)
This is an automated email from the ASF dual-hosted git repository.
nizhikov 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 2703c26e290 IGNITE-17181 Add free size calculation to index-reader (#10102)
2703c26e290 is described below
commit 2703c26e290c96dd2e771a2edd4e03e94d528038
Author: Nikolay <ni...@apache.org>
AuthorDate: Tue Jun 28 11:37:51 2022 +0300
IGNITE-17181 Add free size calculation to index-reader (#10102)
---
.../commandline/indexreader/IgniteIndexReader.java | 157 ++++++++-------
.../commandline/indexreader/PageListsInfo.java | 8 +-
.../commandline/indexreader/ScanContext.java | 36 +++-
.../indexreader/IgniteIndexReaderTest.java | 1 +
.../cache/persistence/freelist/PagesList.java | 2 +-
.../persistence/freelist/io/PagesListMetaIO.java | 11 +-
.../persistence/freelist/io/PagesListNodeIO.java | 17 +-
.../persistence/tree/io/AbstractDataPageIO.java | 11 +-
.../cache/persistence/tree/io/BPlusIO.java | 5 +
.../cache/persistence/tree/io/BPlusMetaIO.java | 13 +-
.../cache/persistence/tree/io/PageIO.java | 9 +
.../cache/persistence/tree/io/PageMetaIO.java | 5 +
.../tree/io/PagePartitionCountersIO.java | 7 +-
.../cache/persistence/tree/io/TrackingPageIO.java | 5 +
.../processors/cache/persistence/DummyPageIO.java | 5 +
.../persistence/tree/io/PageIOFreeSizeTest.java | 217 +++++++++++++++++++++
.../ignite/testsuites/IgnitePdsTestSuite5.java | 2 +
17 files changed, 404 insertions(+), 107 deletions(-)
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReader.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReader.java
index bfd51d1872a..b691972484e 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReader.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReader.java
@@ -18,12 +18,11 @@
package org.apache.ignite.internal.commandline.indexreader;
import java.io.File;
-import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -46,6 +45,7 @@ import org.apache.ignite.internal.cache.query.index.sorted.inline.io.InlineIO;
import org.apache.ignite.internal.commandline.CommandHandler;
import org.apache.ignite.internal.commandline.ProgressPrinter;
import org.apache.ignite.internal.commandline.argument.parser.CLIArgumentParser;
+import org.apache.ignite.internal.commandline.indexreader.ScanContext.PagesStatistic;
import org.apache.ignite.internal.commandline.systemview.SystemViewCommand;
import org.apache.ignite.internal.pagemem.PageIdAllocator;
import org.apache.ignite.internal.processors.cache.persistence.IndexStorageImpl;
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageP
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageMetaIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PagePartitionMetaIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.TrackingPageIO;
import org.apache.ignite.internal.processors.cache.persistence.wal.crc.IgniteDataIntegrityViolationException;
import org.apache.ignite.internal.processors.cache.tree.AbstractDataLeafIO;
import org.apache.ignite.internal.processors.cache.tree.PendingRowIO;
@@ -150,7 +151,7 @@ public class IgniteIndexReader implements AutoCloseable {
Pattern.compile("(?<id>[-0-9]{1,15})_.*");
/** */
- private static final int CHECK_PARTS_MAX_ERRORS_PER_PARTITION = 10;
+ private static final int MAX_ERRORS_CNT = 10;
static {
IndexProcessor.registerIO();
@@ -357,8 +358,6 @@ public class IgniteIndexReader implements AutoCloseable {
* @return Tree traversal context.
*/
ScanContext recursiveTreeScan(long rootPageId, String idx, ItemStorage items) {
- pageIds.add(normalizePageId(rootPageId));
-
ScanContext ctx = createContext(cacheAndTypeId(idx).get1(), filePageStore(rootPageId), items);
metaPageVisitor.readAndVisit(rootPageId, ctx);
@@ -375,8 +374,6 @@ public class IgniteIndexReader implements AutoCloseable {
* @return Tree traversal context.
*/
private ScanContext horizontalTreeScan(long rootPageId, String idx, ItemStorage items) {
- pageIds.add(normalizePageId(rootPageId));
-
ScanContext ctx = createContext(cacheAndTypeId(idx).get1(), filePageStore(rootPageId), items);
levelsPageVisitor.readAndVisit(rootPageId, ctx);
@@ -394,7 +391,7 @@ public class IgniteIndexReader implements AutoCloseable {
return doWithBuffer((buf, addr) -> {
Map<IgniteBiTuple<Long, Integer>, List<Long>> bucketsData = new HashMap<>();
- Map<Class<? extends PageIO>, Long> ioStat = new HashMap<>();
+ Map<Class<? extends PageIO>, PagesStatistic> stats = new HashMap<>();
Map<Long, List<String>> errors = new HashMap<>();
@@ -405,7 +402,7 @@ public class IgniteIndexReader implements AutoCloseable {
try {
PagesListMetaIO io = readPage(idxStore, currMetaPageId, buf);
- pageIds.add(normalizePageId(currMetaPageId));
+ ScanContext.addToStats(io, stats, 1, addr, idxStore.getPageSize());
Map<Integer, GridLongList> data = new HashMap<>();
@@ -419,7 +416,7 @@ public class IgniteIndexReader implements AutoCloseable {
for (Long listId : listIds) {
try {
- pagesCnt += visitPageList(listId, ioStat);
+ pagesCnt += visitPageList(listId, stats);
}
catch (Exception err) {
errors.put(listId, singletonList(err.getMessage()));
@@ -438,7 +435,7 @@ public class IgniteIndexReader implements AutoCloseable {
}
}
- return new PageListsInfo(bucketsData, pagesCnt, ioStat, errors);
+ return new PageListsInfo(bucketsData, pagesCnt, stats, errors);
});
}
@@ -446,10 +443,10 @@ public class IgniteIndexReader implements AutoCloseable {
* Visit single page list.
*
* @param listStartPageId Id of the start page of the page list.
- * @param ioStat Page types statistics.
+ * @param stats Page types statistics.
* @return List of page ids.
*/
- private long visitPageList(long listStartPageId, Map<Class<? extends PageIO>, Long> ioStat) throws IgniteCheckedException {
+ private long visitPageList(long listStartPageId, Map<Class<? extends PageIO>, PagesStatistic> stats) throws IgniteCheckedException {
return doWithBuffer((nodeBuf, nodeAddr) -> doWithBuffer((pageBuf, pageAddr) -> {
long res = 0;
@@ -458,18 +455,16 @@ public class IgniteIndexReader implements AutoCloseable {
while (currPageId != 0) {
PagesListNodeIO io = readPage(idxStore, currPageId, nodeBuf);
- ScanContext.onPageIO(readPage(idxStore, currPageId, pageBuf).getClass(), ioStat, 1);
+ ScanContext.addToStats(io, stats, 1, nodeAddr, idxStore.getPageSize());
- pageIds.add(normalizePageId(normalizePageId(currPageId)));
+ ScanContext.addToStats(readPage(idxStore, currPageId, pageBuf), stats, 1, pageAddr, idxStore.getPageSize());
res += io.getCount(nodeAddr);
for (int i = 0; i < io.getCount(nodeAddr); i++) {
long pageId = normalizePageId(io.getAt(nodeAddr, i));
- pageIds.add(pageId);
-
- ScanContext.onPageIO(readPage(idxStore, pageId, pageBuf).getClass(), ioStat, 1);
+ ScanContext.addToStats(readPage(idxStore, pageId, pageBuf), stats, 1, pageAddr, idxStore.getPageSize());
}
currPageId = io.getNextId(nodeAddr);
@@ -499,17 +494,14 @@ public class IgniteIndexReader implements AutoCloseable {
try {
pageId = pageId(INDEX_PARTITION, FLAG_IDX, i);
- PageIO io = readPage(ctx, pageId, buf);
+ PageIO io = readPage(ctx, pageId, buf, false);
progressPrinter.printProgress();
if (idxFilter != null)
continue;
- if (io instanceof PageMetaIO || io instanceof PagesListMetaIO)
- continue;
-
- if (!((io instanceof BPlusMetaIO || io instanceof BPlusInnerIO)))
+ if (io instanceof TrackingPageIO)
continue;
if (pageIds.contains(normalizePageId(pageId)))
@@ -589,8 +581,8 @@ public class IgniteIndexReader implements AutoCloseable {
", link=" + cacheAwareLink.link + ']');
}
- if (errors.size() >= CHECK_PARTS_MAX_ERRORS_PER_PARTITION) {
- errors.add("Too many errors (" + CHECK_PARTS_MAX_ERRORS_PER_PARTITION +
+ if (errors.size() >= MAX_ERRORS_CNT) {
+ errors.add("Too many errors (" + MAX_ERRORS_CNT +
") found for partId=" + partId + ", stopping analysis for this partition.");
break;
@@ -684,49 +676,41 @@ public class IgniteIndexReader implements AutoCloseable {
return partId == INDEX_PARTITION ? idxStore : partStores[partId];
}
- /**
- * Reading a page from channel into buffer.
- *
- * @param buf Buffer.
- * @param ch Source for reading pages.
- * @param pageSize Size of page to read into buffer.
- */
- private boolean readNextPage(ByteBuffer buf, FileChannel ch, int pageSize) throws IOException {
- assert buf.remaining() == pageSize;
-
- do {
- if (ch.read(buf) == -1)
- break;
- }
- while (buf.hasRemaining());
-
- if (!buf.hasRemaining() && PageIO.getPageId(buf) != 0)
- return true; //pageSize bytes read && pageId != 0
- else if (buf.remaining() == pageSize)
- return false; //0 bytes read
- else
- // 1 <= readBytes < pageSize || readBytes == pagesIze && pageId != 0
- throw new IgniteException("Corrupted page in partitionId " +
- ", readByte=" + buf.position() + ", pageSize=" + pageSize);
- }
-
/** */
static long normalizePageId(long pageId) {
return pageId(partId(pageId), flag(pageId), pageIndex(pageId));
}
+ /** */
+ private <I extends PageIO> I readPage(FilePageStore store, long pageId, ByteBuffer buf) throws IgniteCheckedException {
+ return readPage(store, pageId, buf, true);
+ }
+
/**
* Reads pages into buffer.
*
* @param store Source for reading pages.
* @param pageId Page ID.
* @param buf Buffer.
+ * @param addToPageIds If {@code true} then add page ID to global set.
*/
- private <I extends PageIO> I readPage(FilePageStore store, long pageId, ByteBuffer buf) throws IgniteCheckedException {
+ private <I extends PageIO> I readPage(
+ FilePageStore store,
+ long pageId,
+ ByteBuffer buf,
+ boolean addToPageIds
+ ) throws IgniteCheckedException {
try {
store.read(pageId, (ByteBuffer)buf.rewind(), false);
- return PageIO.getPageIO(bufferAddress(buf));
+ long addr = bufferAddress(buf);
+
+ if (store == idxStore && addToPageIds)
+ pageIds.add(normalizePageId(pageId));
+
+ I io = PageIO.getPageIO(addr);
+
+ return io;
}
catch (IgniteDataIntegrityViolationException | IllegalArgumentException e) {
// Replacing exception due to security reasons, as IgniteDataIntegrityViolationException prints page content.
@@ -738,9 +722,19 @@ public class IgniteIndexReader implements AutoCloseable {
/** */
protected <I extends PageIO> I readPage(ScanContext ctx, long pageId, ByteBuffer buf) throws IgniteCheckedException {
- final I io = readPage(ctx.store, pageId, buf);
+ return readPage(ctx, pageId, buf, true);
+ }
- ctx.onPageIO(io);
+ /** */
+ protected <I extends PageIO> I readPage(
+ ScanContext ctx,
+ long pageId,
+ ByteBuffer buf,
+ boolean addToPageIds
+ ) throws IgniteCheckedException {
+ final I io = readPage(ctx.store, pageId, buf, addToPageIds);
+
+ ctx.addToStats(io, bufferAddress(buf));
return io;
}
@@ -785,16 +779,16 @@ public class IgniteIndexReader implements AutoCloseable {
if (rctx.items.size() != hctx.items.size())
errors.add(compareError("items", name, rctx.items.size(), hctx.items.size(), null));
- rctx.ioStat.forEach((cls, cnt) -> {
- long scanCnt = hctx.ioStat.getOrDefault(cls, 0L);
+ rctx.stats.forEach((cls, stat) -> {
+ long scanCnt = hctx.stats.getOrDefault(cls, new PagesStatistic()).cnt;
- if (scanCnt != cnt)
- errors.add(compareError("pages", name, cnt, scanCnt, cls));
+ if (scanCnt != stat.cnt)
+ errors.add(compareError("pages", name, stat.cnt, scanCnt, cls));
});
- hctx.ioStat.forEach((cls, cnt) -> {
- if (!rctx.ioStat.containsKey(cls))
- errors.add(compareError("pages", name, 0, cnt, cls));
+ hctx.stats.forEach((cls, stat) -> {
+ if (!rctx.stats.containsKey(cls))
+ errors.add(compareError("pages", name, 0, stat.cnt, cls));
});
});
@@ -812,7 +806,7 @@ public class IgniteIndexReader implements AutoCloseable {
/** Prints sequential file scan results. */
private void printSequentialScanInfo(ScanContext ctx) {
- printIoStat("", "---- These pages types were encountered during sequential scan:", ctx.ioStat);
+ printIoStat("", "---- These pages types were encountered during sequential scan:", ctx.stats);
if (!ctx.errors.isEmpty()) {
log.severe("----");
@@ -827,7 +821,7 @@ public class IgniteIndexReader implements AutoCloseable {
null,
Arrays.asList(STRING, NUMBER),
Arrays.asList(
- Arrays.asList("Total pages encountered during sequential scan:", ctx.ioStat.values().stream().mapToLong(a -> a).sum()),
+ Arrays.asList("Total pages encountered during sequential scan:", ctx.stats.values().stream().mapToLong(a -> a.cnt).sum()),
Arrays.asList("Total errors occurred during sequential scan: ", ctx.errors.size())
),
log
@@ -861,7 +855,7 @@ public class IgniteIndexReader implements AutoCloseable {
private void printScanResults(String prefix, Map<String, ScanContext> ctxs) {
log.info(prefix + "Tree traversal results");
- Map<Class<? extends PageIO>, Long> ioStat = new HashMap<>();
+ Map<Class<? extends PageIO>, PagesStatistic> stats = new HashMap<>();
int totalErr = 0;
@@ -874,9 +868,9 @@ public class IgniteIndexReader implements AutoCloseable {
log.info(prefix + "-----");
log.info(prefix + "Index tree: " + idxName);
- printIoStat(prefix, "---- Page stat:", ctx.ioStat);
+ printIoStat(prefix, "---- Page stat:", ctx.stats);
- ctx.ioStat.forEach((cls, cnt) -> ScanContext.onPageIO(cls, ioStat, cnt));
+ ctx.stats.forEach((cls, stat) -> ScanContext.addToStats(cls, stats, stat));
log.info(prefix + "---- Count of items found in leaf pages: " + ctx.items.size());
@@ -897,7 +891,7 @@ public class IgniteIndexReader implements AutoCloseable {
log.info(prefix + "----");
- printIoStat(prefix, "Total page stat collected during trees traversal:", ioStat);
+ printIoStat(prefix, "Total page stat collected during trees traversal:", stats);
log.info("");
@@ -928,7 +922,7 @@ public class IgniteIndexReader implements AutoCloseable {
Arrays.asList(STRING, NUMBER),
Arrays.asList(
Arrays.asList(prefix + "Total trees: ", ctxs.keySet().size()),
- Arrays.asList(prefix + "Total pages found in trees: ", ioStat.values().stream().mapToLong(a -> a).sum()),
+ Arrays.asList(prefix + "Total pages found in trees: ", stats.values().stream().mapToLong(a -> a.cnt).sum()),
Arrays.asList(prefix + "Total errors during trees traversal: ", totalErr)
),
log
@@ -970,7 +964,7 @@ public class IgniteIndexReader implements AutoCloseable {
log.info(sb.toString());
});
- printIoStat(PAGE_LISTS_PREFIX, "---- Page stat:", pageListsInfo.ioStat);
+ printIoStat(PAGE_LISTS_PREFIX, "---- Page stat:", pageListsInfo.stats);
printErrors(PAGE_LISTS_PREFIX, "---- Errors:", "---- No errors.", "Page id: %s, exception: ", pageListsInfo.errors);
@@ -1020,20 +1014,27 @@ public class IgniteIndexReader implements AutoCloseable {
}
/** */
- private void printIoStat(String prefix, String caption, Map<Class<? extends PageIO>, Long> ioStat) {
+ private void printIoStat(String prefix, String caption, Map<Class<? extends PageIO>, PagesStatistic> stats) {
if (caption != null)
- log.info(prefix + caption + (ioStat.isEmpty() ? " empty" : ""));
+ log.info(prefix + caption + (stats.isEmpty() ? " empty" : ""));
- if (ioStat.isEmpty())
+ if (stats.isEmpty())
return;
- List<List<?>> data = new ArrayList<>(ioStat.size());
+ List<List<?>> data = new ArrayList<>(stats.size());
+
+ stats.forEach((cls, stat) -> data.add(Arrays.asList(
+ prefix + cls.getSimpleName(),
+ stat.cnt,
+ String.format("%.2f", ((double)stat.freeSpace) / U.KB),
+ String.format("%.2f", (stat.freeSpace * 100.0d) / (pageSize * stat.cnt))
+ )));
- ioStat.forEach((cls, cnt) -> data.add(Arrays.asList(prefix + cls.getSimpleName(), cnt)));
+ Collections.sort(data, Comparator.comparingLong(l -> (Long)l.get(1)));
SystemViewCommand.printTable(
- null,
- Arrays.asList(STRING, NUMBER),
+ Arrays.asList(prefix + "Type", "Pages", "Free space (Kb)", "Free space (%)"),
+ Arrays.asList(STRING, NUMBER, NUMBER, NUMBER),
data,
log
);
@@ -1141,8 +1142,6 @@ public class IgniteIndexReader implements AutoCloseable {
public void visit(long addr, ScanContext ctx) throws IgniteCheckedException {
BPlusInnerIO<?> io = PageIO.getPageIO(addr);
- pageIds.add(normalizePageId(PageIO.getPageId(addr)));
-
for (long id : children(io, addr))
readAndVisit(id, ctx);
}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/PageListsInfo.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/PageListsInfo.java
index 84d5cfc0f1f..2c7a94aca72 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/PageListsInfo.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/PageListsInfo.java
@@ -37,8 +37,8 @@ class PageListsInfo {
/** Found pages count. */
final long pagesCnt;
- /** Page type statistics. */
- final Map<Class<? extends PageIO>, Long> ioStat;
+ /** Pages statistics. */
+ final Map<Class<? extends PageIO>, ScanContext.PagesStatistic> stats;
/** Map of errors, pageId -> list of exceptions. */
final Map<Long, List<String>> errors;
@@ -47,12 +47,12 @@ class PageListsInfo {
public PageListsInfo(
Map<IgniteBiTuple<Long, Integer>, List<Long>> bucketsData,
long pagesCnt,
- Map<Class<? extends PageIO>, Long> ioStat,
+ Map<Class<? extends PageIO>, ScanContext.PagesStatistic> stats,
Map<Long, List<String>> errors
) {
this.bucketsData = bucketsData;
this.pagesCnt = pagesCnt;
- this.ioStat = ioStat;
+ this.stats = stats;
this.errors = errors;
}
}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/ScanContext.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/ScanContext.java
index c06f43a03bd..bb1ef520533 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/ScanContext.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/indexreader/ScanContext.java
@@ -35,7 +35,7 @@ class ScanContext {
final FilePageStore store;
/** Page type statistics. */
- final Map<Class<? extends PageIO>, Long> ioStat;
+ final Map<Class<? extends PageIO>, PagesStatistic> stats;
/** Map of errors, pageId -> set of exceptions. */
final Map<Long, List<String>> errors;
@@ -48,22 +48,46 @@ class ScanContext {
this.cacheId = cacheId;
this.store = store;
this.items = items;
- this.ioStat = new LinkedHashMap<>();
+ this.stats = new LinkedHashMap<>();
this.errors = new LinkedHashMap<>();
}
/** */
- public void onPageIO(PageIO io) {
- onPageIO(io.getClass(), ioStat, 1);
+ public void addToStats(PageIO io, long addr) {
+ addToStats(io, stats, 1, addr, store.getPageSize());
}
/** */
- public static void onPageIO(Class<? extends PageIO> io, Map<Class<? extends PageIO>, Long> ioStat, long cnt) {
- ioStat.compute(io, (k, v) -> v == null ? cnt : v + cnt);
+ public static void addToStats(PageIO io, Map<Class<? extends PageIO>, PagesStatistic> stats, long cnt, long addr, int pageSize) {
+ PagesStatistic stat = stats.computeIfAbsent(io.getClass(), k -> new PagesStatistic());
+
+ stat.cnt += cnt;
+ stat.freeSpace += io.getFreeSpace(pageSize, addr);
+ }
+
+ /** */
+ public static void addToStats(
+ Class<? extends PageIO> io,
+ Map<Class<? extends PageIO>, PagesStatistic> stats,
+ PagesStatistic toAdd
+ ) {
+ PagesStatistic stat = stats.computeIfAbsent(io, k -> new PagesStatistic());
+
+ stat.cnt += toAdd.cnt;
+ stat.freeSpace += toAdd.freeSpace;
}
/** */
public void onLeafPage(long pageId, List<Object> data) {
data.forEach(items::add);
}
+
+ /** */
+ static class PagesStatistic {
+ /** Count of pages. */
+ long cnt;
+
+ /** Summary free space. */
+ long freeSpace;
+ }
}
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReaderTest.java b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReaderTest.java
index 0b6358337f3..f6d78008a58 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReaderTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/indexreader/IgniteIndexReaderTest.java
@@ -129,6 +129,7 @@ public class IgniteIndexReaderTest extends GridCommandHandlerAbstractTest {
private static final String CHECK_IDX_PTRN_COMMON =
"<PREFIX>Index tree: I \\[idxName=[\\-_0-9]{1,20}_%s##H2Tree.0, pageId=[0-9a-f]{16}\\]" +
LINE_DELIM + "<PREFIX>---- Page stat:" +
+ LINE_DELIM + "<PREFIX>Type.*Pages.*Free space.*" +
LINE_DELIM + "<PREFIX>([0-9a-zA-Z]{1,50}.*[0-9]{1,5}" +
LINE_DELIM + "<PREFIX>){%s,1000}---- Count of items found in leaf pages: %s" +
LINE_DELIM;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
index 879ec667792..1d23fb321f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
@@ -2320,7 +2320,7 @@ public abstract class PagesList extends DataStructure {
* @param tailId Tail ID.
* @param empty Empty flag.
*/
- Stripe(long tailId, boolean empty) {
+ public Stripe(long tailId, boolean empty) {
this.tailId = tailId;
this.empty = empty;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListMetaIO.java
index 6c5507ae2ac..0fae24c6d3e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListMetaIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListMetaIO.java
@@ -39,10 +39,10 @@ public class PagesListMetaIO extends PageIO {
private static final int NEXT_META_PAGE_OFF = CNT_OFF + 2;
/** */
- private static final int ITEMS_OFF = NEXT_META_PAGE_OFF + 8;
+ public static final int ITEMS_OFF = NEXT_META_PAGE_OFF + 8;
/** */
- private static final int ITEM_SIZE = 10;
+ public static final int ITEM_SIZE = 10;
/** */
public static final IOVersions<PagesListMetaIO> VERSIONS = new IOVersions<>(
@@ -180,7 +180,7 @@ public class PagesListMetaIO extends PageIO {
* @param pageAddr Page address.
* @return Maximum number of items which can be stored in buffer.
*/
- private int getCapacity(int pageSize, long pageAddr) {
+ public int getCapacity(int pageSize, long pageAddr) {
return (pageSize - ITEMS_OFF) / ITEM_SIZE;
}
@@ -209,4 +209,9 @@ public class PagesListMetaIO extends PageIO {
sb.a("\n\t}\n]");
}
+
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return (getCapacity(pageSize, pageAddr) - getCount(pageAddr)) * ITEM_SIZE;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListNodeIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListNodeIO.java
index 42126dddede..a80651a2820 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListNodeIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/io/PagesListNodeIO.java
@@ -43,10 +43,10 @@ public class PagesListNodeIO extends PageIO implements CompactablePageIO {
private static final int PREV_PAGE_ID_OFF = COMMON_HEADER_END;
/** */
- private static final int NEXT_PAGE_ID_OFF = PREV_PAGE_ID_OFF + 8;
+ private static final int NEXT_PAGE_ID_OFF = PREV_PAGE_ID_OFF + Long.BYTES;
/** */
- private static final int CNT_OFF = NEXT_PAGE_ID_OFF + 8;
+ private static final int CNT_OFF = NEXT_PAGE_ID_OFF + Long.BYTES;
/** */
private static final int PAGE_IDS_OFF = CNT_OFF + 2;
@@ -140,8 +140,8 @@ public class PagesListNodeIO extends PageIO implements CompactablePageIO {
* @param pageSize Page size.
* @return Capacity of this page in items.
*/
- private int getCapacity(int pageSize) {
- return (pageSize - PAGE_IDS_OFF) >>> 3; // /8
+ public int getCapacity(int pageSize) {
+ return (pageSize - PAGE_IDS_OFF) / Long.BYTES;
}
/**
@@ -149,7 +149,7 @@ public class PagesListNodeIO extends PageIO implements CompactablePageIO {
* @return Item offset.
*/
private int offset(int idx) {
- return PAGE_IDS_OFF + 8 * idx;
+ return PAGE_IDS_OFF + Long.BYTES * idx;
}
/**
@@ -229,7 +229,7 @@ public class PagesListNodeIO extends PageIO implements CompactablePageIO {
for (int i = 0; i < cnt; i++) {
if (PageIdUtils.maskPartitionId(getAt(pageAddr, i)) == PageIdUtils.maskPartitionId(dataPageId)) {
if (i != cnt - 1)
- copyMemory(pageAddr, offset(i + 1), pageAddr, offset(i), 8 * (cnt - i - 1));
+ copyMemory(pageAddr, offset(i + 1), pageAddr, offset(i), Long.BYTES * (cnt - i - 1));
setCount(pageAddr, cnt - 1);
@@ -282,4 +282,9 @@ public class PagesListNodeIO extends PageIO implements CompactablePageIO {
sb.a("\n\t}\n]");
}
+
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return (getCapacity(pageSize) - getCount(pageAddr)) * Long.BYTES;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java
index 9063fc95faf..1a60dc537c6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java
@@ -192,13 +192,13 @@ public abstract class AbstractDataPageIO<T extends Storable> extends PageIO impl
public static final int ITEMS_OFF = FIRST_ENTRY_OFF + 2;
/** */
- private static final int ITEM_SIZE = 2;
+ public static final int ITEM_SIZE = 2;
/** */
- private static final int PAYLOAD_LEN_SIZE = 2;
+ public static final int PAYLOAD_LEN_SIZE = 2;
/** */
- private static final int LINK_SIZE = 8;
+ public static final int LINK_SIZE = 8;
/** */
private static final int FRAGMENTED_FLAG = 0b10000000_00000000;
@@ -322,6 +322,11 @@ public abstract class AbstractDataPageIO<T extends Storable> extends PageIO impl
PageUtils.putShort(pageAddr, FREE_SPACE_OFF, (short)freeSpace);
}
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return getFreeSpace(pageAddr);
+ }
+
/**
* Free space refers to a "max row size (without any data page specific overhead) which is guaranteed to fit into
* this data page".
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusIO.java
index eb7cedba1be..11ab12a8724 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusIO.java
@@ -469,6 +469,11 @@ public abstract class BPlusIO<L> extends PageIO implements CompactablePageIO {
.a("\n]");
}
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return (getMaxCount(pageAddr, pageSize) - getCount(pageAddr)) * getItemSize();
+ }
+
/**
* @param pageAddr Page address.
* @return Offset after the last item.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java
index c05f072cf39..edcfefc4f88 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java
@@ -50,7 +50,7 @@ public class BPlusMetaIO extends PageIO {
private static final int FLAGS_OFFSET = INLINE_SIZE_OFFSET + 2;
/** */
- private static final int CREATED_VER_OFFSET = FLAGS_OFFSET + 8;
+ private static final int CREATED_VER_OFFSET = FLAGS_OFFSET + Long.BYTES;
/** */
private static final int REFS_OFFSET = CREATED_VER_OFFSET + IgniteProductVersion.SIZE_IN_BYTES;
@@ -123,8 +123,8 @@ public class BPlusMetaIO extends PageIO {
* @param pageSize Page size.
* @return Max levels possible for this page size.
*/
- private int getMaxLevels(long pageAddr, int pageSize) {
- return (pageSize - refsOff) / 8;
+ public int getMaxLevels(long pageAddr, int pageSize) {
+ return (pageSize - refsOff) / Long.BYTES;
}
/**
@@ -145,7 +145,7 @@ public class BPlusMetaIO extends PageIO {
* @return Offset for page reference.
*/
private int offset(int lvl) {
- return lvl * 8 + refsOff;
+ return lvl * Long.BYTES + refsOff;
}
/**
@@ -346,6 +346,11 @@ public class BPlusMetaIO extends PageIO {
//TODO print firstPageIds by level
}
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return (getMaxLevels(pageAddr, pageSize) - getLevelsCount(pageAddr)) * Long.BYTES;
+ }
+
/**
* @param pageAddr Page address.
* @param inlineObjSupported Supports inline object flag.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java
index bee16c3c9d6..dc0acda88a1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java
@@ -903,6 +903,15 @@ public abstract class PageIO {
*/
protected abstract void printPage(long addr, int pageSize, GridStringBuilder sb) throws IgniteCheckedException;
+ /**
+ * Count of bytes that is currently free in this page and possibly can be used to place additional payload.
+ * @param pageSize Page size.
+ * @param pageAddr Page address.
+ *
+ * @return Free space.
+ */
+ public abstract int getFreeSpace(int pageSize, long pageAddr);
+
/**
* @param page Page.
* @param out Output buffer.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageMetaIO.java
index 170d66d5580..821f0b90791 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageMetaIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageMetaIO.java
@@ -274,4 +274,9 @@ public class PageMetaIO extends PageIO {
.a(",\n\tcandidatePageCount=").a(getCandidatePageCount(addr))
.a("\n]");
}
+
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return 0;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java
index b1adad790a4..25d58b8759c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java
@@ -210,7 +210,7 @@ public class PagePartitionCountersIO extends PageIO {
* @param pageSize Page size.
* @return Maximum number of items which can be stored in buffer.
*/
- private int getCapacity(int pageSize) {
+ public int getCapacity(int pageSize) {
return (pageSize - ITEMS_OFF) / ITEM_SIZE;
}
@@ -230,4 +230,9 @@ public class PagePartitionCountersIO extends PageIO {
sb.a("\n\t}\n]");
}
+
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return (getCapacity(pageSize) - getCount(pageAddr)) * ITEM_SIZE;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java
index 97522ad0aa5..4367d33be7c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java
@@ -491,4 +491,9 @@ public class TrackingPageIO extends PageIO {
sb.a("}\n\t}\n]");
}
+
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return 0;
+ }
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/DummyPageIO.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/DummyPageIO.java
index b34353392b7..a0136c74bd6 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/DummyPageIO.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/DummyPageIO.java
@@ -46,6 +46,11 @@ public class DummyPageIO extends PageIO implements CompactablePageIO {
sb.a("\n]");
}
+ /** {@inheritDoc} */
+ @Override public int getFreeSpace(int pageSize, long pageAddr) {
+ return 0;
+ }
+
/** {@inheritDoc} */
@Override public void compactPage(ByteBuffer page, ByteBuffer out, int pageSize) {
copyPage(page, out, pageSize);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIOFreeSizeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIOFreeSizeTest.java
new file mode 100644
index 00000000000..dd5c59ba7e9
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIOFreeSizeTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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.tree.io;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.cache.query.index.IndexProcessor;
+import org.apache.ignite.internal.cache.query.index.sorted.IndexRow;
+import org.apache.ignite.internal.cache.query.index.sorted.inline.io.AbstractInlineInnerIO;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.PagesList;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.io.PagesListMetaIO;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.io.PagesListNodeIO;
+import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMetrics;
+import org.apache.ignite.internal.processors.metric.impl.LongAdderMetric;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static org.apache.ignite.internal.util.IgniteUtils.KB;
+
+/** Tests {@link PageIO#getFreeSpace(int, long)} method for different {@link PageIO} implementations. */
+@RunWith(Parameterized.class)
+public class PageIOFreeSizeTest extends GridCommonAbstractTest {
+ /** Page size. */
+ @Parameterized.Parameter
+ public int pageSz;
+
+ /** */
+ @Parameterized.Parameters(name = "pageSz={0}")
+ public static Collection<?> parameters() {
+ List<Object[]> params = new ArrayList<>();
+
+ for (long pageSz : new long[] {4 * KB, 8 * KB, 16 * KB})
+ params.add(new Object[] {(int)pageSz});
+
+ return params;
+ }
+
+ /** Page buffer. */
+ private ByteBuffer buf;
+
+ /** Page address. */
+ private long addr;
+
+ /** */
+ private final PageMetrics mock = new PageMetrics() {
+ final LongAdderMetric totalPages = new LongAdderMetric("a", null);
+
+ final LongAdderMetric idxPages = new LongAdderMetric("b", null);
+
+ @Override public LongAdderMetric totalPages() {
+ return totalPages;
+ }
+
+ @Override public LongAdderMetric indexPages() {
+ return idxPages;
+ }
+
+ @Override public void reset() {
+ // No-op.
+ }
+ };
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ IndexProcessor.registerIO();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ buf = GridUnsafe.allocateBuffer(pageSz);
+ addr = GridUnsafe.bufferAddress(buf);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ GridUnsafe.freeBuffer(buf);
+ }
+
+ /** */
+ @Test
+ public void testPagesListMetaIO() {
+ PagesListMetaIO io = io(PagesListMetaIO.VERSIONS);
+
+ int emptyPageSz = io.getCapacity(pageSz, addr) * PagesListMetaIO.ITEM_SIZE;
+
+ assertEquals(emptyPageSz, io.getFreeSpace(pageSz, addr));
+
+ io.addTails(pageSz, addr, 1, new PagesList.Stripe[] {new PagesList.Stripe(1, true)}, 0);
+
+ assertEquals(emptyPageSz - PagesListMetaIO.ITEM_SIZE, io.getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ @Test
+ public void testPagesListNodeIO() {
+ PagesListNodeIO io = io(PagesListNodeIO.VERSIONS);
+
+ int emptyPageSz = io.getCapacity(pageSz) * Long.BYTES;
+
+ assertEquals(emptyPageSz, io.getFreeSpace(pageSz, addr));
+
+ io.addPage(addr, 42L, pageSz);
+ io.addPage(addr, 43L, pageSz);
+
+ assertEquals(emptyPageSz - 2 * Long.BYTES, io.getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ @Test
+ public void testTrackingPageIO() {
+ assertEquals(0, io(TrackingPageIO.VERSIONS).getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ @Test
+ public void testPageMetaIO() {
+ assertEquals(0, io(PageMetaIO.VERSIONS).getFreeSpace(pageSz, addr));
+ assertEquals(0, io(PageMetaIOV2.VERSIONS).getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ @Test
+ public void testPartitionCountersIO() {
+ PagePartitionCountersIO io = io(PagePartitionCountersIO.VERSIONS);
+
+ int emptyPageSz = io.getCapacity(pageSz) * PagePartitionCountersIO.ITEM_SIZE;
+
+ assertEquals(emptyPageSz, io.getFreeSpace(pageSz, addr));
+
+ io.writeCacheSizes(pageSz, addr, new byte[PagePartitionCountersIO.ITEM_SIZE * 3], 0);
+
+ assertEquals(emptyPageSz - 3 * PagePartitionCountersIO.ITEM_SIZE, io.getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ @Test
+ public void testBPlusMetaIO() {
+ BPlusMetaIO io = io(BPlusMetaIO.VERSIONS);
+
+ int emptyPageSz = io.getMaxLevels(addr, pageSz) * Long.BYTES;
+
+ assertEquals(emptyPageSz, io.getFreeSpace(pageSz, addr));
+
+ io.initRoot(addr, 42L, pageSz);
+
+ assertEquals(emptyPageSz - Long.BYTES, io.getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ @Test
+ public void testBPlusIO() throws IgniteCheckedException {
+ BPlusInnerIO<IndexRow> io = io(AbstractInlineInnerIO.versions(42, false));
+
+ int emptyPageSz = io.getMaxCount(addr, pageSz) * io.getItemSize();
+
+ assertEquals(emptyPageSz, io.getFreeSpace(pageSz, addr));
+
+ io.insert(addr, 0, null, new byte[42], 42, true);
+
+ // Inner pages contains extra link to next level.
+ assertEquals(emptyPageSz - (42 + Long.BYTES), io.getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ @Test
+ public void testDataPageIO() throws IgniteCheckedException {
+ DataPageIO io = io(DataPageIO.VERSIONS);
+
+ int emptyPageSz = pageSz - DataPageIO.ITEMS_OFF - DataPageIO.ITEM_SIZE - DataPageIO.PAYLOAD_LEN_SIZE - DataPageIO.LINK_SIZE;
+
+ assertEquals(emptyPageSz, io.getFreeSpace(pageSz, addr));
+
+ io.addRow(addr, new byte[42], pageSz);
+
+ // See AbstractDataPageIO#getPageEntrySize(int, byte)
+ assertEquals(emptyPageSz - 42 - 4 /* data size added. */, io.getFreeSpace(pageSz, addr));
+ }
+
+ /** */
+ private <I extends PageIO> I io(IOVersions<I> versions) {
+ I io = versions.latest();
+
+ GridUnsafe.setMemory(addr, pageSz, (byte)0);
+
+ io.initNewPage(addr, 1, pageSz, mock);
+
+ return io;
+ }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite5.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite5.java
index aeb1865904c..d1f332e4468 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite5.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite5.java
@@ -39,6 +39,7 @@ import org.apache.ignite.internal.processors.cache.persistence.pagemem.PagesWrit
import org.apache.ignite.internal.processors.cache.persistence.pagemem.SpeedBasedThrottleBreakdownTest;
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.tree.io.PageIOFreeSizeTest;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.TrackingPageIOTest;
import org.apache.ignite.internal.processors.cache.persistence.wal.CpTriggeredWalDeltaConsistencyTest;
import org.apache.ignite.internal.processors.cache.persistence.wal.ExplicitWalDeltaConsistencyTest;
@@ -80,6 +81,7 @@ public class IgnitePdsTestSuite5 {
GridTestUtils.addTestIfNeeded(suite, PageMemoryImplTest.class, ignoredTests);
GridTestUtils.addTestIfNeeded(suite, PageIdDistributionTest.class, ignoredTests);
GridTestUtils.addTestIfNeeded(suite, TrackingPageIOTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite, PageIOFreeSizeTest.class, ignoredTests);
// BTree tests with store page memory.
GridTestUtils.addTestIfNeeded(suite, BPlusTreePageMemoryImplTest.class, ignoredTests);