Full page ID to ignore partition ID for index pages.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ad5aacfa Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ad5aacfa Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ad5aacfa Branch: refs/heads/ignite-db-x-10884 Commit: ad5aacfae6c56ea5c3e543d200bf4e20771047b8 Parents: 823fabd Author: Alexey Goncharuk <[email protected]> Authored: Mon Apr 25 17:20:30 2016 -0700 Committer: Alexey Goncharuk <[email protected]> Committed: Mon Apr 25 17:20:30 2016 -0700 ---------------------------------------------------------------------- .../ignite/internal/pagemem/FullPageId.java | 21 +++-- .../ignite/internal/pagemem/PageIdUtils.java | 86 +++++++++++--------- .../internal/pagemem/impl/FullPageIdTable.java | 21 ++--- .../pagemem/impl/PageIdUtilsSelfTest.java | 39 +++++++++ 4 files changed, 112 insertions(+), 55 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ad5aacfa/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java index 22a01c4..0247aec 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java @@ -19,23 +19,30 @@ package org.apache.ignite.internal.pagemem; import org.apache.ignite.internal.util.typedef.internal.SB; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_IDX; + /** * */ public class FullPageId { /** */ - private long pageId; + private final long pageId; + + /** */ + private final long effectivePageId; /** */ - private int cacheId; + private final int cacheId; /** * @param pageId Page ID. * @param cacheId Cache ID. */ public FullPageId(long pageId, int cacheId) { - this.pageId = pageId; + this.pageId = PageIdUtils.pageId(pageId); this.cacheId = cacheId; + + effectivePageId = PageIdUtils.flag(pageId) == FLAG_IDX ? PageIdUtils.effectiveIndexPageId(pageId) : this.pageId; } /** @@ -62,12 +69,12 @@ public class FullPageId { FullPageId that = (FullPageId)o; - return pageId == that.pageId && cacheId == that.cacheId; + return effectivePageId == that.effectivePageId && cacheId == that.cacheId; } /** {@inheritDoc} */ @Override public int hashCode() { - int result = (int)(pageId ^ (pageId >>> 32)); + int result = (int)(effectivePageId ^ (effectivePageId >>> 32)); result = 31 * result + cacheId; @@ -76,6 +83,8 @@ public class FullPageId { /** {@inheritDoc} */ @Override public String toString() { - return new SB("FullPageId [pageId=").appendHex(pageId).a(", cacheId=").a(cacheId).a(']').toString(); + return new SB("FullPageId [pageId=").appendHex(pageId) + .a(", effectivePageId=").appendHex(effectivePageId) + .a(", cacheId=").a(cacheId).a(']').toString(); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/ad5aacfa/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java index 4493b1a..3a14c5f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java @@ -18,47 +18,55 @@ package org.apache.ignite.internal.pagemem; /** - * TODO describe the bits structure. + * Utility class for page ID parts manipulation. + * + * @see FullPageId */ public final class PageIdUtils { /** */ - private static final long FILE_ID_MASK = 0x000FFFFFC0000000L; + private static final int PAGE_IDX_SIZE = 30; /** */ - private static final long PAGE_NUM_MASK = 0x000000003FFFFFFFL; + private static final int FILE_ID_SIZE = 22; /** */ - private static final int OFFSET_SHIFTED_MASK = 0xFFF; + private static final int PART_ID_SIZE = 14; /** */ - private static final int FILE_ID_SIZE = Long.bitCount(FILE_ID_MASK); + private static final int FLAG_SIZE = 3; /** */ - private static final int PART_ID_SIZE = 14; + private static final int OFFSET_SIZE = 12; /** */ - private static final int PART_ID_MASK = ~(-1 << PART_ID_SIZE); + private static final long PAGE_IDX_MASK = ~(-1 << PAGE_IDX_SIZE); /** */ - private static final int FLAG_SIZE = 3; + private static final long FILE_ID_MASK = ~(-1 << FILE_ID_SIZE); + + /** */ + private static final long OFFSET_MASK = ~(-1 << OFFSET_SIZE); + + /** */ + private static final int PART_ID_MASK = ~(-1 << PART_ID_SIZE); /** */ private static final int FLAG_MASK = ~(-1 << FLAG_SIZE); /** */ - private static final int PAGE_NUM_SIZE = Long.bitCount(PAGE_NUM_MASK); + private static final long EFFECTIVE_INDEX_PAGE_ID_MASK = ((long)FLAG_MASK << (PAGE_IDX_SIZE + PART_ID_SIZE)) | PAGE_IDX_MASK; /** Maximum page number. */ - public static final int MAX_PAGE_NUM = (1 << PAGE_NUM_SIZE) - 1; + public static final int MAX_PAGE_NUM = (1 << PAGE_IDX_SIZE) - 1; + + /** Maximum page number. */ + public static final int MAX_PART_ID = (1 << PART_ID_SIZE) - 1; /** Maximum file ID. */ public static final int MAX_FILE_ID = (1 << FILE_ID_SIZE) - 1; /** Maximum offset in dwords. */ - public static final int MAX_OFFSET_DWORDS = OFFSET_SHIFTED_MASK; - - /** Maximum part number. */ - public static final int MAX_PART_ID = (1 << PART_ID_SIZE) - 1; + public static final int MAX_OFFSET_DWORDS = (int)OFFSET_MASK; /** * @@ -77,10 +85,10 @@ public final class PageIdUtils { */ public static long linkFromBytesOffset(long pageId, int bytesOffset) { assert (bytesOffset & 0x7) == 0; - assert (pageId >> (PAGE_NUM_SIZE + FILE_ID_SIZE)) == 0; + assert (pageId >> (PAGE_IDX_SIZE + FILE_ID_SIZE)) == 0; - // (bytesOffset >> 3) << PAGE_NUM_SIZE - return pageId | (((long)bytesOffset) << (FILE_ID_SIZE + PAGE_NUM_SIZE - 3)); + // (bytesOffset >> 3) << PAGE_IDX_SIZE + return pageId | (((long)bytesOffset) << (FILE_ID_SIZE + PAGE_IDX_SIZE - 3)); } /** @@ -91,9 +99,9 @@ public final class PageIdUtils { * @return Page link. */ public static long linkFromDwordOffset(long pageId, int dwordOffset) { - assert (pageId >> (PAGE_NUM_SIZE + FILE_ID_SIZE)) == 0; + assert (pageId >> (PAGE_IDX_SIZE + FILE_ID_SIZE)) == 0; - return pageId | (((long)dwordOffset) << (PAGE_NUM_SIZE + FILE_ID_SIZE)); + return pageId | (((long)dwordOffset) << (PAGE_IDX_SIZE + FILE_ID_SIZE)); } /** @@ -104,9 +112,14 @@ public final class PageIdUtils { * @return Page ID. */ public static long pageId(int fileId, long pageIdx) { - assert (pageIdx & ~PAGE_NUM_MASK) == 0; + assert (pageIdx & ~PAGE_IDX_MASK) == 0; + + long pageId = 0; + + pageId = (pageId << FILE_ID_SIZE) | (fileId & FILE_ID_MASK); + pageId = (pageId << PAGE_IDX_SIZE) | (pageIdx & PAGE_IDX_MASK); - return (( ((long)fileId) << PAGE_NUM_SIZE) & FILE_ID_MASK ) | pageIdx; + return pageId; } /** @@ -116,7 +129,7 @@ public final class PageIdUtils { * @return Page ID. */ public static long pageIdx(long pageId) { - return pageId & PAGE_NUM_MASK; + return pageId & PAGE_IDX_MASK; } /** @@ -126,7 +139,15 @@ public final class PageIdUtils { * @return Page ID. */ public static long pageId(long link) { - return link & (FILE_ID_MASK | PAGE_NUM_MASK); + return link & ~(OFFSET_MASK << (FILE_ID_SIZE + PAGE_IDX_SIZE)); + } + + /** + * @param link Page link. + * @return Effective index page id. + */ + public static long effectiveIndexPageId(long link) { + return link & EFFECTIVE_INDEX_PAGE_ID_MASK; } /** @@ -136,7 +157,7 @@ public final class PageIdUtils { * @return File ID. */ public static int fileId(long linkOrPageId) { - return (int)((linkOrPageId & FILE_ID_MASK) >> PAGE_NUM_SIZE); + return (int)((linkOrPageId >> PAGE_IDX_SIZE) & FILE_ID_MASK); } /** @@ -146,7 +167,7 @@ public final class PageIdUtils { * @return Offset within the page in bytes. */ public static int bytesOffset(long link) { - return (int)((link >> (PAGE_NUM_SIZE + FILE_ID_SIZE)) & OFFSET_SHIFTED_MASK) << 3; + return (int)((link >> (PAGE_IDX_SIZE + FILE_ID_SIZE)) & OFFSET_MASK) << 3; } /** @@ -156,16 +177,7 @@ public final class PageIdUtils { * @return Offset in 8-byte words. */ public static int dwordsOffset(long link) { - return (int)(link >> (PAGE_NUM_SIZE + FILE_ID_SIZE)) & OFFSET_SHIFTED_MASK; - } - - /** - * @param cacheId Cache ID. - * @param partId Partition ID. - * @return File ID constructed from the given cache ID and partition ID. - */ - public static int fileId(int cacheId, int partId) { - return (cacheId & 0xFF << 14) | partId; + return (int)((link >> (PAGE_IDX_SIZE + FILE_ID_SIZE)) & OFFSET_MASK); } /** @@ -183,10 +195,10 @@ public final class PageIdUtils { } public static byte flag(long pageId) { - return (byte) (( pageId >>> (PART_ID_SIZE + PAGE_NUM_SIZE) ) & FLAG_MASK); + return (byte) (( pageId >>> (PART_ID_SIZE + PAGE_IDX_SIZE) ) & FLAG_MASK); } public static int partId(long pageId) { - return (int) ((pageId >>> PAGE_NUM_SIZE) & PART_ID_MASK); + return (int) ((pageId >>> PAGE_IDX_SIZE) & PART_ID_MASK); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/ad5aacfa/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/FullPageIdTable.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/FullPageIdTable.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/FullPageIdTable.java index e05d64c..9c4ce66 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/FullPageIdTable.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/FullPageIdTable.java @@ -46,13 +46,10 @@ public class FullPageIdTable { private static final int EMPTY_CACHE_ID = EMPTY_FULL_PAGE_ID.cacheId(); /** */ - public static final FullPageId REMOVED_FULL_PAGE_ID = new FullPageId(0x8000000000000000L, 0); + private static final long REMOVED_PAGE_ID = 0x8000000000000000L; /** */ - private static final long REMOVED_PAGE_ID = REMOVED_FULL_PAGE_ID.pageId(); - - /** */ - private static final int REMOVED_CACHE_ID = REMOVED_FULL_PAGE_ID.cacheId(); + private static final int REMOVED_CACHE_ID = 0; /** */ private static final int EQUAL = 0; @@ -179,7 +176,7 @@ public class FullPageIdTable { int res = testKeyAt(index, key); if (res == EMPTY) { - setKeyAt(index, key); + setKeyAt(index, key.pageId(), key.cacheId()); incrementSize(); @@ -237,7 +234,7 @@ public class FullPageIdTable { long res = testKeyAt(index, key); if (res == EQUAL) { - setKeyAt(index, REMOVED_FULL_PAGE_ID); + setKeyAt(index, REMOVED_PAGE_ID, REMOVED_CACHE_ID); decrementSize(); @@ -283,20 +280,20 @@ public class FullPageIdTable { */ private boolean assertKey(FullPageId fullId) { assert !F.eq(fullId, EMPTY_FULL_PAGE_ID) : "fullId != EMPTY"; - assert !F.eq(fullId, REMOVED_FULL_PAGE_ID) : "fullId != REMOVED"; return true; } /** * @param index Entry index. - * @param val Value to write. + * @param pageId Page ID to write. + * @param cacheId Cache ID to write. */ - private void setKeyAt(int index, FullPageId val) { + private void setKeyAt(int index, long pageId, int cacheId) { long base = valPtr + 4 + (long)index * BYTES_PER_ENTRY; - mem.writeLong(base, val.pageId()); - mem.writeLong(base + 8, val.cacheId()); + mem.writeLong(base, pageId); + mem.writeLong(base + 8, cacheId); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/ad5aacfa/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java index 1306204..77ab497 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java @@ -10,7 +10,10 @@ package org.apache.ignite.internal.pagemem.impl; import java.util.Random; + +import org.apache.ignite.internal.pagemem.FullPageId; import org.apache.ignite.internal.pagemem.PageIdUtils; +import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; @@ -146,6 +149,42 @@ public class PageIdUtilsSelfTest extends GridCommonAbstractTest { } /** + * @throws Exception if failed. + */ + public void testFullPageId() throws Exception { + Random rnd = new Random(); + + // Check that link is not included in FullPageId for data pages. + for (int i = 0; i < 50_000; i++) { + int offset = rnd.nextInt(PageIdUtils.MAX_OFFSET_DWORDS + 1); + int partId = rnd.nextInt(PageIdUtils.MAX_PART_ID + 1); + int pageNum = rnd.nextInt(PageIdUtils.MAX_PAGE_NUM + 1); + + long pageId = PageIdUtils.pageId(partId, PageMemory.FLAG_DATA, pageNum); + + long link1 = PageIdUtils.linkFromDwordOffset(pageId, offset); + long link2 = PageIdUtils.linkFromDwordOffset(pageId, 0); + + assertEquals(new FullPageId(link1, 1), new FullPageId(link2, 1)); + } + + // Check that partition ID is not included in FullPageId for data pages. + for (int i = 0; i < 50_000; i++) { + int offset = rnd.nextInt(PageIdUtils.MAX_OFFSET_DWORDS + 1); + int partId = rnd.nextInt(PageIdUtils.MAX_PART_ID + 1); + int pageNum = rnd.nextInt(PageIdUtils.MAX_PAGE_NUM + 1); + + long pageId1 = PageIdUtils.pageId(partId, PageMemory.FLAG_IDX, pageNum); + long pageId2 = PageIdUtils.pageId(1, PageMemory.FLAG_IDX, pageNum); + + long link1 = PageIdUtils.linkFromDwordOffset(pageId1, offset); + long link2 = PageIdUtils.linkFromDwordOffset(pageId2, 0); + + assertEquals(new FullPageId(link1, 1), new FullPageId(link2, 1)); + } + } + + /** * @throws Exception If failed. */ public void testRandomIds() throws Exception {
