Search in sources :

Example 1 with FrameOpSpaceStatus

use of org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus in project asterixdb by apache.

the class RTree method insertTuple.

private void insertTuple(ICachedPage node, int pageId, ITupleReference tuple, RTreeOpContext ctx, boolean isLeaf) throws HyracksDataException {
    boolean succeeded = false;
    FrameOpSpaceStatus spaceStatus;
    if (!isLeaf) {
        spaceStatus = ctx.getInteriorFrame().hasSpaceInsert(tuple);
    } else {
        spaceStatus = ctx.getLeafFrame().hasSpaceInsert(tuple);
    }
    switch(spaceStatus) {
        case SUFFICIENT_CONTIGUOUS_SPACE:
            {
                try {
                    if (!isLeaf) {
                        ctx.getInteriorFrame().insert(tuple, -1);
                    } else {
                        ctx.getModificationCallback().found(null, tuple);
                        ctx.getLeafFrame().insert(tuple, -1);
                    }
                    succeeded = true;
                } finally {
                    if (succeeded) {
                        ctx.getLSNUpdates().add(node);
                        ctx.getSplitKey().reset();
                    } else if (isLeaf) {
                        // In case of a crash, we un-latch the interior node
                        // inside updateParentForInsert.
                        node.releaseWriteLatch(true);
                        bufferCache.unpin(node);
                    }
                }
                break;
            }
        case SUFFICIENT_SPACE:
            {
                try {
                    if (!isLeaf) {
                        ctx.getInteriorFrame().compact();
                        ctx.getInteriorFrame().insert(tuple, -1);
                    } else {
                        ctx.getLeafFrame().compact();
                        ctx.getModificationCallback().found(null, tuple);
                        ctx.getLeafFrame().insert(tuple, -1);
                    }
                    succeeded = true;
                } finally {
                    if (succeeded) {
                        ctx.getLSNUpdates().add(node);
                        ctx.getSplitKey().reset();
                    } else if (isLeaf) {
                        // In case of a crash, we un-latch the interior node
                        // inside updateParentForInsert.
                        node.releaseWriteLatch(true);
                        bufferCache.unpin(node);
                    }
                }
                break;
            }
        case INSUFFICIENT_SPACE:
            {
                int rightPageId = freePageManager.takePage(ctx.getMetaFrame());
                ICachedPage rightNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rightPageId), true);
                rightNode.acquireWriteLatch();
                try {
                    IRTreeFrame rightFrame;
                    if (!isLeaf) {
                        rightFrame = (IRTreeFrame) interiorFrameFactory.createFrame();
                        rightFrame.setPage(rightNode);
                        rightFrame.initBuffer(ctx.getInteriorFrame().getLevel());
                        rightFrame.setRightPage(ctx.getInteriorFrame().getRightPage());
                        ctx.getInteriorFrame().split(rightFrame, tuple, ctx.getSplitKey(), ctx, bufferCache);
                        ctx.getInteriorFrame().setRightPage(rightPageId);
                    } else {
                        rightFrame = (IRTreeFrame) leafFrameFactory.createFrame();
                        rightFrame.setPage(rightNode);
                        rightFrame.initBuffer((byte) 0);
                        rightFrame.setRightPage(ctx.getInteriorFrame().getRightPage());
                        ctx.getModificationCallback().found(null, tuple);
                        ctx.getLeafFrame().split(rightFrame, tuple, ctx.getSplitKey(), ctx, bufferCache);
                        ctx.getLeafFrame().setRightPage(rightPageId);
                    }
                    succeeded = true;
                } finally {
                    if (succeeded) {
                        ctx.getNSNUpdates().add(rightNode);
                        ctx.getLSNUpdates().add(rightNode);
                        ctx.getNSNUpdates().add(node);
                        ctx.getLSNUpdates().add(node);
                    } else if (isLeaf) {
                        // In case of a crash, we un-latch the interior node
                        // inside updateParentForInsert.
                        node.releaseWriteLatch(true);
                        bufferCache.unpin(node);
                        rightNode.releaseWriteLatch(true);
                        bufferCache.unpin(rightNode);
                    } else {
                        rightNode.releaseWriteLatch(true);
                        bufferCache.unpin(rightNode);
                    }
                }
                ctx.getSplitKey().setPages(pageId, rightPageId);
                if (pageId == rootPage) {
                    int newLeftId = freePageManager.takePage(ctx.getMetaFrame());
                    ICachedPage newLeftNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, newLeftId), true);
                    newLeftNode.acquireWriteLatch();
                    succeeded = false;
                    try {
                        // copy left child to new left child
                        System.arraycopy(node.getBuffer().array(), 0, newLeftNode.getBuffer().array(), 0, newLeftNode.getBuffer().capacity());
                        // initialize new root (leftNode becomes new root)
                        ctx.getInteriorFrame().setPage(node);
                        ctx.getInteriorFrame().initBuffer((byte) (ctx.getInteriorFrame().getLevel() + 1));
                        ctx.getSplitKey().setLeftPage(newLeftId);
                        ctx.getInteriorFrame().insert(ctx.getSplitKey().getLeftTuple(), -1);
                        ctx.getInteriorFrame().insert(ctx.getSplitKey().getRightTuple(), -1);
                        succeeded = true;
                    } finally {
                        if (succeeded) {
                            ctx.getNSNUpdates().remove(ctx.getNSNUpdates().size() - 1);
                            ctx.getLSNUpdates().remove(ctx.getLSNUpdates().size() - 1);
                            ctx.getNSNUpdates().add(newLeftNode);
                            ctx.getLSNUpdates().add(newLeftNode);
                            ctx.getNSNUpdates().add(node);
                            ctx.getLSNUpdates().add(node);
                            ctx.getSplitKey().reset();
                        } else if (isLeaf) {
                            // In case of a crash, we un-latch the interior node
                            // inside updateParentForInsert.
                            node.releaseWriteLatch(true);
                            bufferCache.unpin(node);
                            rightNode.releaseWriteLatch(true);
                            bufferCache.unpin(rightNode);
                            newLeftNode.releaseWriteLatch(true);
                            bufferCache.unpin(newLeftNode);
                        } else {
                            rightNode.releaseWriteLatch(true);
                            bufferCache.unpin(rightNode);
                            newLeftNode.releaseWriteLatch(true);
                            bufferCache.unpin(newLeftNode);
                        }
                    }
                }
                break;
            }
        default:
            {
                throw new IllegalStateException("NYI: " + spaceStatus);
            }
    }
}
Also used : ICachedPage(org.apache.hyracks.storage.common.buffercache.ICachedPage) IRTreeFrame(org.apache.hyracks.storage.am.rtree.api.IRTreeFrame) FrameOpSpaceStatus(org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus)

