Search in sources :

Example 1 with PageIo

use of org.apache.ignite.internal.pagememory.io.PageIo in project ignite-3 by apache.

the class RandomLruPageReplacementPolicy method isStoreMetadataPage.

/**
 * Return {@code true} if page is related to metadata.
 *
 * @param absPageAddr Absolute page address
 */
private boolean isStoreMetadataPage(long absPageAddr) {
    try {
        long dataAddr = absPageAddr + PAGE_OVERHEAD;
        PageIo io = seg.ioRegistry().resolve(dataAddr);
        return io instanceof PagesListMetaIo;
    } catch (IgniteInternalCheckedException ignored) {
        return false;
    }
}
Also used : IgniteInternalCheckedException(org.apache.ignite.lang.IgniteInternalCheckedException) PagesListMetaIo(org.apache.ignite.internal.pagememory.freelist.io.PagesListMetaIo) PageIo(org.apache.ignite.internal.pagememory.io.PageIo)

Example 2 with PageIo

use of org.apache.ignite.internal.pagememory.io.PageIo in project ignite-3 by apache.

the class PageIoRegistryTest method testResolve.

@Test
void testResolve() throws Exception {
    // Module is not yet loaded.
    assertThrows(IgniteInternalCheckedException.class, () -> ioRegistry.resolve(TEST_PAGE_TYPE, TEST_PAGE_VER));
    // Load all PageIOModule-s from the classpath.
    ioRegistry.loadFromServiceLoader();
    // Test base resolve method.
    PageIo pageIo = ioRegistry.resolve(TEST_PAGE_TYPE, TEST_PAGE_VER);
    assertTrue(pageIo instanceof TestPageIo);
    assertEquals(TEST_PAGE_TYPE, pageIo.getType());
    assertEquals(TEST_PAGE_VER, pageIo.getVersion());
    ByteBuffer pageBuffer = ByteBuffer.allocateDirect(4);
    pageBuffer.order(GridUnsafe.NATIVE_BYTE_ORDER);
    pageBuffer.putShort(PageIo.TYPE_OFF, (short) TEST_PAGE_TYPE);
    pageBuffer.putShort(PageIo.VER_OFF, (short) TEST_PAGE_VER);
    // Test resolve from a pointer.
    assertEquals(pageIo, ioRegistry.resolve(bufferAddress(pageBuffer)));
    // Test resolve from ByteBuffer.
    assertEquals(pageIo, ioRegistry.resolve(pageBuffer));
}
Also used : TestPageIo(org.apache.ignite.internal.pagememory.TestPageIoModule.TestPageIo) ByteBuffer(java.nio.ByteBuffer) PageIo(org.apache.ignite.internal.pagememory.io.PageIo) TestPageIo(org.apache.ignite.internal.pagememory.TestPageIoModule.TestPageIo) Test(org.junit.jupiter.api.Test)

Example 3 with PageIo

use of org.apache.ignite.internal.pagememory.io.PageIo in project ignite-3 by apache.

the class PagesList method takeEmptyPage.

/**
 * Takes empty page from free list.
 *
 * @param bucket Bucket index.
 * @param initIoVers Optional IO to initialize page.
 * @param statHolder Statistics holder to track IO operations.
 * @return Removed page ID.
 * @throws IgniteInternalCheckedException If failed.
 */
