Search in sources :

Example 1 with PagesListInitNewPageRecord

use of org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageRecord in project ignite by apache.

the class PagesList method handlePageFull.

/**
     * @param pageId Page ID.
     * @param page Page pointer.
     * @param pageAddr Page address.
     * @param io IO.
     * @param dataId Data page ID.
     * @param data Data page pointer.
     * @param dataAddr Data page address.
     * @param bucket Bucket index.
     * @throws IgniteCheckedException If failed.
     * */
private void handlePageFull(final long pageId, final long page, final long pageAddr, PagesListNodeIO io, final long dataId, final long data, final long dataAddr, int bucket) throws IgniteCheckedException {
    DataPageIO dataIO = DataPageIO.VERSIONS.forPage(dataAddr);
    // Attempt to add page failed: the node page is full.
    if (isReuseBucket(bucket)) {
        // We can put only empty data pages to reuse bucket.
        assert dataIO.isEmpty(dataAddr);
        // Change page type to index and add it as next node page to this list.
        long newDataId = PageIdUtils.changeType(dataId, FLAG_IDX);
        setupNextPage(io, pageId, pageAddr, newDataId, dataAddr);
        if (needWalDeltaRecord(pageId, page, null))
            wal.log(new PagesListSetNextRecord(cacheId, pageId, newDataId));
        if (needWalDeltaRecord(dataId, data, null))
            wal.log(new PagesListInitNewPageRecord(cacheId, dataId, io.getType(), io.getVersion(), newDataId, pageId, 0L));
        // In reuse bucket the page itself can be used as a free page.
        bucketsSize[bucket].incrementAndGet();
        updateTail(bucket, pageId, newDataId);
    } else {
        // Just allocate a new node page and add our data page there.
        final long nextId = allocatePage(null);
        final long nextPage = acquirePage(nextId);
        try {
            // Newly allocated page.
            long nextPageAddr = writeLock(nextId, nextPage);
            assert nextPageAddr != 0L;
            // Here we should never write full page, because it is known to be new.
            Boolean nextWalPlc = FALSE;
            try {
                setupNextPage(io, pageId, pageAddr, nextId, nextPageAddr);
                if (needWalDeltaRecord(pageId, page, null))
                    wal.log(new PagesListSetNextRecord(cacheId, pageId, nextId));
                int idx = io.addPage(nextPageAddr, dataId, pageSize());
                if (needWalDeltaRecord(nextId, nextPage, nextWalPlc))
                    wal.log(new PagesListInitNewPageRecord(cacheId, nextId, io.getType(), io.getVersion(), nextId, pageId, dataId));
                assert idx != -1;
                dataIO.setFreeListPageId(dataAddr, nextId);
                if (needWalDeltaRecord(dataId, data, null))
                    wal.log(new DataPageSetFreeListPageRecord(cacheId, dataId, nextId));
                bucketsSize[bucket].incrementAndGet();
                updateTail(bucket, pageId, nextId);
            } finally {
                writeUnlock(nextId, nextPage, nextPageAddr, nextWalPlc, true);
            }
        } finally {
            releasePage(nextId, nextPage);
        }
    }
}
Also used : DataPageIO(org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO) DataPageSetFreeListPageRecord(org.apache.ignite.internal.pagemem.wal.record.delta.DataPageSetFreeListPageRecord) PagesListSetNextRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord) PagesListInitNewPageRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageRecord)

Example 2 with PagesListInitNewPageRecord

use of org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageRecord in project ignite by apache.

the class PagesList method putReuseBag.

/**
     * @param pageId Page ID.
     * @param page Page pointer.
     * @param pageAddr Page address.
     * @param io IO.
     * @param bag Reuse bag.
     * @param bucket Bucket.
     * @return {@code true} If succeeded.
     * @throws IgniteCheckedException if failed.
     */
@SuppressWarnings("ForLoopReplaceableByForEach")
private boolean putReuseBag(final long pageId, final long page, final long pageAddr, PagesListNodeIO io, ReuseBag bag, int bucket) throws IgniteCheckedException {
    if (io.getNextId(pageAddr) != 0L)
        // Splitted.
        return false;
    long nextId;
    long prevId = pageId;
    long prevPage = page;
    long prevAddr = pageAddr;
    Boolean walPlc = null;
    // TODO may be unlock right away and do not keep all these pages locked?
    GridLongList locked = null;
    try {
        while ((nextId = bag.pollFreePage()) != 0L) {
            int idx = io.addPage(prevAddr, nextId, pageSize());
            if (idx == -1) {
                // Attempt to add page failed: the node page is full.
                final long nextPage = acquirePage(nextId);
                try {
                    // Page from reuse bag can't be concurrently recycled.
                    long nextPageAddr = writeLock(nextId, nextPage);
                    assert nextPageAddr != 0L;
                    if (locked == null) {
                        locked = new GridLongList(6);
                    }
                    locked.add(nextId);
                    locked.add(nextPage);
                    locked.add(nextPageAddr);
                    setupNextPage(io, prevId, prevAddr, nextId, nextPageAddr);
                    if (needWalDeltaRecord(prevId, prevPage, walPlc))
                        wal.log(new PagesListSetNextRecord(cacheId, prevId, nextId));
                    // Here we should never write full page, because it is known to be new.
                    if (needWalDeltaRecord(nextId, nextPage, FALSE))
                        wal.log(new PagesListInitNewPageRecord(cacheId, nextId, io.getType(), io.getVersion(), nextId, prevId, 0L));
                    // In reuse bucket the page itself can be used as a free page.
                    if (isReuseBucket(bucket))
                        bucketsSize[bucket].incrementAndGet();
                    // Switch to this new page, which is now a part of our list
                    // to add the rest of the bag to the new page.
                    prevAddr = nextPageAddr;
                    prevId = nextId;
                    prevPage = nextPage;
                    // Starting from tis point all wal records are written for reused pages from the bag.
                    // This mean that we use delta records only.
                    walPlc = FALSE;
                } finally {
                    releasePage(nextId, nextPage);
                }
            } else {
                // TODO: use single WAL record for bag?
                if (needWalDeltaRecord(prevId, prevPage, walPlc))
                    wal.log(new PagesListAddPageRecord(cacheId, prevId, nextId));
                bucketsSize[bucket].incrementAndGet();
            }
        }
    } finally {
        if (locked != null) {
            // We have to update our bucket with the new tail.
            updateTail(bucket, pageId, prevId);
            // Release write.
            for (int i = 0; i < locked.size(); i += 3) {
                writeUnlock(locked.get(i), locked.get(i + 1), locked.get(i + 2), FALSE, true);
            }
        }
    }
    return true;
}
Also used : PagesListAddPageRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListAddPageRecord) GridLongList(org.apache.ignite.internal.util.GridLongList) PagesListSetNextRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord) PagesListInitNewPageRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageRecord)

Aggregations

PagesListInitNewPageRecord (org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageRecord)2 PagesListSetNextRecord (org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord)2 DataPageSetFreeListPageRecord (org.apache.ignite.internal.pagemem.wal.record.delta.DataPageSetFreeListPageRecord)1 PagesListAddPageRecord (org.apache.ignite.internal.pagemem.wal.record.delta.PagesListAddPageRecord)1 DataPageIO (org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO)1 GridLongList (org.apache.ignite.internal.util.GridLongList)1