Example 2 with FrameOpSpaceStatus

use of org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus in project asterixdb by apache.

the class BTreeNSMLeafFrame method hasSpaceUpdate.

@Override
public FrameOpSpaceStatus hasSpaceUpdate(ITupleReference newTuple, int oldTupleIndex) {
    frameTuple.resetByTupleIndex(this, oldTupleIndex);
    int oldTupleBytes = frameTuple.getTupleSize();
    int newTupleBytes = tupleWriter.bytesRequired(newTuple);
    FrameOpSpaceStatus status = hasSpaceUpdate(oldTupleBytes, newTupleBytes);
    if (status == FrameOpSpaceStatus.INSUFFICIENT_SPACE && (getLargeFlag() || getTupleCount() == 1) && isLargeTuple(newTupleBytes)) {
        return FrameOpSpaceStatus.EXPAND;
    }
    return status;
}
Also used : FrameOpSpaceStatus(org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus)

Example 3 with FrameOpSpaceStatus

use of org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus in project asterixdb by apache.

the class BTree method updateLeaf.

private boolean updateLeaf(ITupleReference tuple, int oldTupleIndex, int pageId, BTreeOpContext ctx) throws Exception {
    FrameOpSpaceStatus spaceStatus = ctx.getLeafFrame().hasSpaceUpdate(tuple, oldTupleIndex);
    ITupleReference beforeTuple = ctx.getLeafFrame().getMatchingKeyTuple(tuple, oldTupleIndex);
    boolean restartOp = false;
    switch(spaceStatus) {
        case SUFFICIENT_INPLACE_SPACE:
            {
                ctx.getModificationCallback().found(beforeTuple, tuple);
                ctx.getLeafFrame().update(tuple, oldTupleIndex, true);
                ctx.getSplitKey().reset();
                break;
            }
        case EXPAND:
            {
                // TODO: avoid repeated calculation of tuple size
                // TODO: in-place update on expand
                // Delete the old tuple, compact the frame, and insert the new tuple.
                ctx.getModificationCallback().found(beforeTuple, tuple);
                ctx.getLeafFrame().delete(tuple, oldTupleIndex);
                ctx.getLeafFrame().compact();
                ctx.getLeafFrame().ensureCapacity(bufferCache, tuple, ctx);
                int targetTupleIndex = ctx.getLeafFrame().findInsertTupleIndex(tuple);
                ctx.getLeafFrame().insert(tuple, targetTupleIndex);
                ctx.getSplitKey().reset();
                break;
            }
        case SUFFICIENT_CONTIGUOUS_SPACE:
            {
                ctx.getModificationCallback().found(beforeTuple, tuple);
                ctx.getLeafFrame().update(tuple, oldTupleIndex, false);
                ctx.getSplitKey().reset();
                break;
            }
        case SUFFICIENT_SPACE:
            {
                // Delete the old tuple, compact the frame, and insert the new tuple.
                ctx.getModificationCallback().found(beforeTuple, tuple);
                ctx.getLeafFrame().delete(tuple, oldTupleIndex);
                ctx.getLeafFrame().compact();
                int targetTupleIndex = ctx.getLeafFrame().findInsertTupleIndex(tuple);
                ctx.getLeafFrame().insert(tuple, targetTupleIndex);
                ctx.getSplitKey().reset();
                break;
            }
        case INSUFFICIENT_SPACE:
            {
                restartOp = performLeafSplit(pageId, tuple, ctx, oldTupleIndex);
                break;
            }
        default:
            {
                throw new IllegalStateException("NYI: " + spaceStatus);
            }
    }
    return restartOp;
}
Also used : ITupleReference(org.apache.hyracks.dataflow.common.data.accessors.ITupleReference) FrameOpSpaceStatus(org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus)

