This is an automated email from the ASF dual-hosted git repository. tkalkirill pushed a commit to branch ignite-26232 in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit 2bce4741965dfc30f908b3c61a57450110eae5fb Author: Kirill Tkalenko <[email protected]> AuthorDate: Mon Aug 18 20:11:42 2025 +0300 IGNITE-26232 wip --- .../ItBplusTreePersistentPageMemoryTest.java | 3 +- ...BplusTreeReuseListPersistentPageMemoryTest.java | 3 +- .../pagememory/persistence/PageHeader.java | 97 ++++++++------- .../internal/pagememory/persistence/PagePool.java | 4 +- .../persistence/PersistentPageMemory.java | 35 +++--- .../RandomLruPageReplacementPolicy.java | 4 +- .../pagememory/persistence/PageHeaderTest.java | 134 +++++++++++++++++++++ .../RandomLruPageReplacementPolicySelfTest.java | 2 +- .../pagememory/PersistentPageMemoryNoLoadTest.java | 8 +- 9 files changed, 215 insertions(+), 75 deletions(-) diff --git a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java index 1b72c95a5ec..7bb5761eb51 100644 --- a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java +++ b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java @@ -26,6 +26,7 @@ import org.apache.ignite.internal.lang.IgniteSystemProperties; import org.apache.ignite.internal.pagememory.PageMemory; import org.apache.ignite.internal.pagememory.TestPageIoRegistry; import org.apache.ignite.internal.pagememory.configuration.PersistentDataRegionConfiguration; +import org.apache.ignite.internal.pagememory.persistence.PageHeader; import org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory; import org.apache.ignite.internal.pagememory.persistence.PersistentPageMemoryMetricSource; import org.apache.ignite.internal.pagememory.persistence.TestPageReadWriteManager; @@ -50,7 +51,7 @@ public class ItBplusTreePersistentPageMemoryTest extends AbstractBplusTreePageMe @BeforeAll static void initLockOffset() { - lockOffset = PersistentPageMemory.PAGE_LOCK_OFFSET; + lockOffset = PageHeader.PAGE_LOCK_OFFSET; } /** {@inheritDoc} */ diff --git a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java index a771351f0fc..cc3f96239b6 100644 --- a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java +++ b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java @@ -25,6 +25,7 @@ import org.apache.ignite.internal.configuration.testframework.ConfigurationExten import org.apache.ignite.internal.pagememory.PageMemory; import org.apache.ignite.internal.pagememory.TestPageIoRegistry; import org.apache.ignite.internal.pagememory.configuration.PersistentDataRegionConfiguration; +import org.apache.ignite.internal.pagememory.persistence.PageHeader; import org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory; import org.apache.ignite.internal.pagememory.persistence.PersistentPageMemoryMetricSource; import org.apache.ignite.internal.pagememory.persistence.TestPageReadWriteManager; @@ -40,7 +41,7 @@ import org.junit.jupiter.api.extension.ExtendWith; public class ItBplusTreeReuseListPersistentPageMemoryTest extends AbstractBplusTreeReusePageMemoryTest { @BeforeAll static void initLockOffset() { - lockOffset = PersistentPageMemory.PAGE_LOCK_OFFSET; + lockOffset = PageHeader.PAGE_LOCK_OFFSET; } /** {@inheritDoc} */ diff --git a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageHeader.java b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageHeader.java index a58d5104c4e..249344ce57b 100644 --- a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageHeader.java +++ b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageHeader.java @@ -43,19 +43,33 @@ import org.apache.ignite.internal.pagememory.FullPageId; * * <p>Additional information:</p> * <ul> - * <li>Size of the page header in {@link PersistentPageMemory#PAGE_OVERHEAD}.</li> + * <li>Size of the page header in {@link #PAGE_OVERHEAD}.</li> * <li>Flags currently store only one value, whether the page is dirty or not. Only one byte is used for now, the rest can be reused * later, we do not remove them only for alignment.</li> * </ul> */ -// TODO: IGNITE-16350 Improve documentation and refactoring public class PageHeader { /** Page marker. */ - public static final long PAGE_MARKER = 0x0000000000000001L; + static final long PAGE_MARKER = 0x0000000000000001L; /** Dirty flag. */ private static final int DIRTY_FLAG = 0x01000000; + /** Unknown partition generation. */ + static final int UNKNOWN_PARTITION_GENERATION = -1; + + /** 8b Marker/timestamp, 4b Partition generation, 4b flags, 8b Page ID, 4b Group ID, 4b Pin count, 8b Lock, 8b Temporary buffer. */ + public static final int PAGE_OVERHEAD = 48; + + /** Marker or timestamp offset. */ + private static final int MARKER_OR_TIMESTAMP_OFFSET = 0; + + /** Partition generation offset. */ + private static final int PARTITION_GENERATION_OFFSET = 8; + + /** Flags offset. */ + private static final int FLAGS_OFFSET = 12; + /** Page ID offset. */ private static final int PAGE_ID_OFFSET = 16; @@ -65,28 +79,23 @@ public class PageHeader { /** Page pin counter offset. */ private static final int PAGE_PIN_CNT_OFFSET = 28; + /** Page lock offset. */ + public static final int PAGE_LOCK_OFFSET = 32; + /** Page temp copy buffer relative pointer offset. */ private static final int PAGE_TMP_BUF_OFFSET = 40; - private static final int PARTITION_GENERATION_OFFSET = 8; - - private static final int FLAGS_OFFSET = 12; - - /** Unknown partition generation. */ - static final int UNKNOWN_PARTITION_GENERATION = -1; - /** * Initializes the header of the page. * * @param absPtr Absolute pointer to initialize. - * @param relative Relative pointer to write. */ - public static void initNew(long absPtr, long relative) { - writePartitionGeneration(absPtr, UNKNOWN_PARTITION_GENERATION); + public static void initNew(long absPtr) { + partitionGeneration(absPtr, UNKNOWN_PARTITION_GENERATION); tempBufferPointer(absPtr, INVALID_REL_PTR); - putLong(absPtr, PAGE_MARKER); + putLong(absPtr + MARKER_OR_TIMESTAMP_OFFSET, PAGE_MARKER); putInt(absPtr + PAGE_PIN_CNT_OFFSET, 0); } @@ -114,37 +123,37 @@ public class PageHeader { * Returns flag value. * * @param absPtr Absolute pointer. - * @param flag Flag mask. + * @param flagMask Flag mask. */ - private static boolean flag(long absPtr, int flag) { - assert (flag & 0xFFFFFF) == 0; - assert Long.bitCount(flag) == 1; + private static boolean flag(long absPtr, int flagMask) { + assert (flagMask & 0xFFFFFF) == 0 : Integer.toHexString(flagMask); + assert Long.bitCount(flagMask) == 1 : Integer.toHexString(flagMask); int flags = getInt(absPtr + FLAGS_OFFSET); - return (flags & flag) != 0; + return (flags & flagMask) != 0; } /** * Sets flag value. * * @param absPtr Absolute pointer. - * @param flag Flag mask. + * @param flagMask Flag mask. * @param set New flag value. * @return Previous flag value. */ - private static boolean flag(long absPtr, int flag, boolean set) { - assert (flag & 0xFFFFFF) == 0; - assert Long.bitCount(flag) == 1; + private static boolean flag(long absPtr, int flagMask, boolean set) { + assert (flagMask & 0xFFFFFF) == 0 : Integer.toHexString(flagMask); + assert Long.bitCount(flagMask) == 1 : Integer.toHexString(flagMask); int flags = getInt(absPtr + FLAGS_OFFSET); - boolean was = (flags & flag) != 0; + boolean was = (flags & flagMask) != 0; if (set) { - flags |= flag; + flags |= flagMask; } else { - flags &= ~flag; + flags &= ~flagMask; } putInt(absPtr + FLAGS_OFFSET, flags); @@ -186,20 +195,20 @@ public class PageHeader { * * @param absPtr Absolute pointer. */ - public static int pinCount(long absPtr) { - return getIntVolatile(null, absPtr); + static int pinCount(long absPtr) { + return getIntVolatile(null, absPtr + PAGE_PIN_CNT_OFFSET); } /** * Volatile write for current timestamp to page in {@code absAddr} address. * * @param absPtr Absolute page address. - * @param tstamp Timestamp. + * @param timestamp Timestamp. */ - public static void writeTimestamp(final long absPtr, long tstamp) { - tstamp &= 0xFFFFFFFFFFFFFF00L; + public static void timestamp(long absPtr, long timestamp) { + timestamp &= 0xFFFFFFFFFFFFFF00L; - putLongVolatile(null, absPtr, tstamp | 0x01); + putLongVolatile(null, absPtr + MARKER_OR_TIMESTAMP_OFFSET, timestamp | 0x01); } /** @@ -208,8 +217,8 @@ public class PageHeader { * @param absPtr Absolute page address. * @return Timestamp. */ - public static long readTimestamp(final long absPtr) { - long markerAndTs = getLong(absPtr); + public static long timestamp(long absPtr) { + long markerAndTs = getLong(absPtr + MARKER_OR_TIMESTAMP_OFFSET); // Clear last byte as it is occupied by page marker. return markerAndTs & ~0xFF; @@ -222,7 +231,7 @@ public class PageHeader { * @param tmpRelPtr Temp buffer relative pointer or {@link PersistentPageMemory#INVALID_REL_PTR} if page is not copied to checkpoint * buffer. */ - public static void tempBufferPointer(long absPtr, long tmpRelPtr) { + static void tempBufferPointer(long absPtr, long tmpRelPtr) { putLong(absPtr + PAGE_TMP_BUF_OFFSET, tmpRelPtr); } @@ -232,7 +241,7 @@ public class PageHeader { * @param absPtr Page absolute pointer. * @return Temp buffer relative pointer. */ - public static long tempBufferPointer(long absPtr) { + static long tempBufferPointer(long absPtr) { return getLong(absPtr + PAGE_TMP_BUF_OFFSET); } @@ -242,7 +251,7 @@ public class PageHeader { * @param absPtr Absolute memory pointer to the page header. * @return Page ID written to the page. */ - public static long readPageId(long absPtr) { + static long pageId(long absPtr) { return getLong(absPtr + PAGE_ID_OFFSET); } @@ -262,7 +271,7 @@ public class PageHeader { * @param absPtr Absolute memory pointer to the page header. * @return Group ID written to the page. */ - private static int readPageGroupId(final long absPtr) { + private static int pageGroupId(long absPtr) { return getInt(absPtr + PAGE_GROUP_ID_OFFSET); } @@ -272,7 +281,7 @@ public class PageHeader { * @param absPtr Absolute memory pointer to the page header. * @param grpId Group ID to write. */ - private static void pageGroupId(final long absPtr, final int grpId) { + private static void pageGroupId(long absPtr, int grpId) { putInt(absPtr + PAGE_GROUP_ID_OFFSET, grpId); } @@ -282,8 +291,8 @@ public class PageHeader { * @param absPtr Absolute memory pointer to the page header. * @return Full page ID written to the page. */ - public static FullPageId fullPageId(final long absPtr) { - return new FullPageId(readPageId(absPtr), readPageGroupId(absPtr)); + public static FullPageId fullPageId(long absPtr) { + return new FullPageId(pageId(absPtr), pageGroupId(absPtr)); } /** @@ -292,7 +301,7 @@ public class PageHeader { * @param absPtr Absolute memory pointer to the page header. * @param fullPageId Full page ID to write. */ - public static void fullPageId(final long absPtr, final FullPageId fullPageId) { + public static void fullPageId(long absPtr, FullPageId fullPageId) { pageId(absPtr, fullPageId.pageId()); pageGroupId(absPtr, fullPageId.groupId()); @@ -303,7 +312,7 @@ public class PageHeader { * * @param absPtr Absolute memory pointer to the page header. */ - public static int readPartitionGeneration(long absPtr) { + public static int partitionGeneration(long absPtr) { return getInt(absPtr + PARTITION_GENERATION_OFFSET); } @@ -313,7 +322,7 @@ public class PageHeader { * @param absPtr Absolute memory pointer to page header. * @param partitionGeneration Partition generation, strictly positive or {@link #UNKNOWN_PARTITION_GENERATION} if reset is required. */ - static void writePartitionGeneration(long absPtr, int partitionGeneration) { + static void partitionGeneration(long absPtr, int partitionGeneration) { assert partitionGeneration > 0 || partitionGeneration == UNKNOWN_PARTITION_GENERATION : partitionGeneration; putInt(absPtr + PARTITION_GENERATION_OFFSET, partitionGeneration); diff --git a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PagePool.java b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PagePool.java index 417a549a62c..e0bee13d249 100644 --- a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PagePool.java +++ b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PagePool.java @@ -17,11 +17,11 @@ package org.apache.ignite.internal.pagememory.persistence; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_LOCK_OFFSET; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.fullPageId; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.initNew; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.isAcquired; import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.INVALID_REL_PTR; -import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.PAGE_LOCK_OFFSET; import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.RELATIVE_PTR_MASK; import static org.apache.ignite.internal.util.GridUnsafe.compareAndSwapLong; import static org.apache.ignite.internal.util.GridUnsafe.getLongVolatile; @@ -189,7 +189,7 @@ public class PagePool { assert relative != INVALID_REL_PTR; - initNew(absPtr, relative); + initNew(absPtr); rwLock.init(absPtr + PAGE_LOCK_OFFSET, tag); 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 3ba17e416af..2f1a4971aee 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 @@ -27,13 +27,14 @@ import static org.apache.ignite.internal.pagememory.io.PageIo.setPageId; import static org.apache.ignite.internal.pagememory.persistence.CheckpointUrgency.MUST_TRIGGER; import static org.apache.ignite.internal.pagememory.persistence.CheckpointUrgency.NOT_REQUIRED; import static org.apache.ignite.internal.pagememory.persistence.CheckpointUrgency.SHOULD_TRIGGER; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_LOCK_OFFSET; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_OVERHEAD; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.dirty; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.fullPageId; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.isAcquired; -import static org.apache.ignite.internal.pagememory.persistence.PageHeader.readPageId; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.partitionGeneration; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.tempBufferPointer; -import static org.apache.ignite.internal.pagememory.persistence.PageHeader.writePartitionGeneration; -import static org.apache.ignite.internal.pagememory.persistence.PageHeader.writeTimestamp; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.timestamp; import static org.apache.ignite.internal.pagememory.persistence.PagePool.SEGMENT_INDEX_MASK; import static org.apache.ignite.internal.pagememory.persistence.throttling.PagesWriteThrottlePolicy.CP_BUF_FILL_THRESHOLD; import static org.apache.ignite.internal.pagememory.util.PageIdUtils.effectivePageId; @@ -145,12 +146,6 @@ public class PersistentPageMemory implements PageMemory { /** Pointer which means that this page is outdated (for example, group was destroyed, partition eviction'd happened. */ public static final long OUTDATED_REL_PTR = INVALID_REL_PTR + 1; - /** Page lock offset. */ - public static final int PAGE_LOCK_OFFSET = 32; - - /** 8b Marker/timestamp, 4b Partition generation, 4b flags, 8b Page ID, 4b Group ID, 4b Pin count, 8b Lock, 8b Temporary buffer. */ - public static final int PAGE_OVERHEAD = 48; - /** Try again tag. */ public static final int TRY_AGAIN_TAG = -1; @@ -442,7 +437,7 @@ public class PersistentPageMemory implements PageMemory { } if (touch) { - writeTimestamp(absPtr, coarseCurrentTimeMillis()); + timestamp(absPtr, coarseCurrentTimeMillis()); } assert getCrc(absPtr + PAGE_OVERHEAD) == 0; // TODO IGNITE-16612 @@ -584,8 +579,8 @@ public class PersistentPageMemory implements PageMemory { zeroMemory(absPtr + PAGE_OVERHEAD, pageSize()); fullPageId(absPtr, fullId); - writeTimestamp(absPtr, coarseCurrentTimeMillis()); - writePartitionGeneration(absPtr, seg.partGeneration(grpId, partId)); + timestamp(absPtr, coarseCurrentTimeMillis()); + partitionGeneration(absPtr, seg.partGeneration(grpId, partId)); rwLock.init(absPtr + PAGE_LOCK_OFFSET, tag(pageId)); @@ -741,8 +736,8 @@ public class PersistentPageMemory implements PageMemory { absPtr = seg.absolute(relPtr); fullPageId(absPtr, fullId); - writeTimestamp(absPtr, coarseCurrentTimeMillis()); - writePartitionGeneration(absPtr, seg.partGeneration(grpId, partId)); + timestamp(absPtr, coarseCurrentTimeMillis()); + partitionGeneration(absPtr, seg.partGeneration(grpId, partId)); assert !isAcquired(absPtr) : "Pin counter must be 0 for a new page [relPtr=" + hexLong(relPtr) + ", absPtr=" + hexLong(absPtr) + ']'; @@ -793,8 +788,8 @@ public class PersistentPageMemory implements PageMemory { zeroMemory(pageAddr, pageSize()); fullPageId(absPtr, fullId); - writeTimestamp(absPtr, coarseCurrentTimeMillis()); - writePartitionGeneration(absPtr, seg.partGeneration(grpId, partId)); + timestamp(absPtr, coarseCurrentTimeMillis()); + partitionGeneration(absPtr, seg.partGeneration(grpId, partId)); setPageId(pageAddr, pageId); assert !isAcquired(absPtr) : @@ -1116,7 +1111,7 @@ public class PersistentPageMemory implements PageMemory { } private long postWriteLockPage(long absPtr, FullPageId fullId) { - writeTimestamp(absPtr, coarseCurrentTimeMillis()); + timestamp(absPtr, coarseCurrentTimeMillis()); // Create a buffer copy if the page is scheduled for a checkpoint. if (isInCheckpoint(fullId) && tempBufferPointer(absPtr) == INVALID_REL_PTR) { @@ -1161,8 +1156,8 @@ public class PersistentPageMemory implements PageMemory { // info for checkpoint buffer cleaner. fullPageId(tmpAbsPtr, fullId); - assert getCrc(absPtr + PAGE_OVERHEAD) == 0; // TODO GG-11480 - assert getCrc(tmpAbsPtr + PAGE_OVERHEAD) == 0; // TODO GG-11480 + assert getCrc(absPtr + PAGE_OVERHEAD) == 0; // TODO IGNITE-16612 + assert getCrc(tmpAbsPtr + PAGE_OVERHEAD) == 0; // TODO IGNITE-16612 } assert getCrc(absPtr + PAGE_OVERHEAD) == 0; // TODO IGNITE-16612 @@ -1188,7 +1183,7 @@ public class PersistentPageMemory implements PageMemory { long pageId = getPageId(page + PAGE_OVERHEAD); try { - assert pageId != 0 : hexLong(readPageId(page)); + assert pageId != 0 : hexLong(PageHeader.pageId(page)); rwLock.writeUnlock(page + PAGE_LOCK_OFFSET, tag(pageId)); diff --git a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicy.java b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicy.java index ae019a32ba0..774b60869c0 100644 --- a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicy.java +++ b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicy.java @@ -17,9 +17,9 @@ package org.apache.ignite.internal.pagememory.persistence.replacement; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_OVERHEAD; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.fullPageId; import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.INVALID_REL_PTR; -import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.PAGE_OVERHEAD; import static org.apache.ignite.internal.pagememory.util.PageIdUtils.partitionId; import java.util.HashSet; @@ -125,7 +125,7 @@ public class RandomLruPageReplacementPolicy extends PageReplacementPolicy { continue; } - long pageTs = PageHeader.readTimestamp(absPageAddr); + long pageTs = PageHeader.timestamp(absPageAddr); boolean storMeta = isStoreMetadataPage(absPageAddr); diff --git a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/PageHeaderTest.java b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/PageHeaderTest.java new file mode 100644 index 00000000000..f619d1ffc70 --- /dev/null +++ b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/PageHeaderTest.java @@ -0,0 +1,134 @@ +/* + * 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.pagememory.persistence; + +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_LOCK_OFFSET; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_OVERHEAD; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.UNKNOWN_PARTITION_GENERATION; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.acquirePage; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.dirty; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.fullPageId; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.initNew; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.isAcquired; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.partitionGeneration; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.pinCount; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.releasePage; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.tempBufferPointer; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.timestamp; +import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.INVALID_REL_PTR; +import static org.apache.ignite.internal.util.GridUnsafe.allocateMemory; +import static org.apache.ignite.internal.util.GridUnsafe.freeMemory; +import static org.apache.ignite.internal.util.GridUnsafe.getLong; +import static org.apache.ignite.internal.util.GridUnsafe.zeroMemory; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.ignite.internal.pagememory.FullPageId; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** For {@link PageHeader} testing. */ +public class PageHeaderTest { + private static long pageHeaderAddr = -1; + + @BeforeAll + static void beforeAll() { + pageHeaderAddr = allocateMemory(PAGE_OVERHEAD); + } + + @AfterAll + static void afterAll() { + if (pageHeaderAddr != -1) { + freeMemory(pageHeaderAddr); + } + } + + @BeforeEach + void setUp() { + initNew(pageHeaderAddr); + } + + @AfterEach + void tearDown() { + zeroMemory(pageHeaderAddr, PAGE_OVERHEAD); + } + + @Test + void testInitNew() { + zeroMemory(pageHeaderAddr, PAGE_OVERHEAD); + initNew(pageHeaderAddr); + + assertEquals(0L, timestamp(pageHeaderAddr)); + assertEquals(UNKNOWN_PARTITION_GENERATION, partitionGeneration(pageHeaderAddr)); + assertFalse(dirty(pageHeaderAddr)); + assertEquals(new FullPageId(0, 0), fullPageId(pageHeaderAddr)); + assertEquals(0, pinCount(pageHeaderAddr)); + assertEquals(0L, getLong(pageHeaderAddr + PAGE_LOCK_OFFSET)); + assertEquals(INVALID_REL_PTR, tempBufferPointer(pageHeaderAddr)); + } + + @Test + void testReadWriteTimeStamp() { + long timestamp = System.currentTimeMillis(); + + timestamp(pageHeaderAddr, timestamp); + assertEquals(timestamp & ~0xFF, timestamp(pageHeaderAddr)); + } + + @Test + void testReadWritePartitionGeneration() { + partitionGeneration(pageHeaderAddr, 42); + assertEquals(42, partitionGeneration(pageHeaderAddr)); + } + + @Test + void testReadWriteDirtyFlagValue() { + assertFalse(dirty(pageHeaderAddr, true)); + assertTrue(dirty(pageHeaderAddr)); + + assertTrue(dirty(pageHeaderAddr, false)); + assertFalse(dirty(pageHeaderAddr)); + } + + @Test + void testReadWriteFullPageId() { + fullPageId(pageHeaderAddr, new FullPageId(4, 2)); + assertEquals(new FullPageId(4, 2), fullPageId(pageHeaderAddr)); + } + + @Test + void testAcquireRelease() { + assertEquals(1, acquirePage(pageHeaderAddr)); + assertEquals(1, pinCount(pageHeaderAddr)); + assertTrue(isAcquired(pageHeaderAddr)); + + assertEquals(0, releasePage(pageHeaderAddr)); + assertEquals(0, pinCount(pageHeaderAddr)); + assertFalse(isAcquired(pageHeaderAddr)); + } + + @Test + void testReadWriteCheckpointTempBufferRelativePointer() { + tempBufferPointer(pageHeaderAddr, 42); + assertEquals(42, tempBufferPointer(pageHeaderAddr)); + } +} \ No newline at end of file diff --git a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicySelfTest.java b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicySelfTest.java index 2f4cfb518c3..7e68b8c678a 100644 --- a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicySelfTest.java +++ b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/RandomLruPageReplacementPolicySelfTest.java @@ -17,8 +17,8 @@ package org.apache.ignite.internal.pagememory.persistence.replacement; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_OVERHEAD; import static org.apache.ignite.internal.pagememory.persistence.PageHeader.fullPageId; -import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.PAGE_OVERHEAD; import static org.apache.ignite.internal.util.Constants.MiB; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java index 4c1263cc91b..e6e53d4c4db 100644 --- a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java +++ b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java @@ -21,7 +21,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.apache.ignite.internal.pagememory.persistence.CheckpointUrgency.MUST_TRIGGER; import static org.apache.ignite.internal.pagememory.persistence.CheckpointUrgency.NOT_REQUIRED; import static org.apache.ignite.internal.pagememory.persistence.CheckpointUrgency.SHOULD_TRIGGER; -import static org.apache.ignite.internal.pagememory.persistence.PersistentPageMemory.PAGE_OVERHEAD; +import static org.apache.ignite.internal.pagememory.persistence.PageHeader.PAGE_OVERHEAD; import static org.apache.ignite.internal.pagememory.persistence.checkpoint.CheckpointState.FINISHED; import static org.apache.ignite.internal.pagememory.persistence.checkpoint.CheckpointState.PAGES_SORTED; import static org.apache.ignite.internal.pagememory.persistence.checkpoint.CheckpointTestUtils.mockCheckpointTimeoutLock; @@ -596,7 +596,7 @@ public class PersistentPageMemoryNoLoadTest extends AbstractPageMemoryNoLoadSelf // Absolute memory pointer to page with header. long absPtr = mem.acquirePage(fullPageId.groupId(), fullPageId.pageId()); - assertEquals(1, PageHeader.readPartitionGeneration(absPtr)); + assertEquals(1, PageHeader.partitionGeneration(absPtr)); }); } @@ -610,7 +610,7 @@ public class PersistentPageMemoryNoLoadTest extends AbstractPageMemoryNoLoadSelf // Absolute memory pointer to page with header. long absPtr = mem.acquirePage(fullPageId.groupId(), fullPageId.pageId()); - assertEquals(2, PageHeader.readPartitionGeneration(absPtr)); + assertEquals(2, PageHeader.partitionGeneration(absPtr)); }); } @@ -634,7 +634,7 @@ public class PersistentPageMemoryNoLoadTest extends AbstractPageMemoryNoLoadSelf // Absolute memory pointer to page with header. long absPtr = mem.acquirePage(fullPageId.groupId(), fullPageId.pageId()); - assertEquals(2, PageHeader.readPartitionGeneration(absPtr)); + assertEquals(2, PageHeader.partitionGeneration(absPtr)); }); }