protected long takeEmptyPage(int bucket, @Nullable IoVersions<?> initIoVers, IoStatisticsHolder statHolder) throws IgniteInternalCheckedException {
    PagesCache pagesCache = getBucketCache(bucket, false);
    long pageId;
    if (pagesCache != null && (pageId = pagesCache.poll()) != 0L) {
        decrementBucketSize(bucket);
        if (log.isDebugEnabled()) {
            log.debug("Take page from pages list cache [list=" + name() + ", bucket=" + bucket + ", pageId=" + pageId + ']');
        }
        assert !isReuseBucket(bucket) : "reuse bucket detected";
        return pageId;
    }
    for (int lockAttempt = 0; ; ) {
        Stripe stripe = getStripeForTake(bucket);
        if (stripe == null) {
            return 0L;
        }
        final long tailId = stripe.tailId;
        // Stripe was removed from bucket concurrently.
        if (tailId == 0L) {
            continue;
        }
        final long tailPage = acquirePage(tailId, statHolder);
        try {
            // Explicit check.
            long tailAddr = writeLockPage(tailId, tailPage, bucket, lockAttempt++, null);
            if (tailAddr == 0L) {
                continue;
            }
            if (stripe.empty || stripe.tailId != tailId) {
                // Another thread took the last page.
                writeUnlock(tailId, tailPage, tailAddr, false);
                if (bucketsSize.get(bucket) > 0) {
                    // Ignore current attempt.
                    lockAttempt--;
                    continue;
                } else {
                    return 0L;
                }
            }
            assert getPageId(tailAddr) == tailId : "tailId = " + hexLong(tailId) + ", pageId = " + hexLong(getPageId(tailAddr));
            assert getType(tailAddr) == T_PAGE_LIST_NODE : "tailId = " + hexLong(tailId) + ", type = " + getType(tailAddr);
            boolean dirty = false;
            long dataPageId;
            long recycleId = 0L;
            try {
                PagesListNodeIo io = PagesListNodeIo.VERSIONS.forPage(tailAddr);
                if (io.getNextId(tailAddr) != 0) {
                    // It is not a tail anymore, retry.
                    continue;
                }
                pageId = io.takeAnyPage(tailAddr);
                if (pageId != 0L) {
                    decrementBucketSize(bucket);
                    dirty = true;
                    if (isReuseBucket(bucket) && !(itemId(pageId) > 0 && itemId(pageId) <= MAX_ITEMID_NUM)) {
                        throw corruptedFreeListException("Incorrectly recycled pageId in reuse bucket: " + hexLong(pageId), pageId);
                    }
                    if (isReuseBucket(bucket)) {
                        byte flag = getFlag(initIoVers);
                        PageIo initIo = initIoVers == null ? null : initIoVers.latest();
                        dataPageId = initRecycledPage0(pageId, flag, initIo);
                    } else {
                        dataPageId = pageId;
                    }
                    if (io.isEmpty(tailAddr)) {
                        long prevId = io.getPreviousId(tailAddr);
                        // to prevent empty page leak to data pages.
                        if (!isReuseBucket(bucket)) {
                            if (prevId != 0L) {
                                Boolean ok = write(prevId, cutTail, null, bucket, FALSE, statHolder);
                                assert ok == TRUE : ok;
                                recycleId = recyclePage(tailId, tailAddr);
                            } else {
                                stripe.empty = true;
                            }
                        } else {
                            stripe.empty = prevId == 0L;
                        }
                    }
                } else {
                    // a previous page, so, the current page can be collected
                    assert isReuseBucket(bucket);
                    long prevId = io.getPreviousId(tailAddr);
                    assert prevId != 0L;
                    Boolean ok = write(prevId, cutTail, bucket, FALSE, statHolder);
                    assert ok == TRUE : ok;
                    decrementBucketSize(bucket);
                    byte flag = getFlag(initIoVers);
                    PageIo pageIo = initIoVers != null ? initIoVers.latest() : null;
                    dataPageId = initReusedPage(tailId, tailAddr, partitionId(tailId), flag, pageIo);
                    dirty = true;
                }
            // If we do not have a previous page (we are at head), then we still can return
            // current page but we have to drop the whole stripe. Since it is a reuse bucket,
            // we will not do that, but just return 0L, because this may produce contention on
            // meta page.
            } finally {
                writeUnlock(tailId, tailPage, tailAddr, dirty);
            }
            // Put recycled page (if any) to the reuse bucket after tail is unlocked.
            if (recycleId != 0L) {
                assert !isReuseBucket(bucket);
                reuseList.addForRecycle(new SingletonReuseBag(recycleId));
            }
            if (log.isDebugEnabled()) {
                log.debug("Take page from pages list [list=" + name() + ", bucket=" + bucket + ", dataPageId=" + dataPageId + ", tailId=" + tailId + ']');
            }
            return dataPageId;
        } finally {
            releasePage(tailId, tailPage);
        }
    }
}
Also used : PagesListNodeIo(org.apache.ignite.internal.pagememory.freelist.io.PagesListNodeIo) IgniteSystemProperties.getBoolean(org.apache.ignite.lang.IgniteSystemProperties.getBoolean) PageIo(org.apache.ignite.internal.pagememory.io.PageIo) AbstractDataPageIo(org.apache.ignite.internal.pagememory.io.AbstractDataPageIo)

Aggregations

PageIo (org.apache.ignite.internal.pagememory.io.PageIo)3 ByteBuffer (java.nio.ByteBuffer)1 TestPageIo (org.apache.ignite.internal.pagememory.TestPageIoModule.TestPageIo)1 PagesListMetaIo (org.apache.ignite.internal.pagememory.freelist.io.PagesListMetaIo)1 PagesListNodeIo (org.apache.ignite.internal.pagememory.freelist.io.PagesListNodeIo)1 AbstractDataPageIo (org.apache.ignite.internal.pagememory.io.AbstractDataPageIo)1 IgniteInternalCheckedException (org.apache.ignite.lang.IgniteInternalCheckedException)1 IgniteSystemProperties.getBoolean (org.apache.ignite.lang.IgniteSystemProperties.getBoolean)1 Test (org.junit.jupiter.api.Test)1