Example 4 with FrameOpSpaceStatus

use of org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus in project asterixdb by apache.

the class BTree method insertLeaf.

private boolean insertLeaf(ITupleReference tuple, int targetTupleIndex, int pageId, BTreeOpContext ctx) throws Exception {
    boolean restartOp = false;
    FrameOpSpaceStatus spaceStatus = ctx.getLeafFrame().hasSpaceInsert(tuple);
    switch(spaceStatus) {
        case EXPAND:
            {
                // TODO: avoid repeated calculation of tuple size
                ctx.getLeafFrame().ensureCapacity(bufferCache, tuple, ctx);
            }
        // fall-through
        case SUFFICIENT_CONTIGUOUS_SPACE:
            {
                ctx.getModificationCallback().found(null, tuple);
                ctx.getLeafFrame().insert(tuple, targetTupleIndex);
                ctx.getSplitKey().reset();
                break;
            }
        case SUFFICIENT_SPACE:
            {
                int finalIndex = ctx.getLeafFrame().compact() ? ctx.getLeafFrame().findInsertTupleIndex(tuple) : targetTupleIndex;
                ctx.getModificationCallback().found(null, tuple);
                ctx.getLeafFrame().insert(tuple, finalIndex);
                ctx.getSplitKey().reset();
                break;
            }
        case INSUFFICIENT_SPACE:
            {
                // Try compressing the page first and see if there is space available.
                if (ctx.getLeafFrame().compress() && ctx.getLeafFrame().hasSpaceInsert(tuple) == FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE) {
                    ctx.getModificationCallback().found(null, tuple);
                    ctx.getLeafFrame().insert(tuple, ctx.getLeafFrame().findInsertTupleIndex(tuple));
                    ctx.getSplitKey().reset();
                } else {
                    restartOp = performLeafSplit(pageId, tuple, ctx, -1);
                }
                break;
            }
        default:
            {
                throw new IllegalStateException("NYI: " + spaceStatus);
            }
    }
    return restartOp;
}
Also used : FrameOpSpaceStatus(org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus)

Example 5 with FrameOpSpaceStatus

use of org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus in project asterixdb by apache.

the class BTree method insertInterior.

private void insertInterior(ICachedPage node, int pageId, ITupleReference tuple, BTreeOpContext ctx) throws Exception {
    ctx.getInteriorFrame().setPage(node);
    int targetTupleIndex = ctx.getInteriorFrame().findInsertTupleIndex(tuple);
    FrameOpSpaceStatus spaceStatus = ctx.getInteriorFrame().hasSpaceInsert(tuple);
    switch(spaceStatus) {
        case INSUFFICIENT_SPACE:
            {
                int rightPageId = freePageManager.takePage(ctx.getMetaFrame());
                ICachedPage rightNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rightPageId), true);
                rightNode.acquireWriteLatch();
                try {
                    IBTreeFrame rightFrame = ctx.createInteriorFrame();
                    rightFrame.setPage(rightNode);
                    rightFrame.initBuffer(ctx.getInteriorFrame().getLevel());
                    rightFrame.setMultiComparator(ctx.getCmp());
                    // instead of creating a new split key, use the existing
                    // splitKey
                    ctx.getInteriorFrame().split(rightFrame, ctx.getSplitKey().getTuple(), ctx.getSplitKey(), ctx, bufferCache);
                    ctx.getSmPages().add(pageId);
                    ctx.getSmPages().add(rightPageId);
                    ctx.getInteriorFrame().setSmFlag(true);
                    rightFrame.setSmFlag(true);
                    rightFrame.setPageLsn(rightFrame.getPageLsn() + 1);
                    ctx.getInteriorFrame().setPageLsn(ctx.getInteriorFrame().getPageLsn() + 1);
                    ctx.getSplitKey().setPages(pageId, rightPageId);
                } finally {
                    rightNode.releaseWriteLatch(true);
                    bufferCache.unpin(rightNode);
                }
                break;
            }
        case SUFFICIENT_CONTIGUOUS_SPACE:
            {
                ctx.getInteriorFrame().insert(tuple, targetTupleIndex);
                ctx.getSplitKey().reset();
                break;
            }
        case SUFFICIENT_SPACE:
            {
                boolean slotsChanged = ctx.getInteriorFrame().compact();
                if (slotsChanged) {
                    targetTupleIndex = ctx.getInteriorFrame().findInsertTupleIndex(tuple);
                }
                ctx.getInteriorFrame().insert(tuple, targetTupleIndex);
                ctx.getSplitKey().reset();
                break;
            }
        case TOO_LARGE:
            {
                int tupleSize = ctx.getInteriorFrame().getBytesRequiredToWriteTuple(tuple);
                throw HyracksDataException.create(ErrorCode.RECORD_IS_TOO_LARGE, tupleSize, maxTupleSize);
            }
        default:
            {
                throw new IllegalStateException("NYI: " + spaceStatus);
            }
    }
}
Also used : ICachedPage(org.apache.hyracks.storage.common.buffercache.ICachedPage) FrameOpSpaceStatus(org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus) IBTreeFrame(org.apache.hyracks.storage.am.btree.api.IBTreeFrame)

Aggregations

FrameOpSpaceStatus (org.apache.hyracks.storage.am.common.frames.FrameOpSpaceStatus)5 ICachedPage (org.apache.hyracks.storage.common.buffercache.ICachedPage)2 ITupleReference (org.apache.hyracks.dataflow.common.data.accessors.ITupleReference)1 IBTreeFrame (org.apache.hyracks.storage.am.btree.api.IBTreeFrame)1 IRTreeFrame (org.apache.hyracks.storage.am.rtree.api.IRTreeFrame)1