Search in sources :

Example 1 with ITreeIndexFrame

use of org.apache.hyracks.storage.am.common.api.ITreeIndexFrame in project asterixdb by apache.

the class BTreeNSMInteriorFrame method split.

@Override
public void split(ITreeIndexFrame rightFrame, ITupleReference tuple, ISplitKey splitKey, IExtraPageBlockHelper extraPageBlockHelper, IBufferCache bufferCache) throws HyracksDataException {
    ByteBuffer right = rightFrame.getBuffer();
    int tupleCount = getTupleCount();
    // Find split point, and determine into which frame the new tuple should be inserted into.
    ITreeIndexFrame targetFrame = null;
    frameTuple.resetByTupleIndex(this, tupleCount - 1);
    int tuplesToLeft;
    if (cmp.compare(tuple, frameTuple) > 0) {
        // This is a special optimization case when the tuple to be inserted is the largest key on the page.
        targetFrame = rightFrame;
        tuplesToLeft = tupleCount;
    } else {
        int totalSize = 0;
        int halfPageSize = (buf.capacity() - getPageHeaderSize()) / 2;
        int i;
        for (i = 0; i < tupleCount; ++i) {
            frameTuple.resetByTupleIndex(this, i);
            totalSize += tupleWriter.bytesRequired(frameTuple) + CHILD_PTR_SIZE + slotManager.getSlotSize();
            if (totalSize >= halfPageSize) {
                break;
            }
        }
        if (cmp.compare(tuple, frameTuple) > 0) {
            tuplesToLeft = i;
            targetFrame = rightFrame;
        } else {
            tuplesToLeft = i + 1;
            targetFrame = this;
        }
        int tuplesToRight = tupleCount - tuplesToLeft;
        // Copy entire page.
        System.arraycopy(buf.array(), 0, right.array(), 0, buf.capacity());
        // On the right page we need to copy rightmost slots to left.
        int src = rightFrame.getSlotManager().getSlotEndOff();
        int dest = rightFrame.getSlotManager().getSlotEndOff() + tuplesToLeft * rightFrame.getSlotManager().getSlotSize();
        int length = rightFrame.getSlotManager().getSlotSize() * tuplesToRight;
        System.arraycopy(right.array(), src, right.array(), dest, length);
        right.putInt(Constants.TUPLE_COUNT_OFFSET, tuplesToRight);
        // On the left page, remove the highest key and make its child pointer
        // the rightmost child pointer.
        buf.putInt(Constants.TUPLE_COUNT_OFFSET, tuplesToLeft);
    }
    // Copy the split key to be inserted.
    // We must do so because setting the new split key will overwrite the
    // old split key, and we cannot insert the existing split key at this point.
    ISplitKey savedSplitKey = splitKey.duplicate(tupleWriter.createTupleReference());
    // Set split key to be highest value in left page.
    int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
    frameTuple.resetByTupleOffset(buf.array(), tupleOff);
    int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount());
    splitKey.initData(splitKeySize);
    tupleWriter.writeTuple(frameTuple, splitKey.getBuffer(), 0);
    splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer().array(), 0);
    int deleteTupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
    frameTuple.resetByTupleOffset(buf.array(), deleteTupleOff);
    buf.putInt(RIGHT_LEAF_OFFSET, buf.getInt(getLeftChildPageOff(frameTuple)));
    buf.putInt(Constants.TUPLE_COUNT_OFFSET, tuplesToLeft - 1);
    // Compact both pages.
    rightFrame.compact();
    compact();
    // Insert the saved split key.
    int targetTupleIndex;
    // it's safe to catch this exception since it will have been caught before reaching here
    targetTupleIndex = ((BTreeNSMInteriorFrame) targetFrame).findInsertTupleIndex(savedSplitKey.getTuple());
    targetFrame.insert(savedSplitKey.getTuple(), targetTupleIndex);
}
Also used : ISplitKey(org.apache.hyracks.storage.am.common.api.ISplitKey) ITreeIndexFrame(org.apache.hyracks.storage.am.common.api.ITreeIndexFrame) ByteBuffer(java.nio.ByteBuffer)

Example 2 with ITreeIndexFrame

use of org.apache.hyracks.storage.am.common.api.ITreeIndexFrame in project asterixdb by apache.

the class BTreeUpdateSearchOperatorNodePushable method createCursor.

@Override
protected ITreeIndexCursor createCursor() {
    ITreeIndex treeIndex = (ITreeIndex) index;
    ITreeIndexFrame cursorFrame = treeIndex.getLeafFrameFactory().createFrame();
    return new BTreeRangeSearchCursor((IBTreeLeafFrame) cursorFrame, true);
}
Also used : BTreeRangeSearchCursor(org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor) ITreeIndexFrame(org.apache.hyracks.storage.am.common.api.ITreeIndexFrame) ITreeIndex(org.apache.hyracks.storage.am.common.api.ITreeIndex)

Example 3 with ITreeIndexFrame

use of org.apache.hyracks.storage.am.common.api.ITreeIndexFrame in project asterixdb by apache.

the class TreeIndexDiskOrderScanOperatorNodePushable method initialize.

@Override
public void initialize() throws HyracksDataException {
    treeIndexHelper.open();
    ITreeIndex treeIndex = (ITreeIndex) treeIndexHelper.getIndexInstance();
    try {
        ITreeIndexFrame cursorFrame = treeIndex.getLeafFrameFactory().createFrame();
        ITreeIndexCursor cursor = new TreeIndexDiskOrderScanCursor(cursorFrame);
        LocalResource resource = treeIndexHelper.getResource();
        ISearchOperationCallback searchCallback = searchCallbackFactory.createSearchOperationCallback(resource.getId(), ctx, null);
        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor(NoOpOperationCallback.INSTANCE, searchCallback);
        try {
            writer.open();
            indexAccessor.diskOrderScan(cursor);
            int fieldCount = treeIndex.getFieldCount();
            FrameTupleAppender appender = new FrameTupleAppender(new VSizeFrame(ctx));
            ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
            DataOutput dos = tb.getDataOutput();
            while (cursor.hasNext()) {
                tb.reset();
                cursor.next();
                ITupleReference frameTuple = cursor.getTuple();
                for (int i = 0; i < frameTuple.getFieldCount(); i++) {
                    dos.write(frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
                    tb.addFieldEndOffset();
                }
                FrameUtils.appendToWriter(writer, appender, tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
            }
            appender.write(writer, true);
        } catch (Throwable th) {
            writer.fail();
            throw new HyracksDataException(th);
        } finally {
            try {
                cursor.close();
            } catch (Exception cursorCloseException) {
                throw new IllegalStateException(cursorCloseException);
            } finally {
                writer.close();
            }
        }
    } catch (Throwable th) {
        treeIndexHelper.close();
        throw new HyracksDataException(th);
    }
}
Also used : ITreeIndexCursor(org.apache.hyracks.storage.am.common.api.ITreeIndexCursor) DataOutput(java.io.DataOutput) ArrayTupleBuilder(org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder) ISearchOperationCallback(org.apache.hyracks.storage.common.ISearchOperationCallback) ITreeIndexAccessor(org.apache.hyracks.storage.am.common.api.ITreeIndexAccessor) VSizeFrame(org.apache.hyracks.api.comm.VSizeFrame) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException) LocalResource(org.apache.hyracks.storage.common.LocalResource) TreeIndexDiskOrderScanCursor(org.apache.hyracks.storage.am.common.impls.TreeIndexDiskOrderScanCursor) ITreeIndexFrame(org.apache.hyracks.storage.am.common.api.ITreeIndexFrame) FrameTupleAppender(org.apache.hyracks.dataflow.common.comm.io.FrameTupleAppender) ITupleReference(org.apache.hyracks.dataflow.common.data.accessors.ITupleReference) ITreeIndex(org.apache.hyracks.storage.am.common.api.ITreeIndex)

Example 4 with ITreeIndexFrame

use of org.apache.hyracks.storage.am.common.api.ITreeIndexFrame in project asterixdb by apache.

the class BTreeFieldPrefixNSMLeafFrame method split.

@Override
public void split(ITreeIndexFrame rightFrame, ITupleReference tuple, ISplitKey splitKey, IExtraPageBlockHelper extraPageBlockHelper, IBufferCache bufferCache) throws HyracksDataException {
    BTreeFieldPrefixNSMLeafFrame rf = (BTreeFieldPrefixNSMLeafFrame) rightFrame;
    ByteBuffer right = rf.getBuffer();
    int tupleCount = getTupleCount();
    int prefixTupleCount = getPrefixTupleCount();
    // Find split point, and determine into which frame the new tuple should
    // be inserted into.
    int tuplesToLeft;
    int midSlotNum = tupleCount / 2;
    ITreeIndexFrame targetFrame = null;
    frameTuple.resetByTupleIndex(this, midSlotNum);
    int comparison = cmp.compare(tuple, frameTuple);
    if (comparison >= 0) {
        tuplesToLeft = midSlotNum + (tupleCount % 2);
        targetFrame = rf;
    } else {
        tuplesToLeft = midSlotNum;
        targetFrame = this;
    }
    int tuplesToRight = tupleCount - tuplesToLeft;
    // copy entire page
    System.arraycopy(buf.array(), 0, right.array(), 0, buf.capacity());
    // determine how many slots go on left and right page
    int prefixesToLeft = prefixTupleCount;
    for (int i = tuplesToLeft; i < tupleCount; i++) {
        int tupleSlotOff = rf.slotManager.getTupleSlotOff(i);
        int tupleSlot = right.getInt(tupleSlotOff);
        int prefixSlotNum = rf.slotManager.decodeFirstSlotField(tupleSlot);
        if (prefixSlotNum != FieldPrefixSlotManager.TUPLE_UNCOMPRESSED) {
            prefixesToLeft = prefixSlotNum;
            break;
        }
    }
    // if we are splitting in the middle of a prefix both pages need to have the prefix slot and tuple
    int boundaryTupleSlotOff = rf.slotManager.getTupleSlotOff(tuplesToLeft - 1);
    int boundaryTupleSlot = buf.getInt(boundaryTupleSlotOff);
    int boundaryPrefixSlotNum = rf.slotManager.decodeFirstSlotField(boundaryTupleSlot);
    int prefixesToRight = prefixTupleCount - prefixesToLeft;
    if (boundaryPrefixSlotNum == prefixesToLeft && boundaryPrefixSlotNum != FieldPrefixSlotManager.TUPLE_UNCOMPRESSED) {
        // tuples on both pages share one prefix
        prefixesToLeft++;
    }
    // move prefix tuples on right page to beginning of page and adjust prefix slots
    if (prefixesToRight > 0 && prefixesToLeft > 0 && prefixTupleCount > 1) {
        int freeSpace = rf.getOrigFreeSpaceOff();
        int lastPrefixSlotNum = -1;
        for (int i = tuplesToLeft; i < tupleCount; i++) {
            int tupleSlotOff = rf.slotManager.getTupleSlotOff(i);
            int tupleSlot = right.getInt(tupleSlotOff);
            int prefixSlotNum = rf.slotManager.decodeFirstSlotField(tupleSlot);
            if (prefixSlotNum != FieldPrefixSlotManager.TUPLE_UNCOMPRESSED) {
                framePrefixTuple.resetByTupleIndex(this, prefixSlotNum);
                int bytesWritten = 0;
                if (lastPrefixSlotNum != prefixSlotNum) {
                    bytesWritten = tupleWriter.writeTuple(framePrefixTuple, right.array(), freeSpace);
                    int newPrefixSlot = rf.slotManager.encodeSlotFields(framePrefixTuple.getFieldCount(), freeSpace);
                    int prefixSlotOff = rf.slotManager.getPrefixSlotOff(prefixSlotNum);
                    right.putInt(prefixSlotOff, newPrefixSlot);
                    lastPrefixSlotNum = prefixSlotNum;
                }
                int tupleOff = rf.slotManager.decodeSecondSlotField(tupleSlot);
                int newTupleSlot = rf.slotManager.encodeSlotFields(prefixSlotNum - (prefixTupleCount - prefixesToRight), tupleOff);
                right.putInt(tupleSlotOff, newTupleSlot);
                freeSpace += bytesWritten;
            }
        }
    }
    // move the modified prefix slots on the right page
    int prefixSrc = rf.slotManager.getPrefixSlotEndOff();
    int prefixDest = rf.slotManager.getPrefixSlotEndOff() + (prefixTupleCount - prefixesToRight) * rf.slotManager.getSlotSize();
    int prefixLength = rf.slotManager.getSlotSize() * prefixesToRight;
    System.arraycopy(right.array(), prefixSrc, right.array(), prefixDest, prefixLength);
    // on right page we need to copy rightmost tuple slots to left
    int src = rf.slotManager.getTupleSlotEndOff();
    int dest = rf.slotManager.getTupleSlotEndOff() + tuplesToLeft * rf.slotManager.getSlotSize() + (prefixTupleCount - prefixesToRight) * rf.slotManager.getSlotSize();
    int length = rf.slotManager.getSlotSize() * tuplesToRight;
    System.arraycopy(right.array(), src, right.array(), dest, length);
    right.putInt(ITreeIndexFrame.Constants.TUPLE_COUNT_OFFSET, tuplesToRight);
    right.putInt(PREFIX_TUPLE_COUNT_OFFSET, prefixesToRight);
    // on left page move slots to reflect possibly removed prefixes
    src = slotManager.getTupleSlotEndOff() + tuplesToRight * slotManager.getSlotSize();
    dest = slotManager.getTupleSlotEndOff() + tuplesToRight * slotManager.getSlotSize() + (prefixTupleCount - prefixesToLeft) * slotManager.getSlotSize();
    length = slotManager.getSlotSize() * tuplesToLeft;
    System.arraycopy(buf.array(), src, buf.array(), dest, length);
    buf.putInt(ITreeIndexFrame.Constants.TUPLE_COUNT_OFFSET, tuplesToLeft);
    buf.putInt(PREFIX_TUPLE_COUNT_OFFSET, prefixesToLeft);
    // compact both pages
    compact();
    rightFrame.compact();
    // insert last key
    int targetTupleIndex;
    // it's safe to catch this exception since it will have been caught before reaching here
    targetTupleIndex = ((IBTreeLeafFrame) targetFrame).findInsertTupleIndex(tuple);
    targetFrame.insert(tuple, targetTupleIndex);
    // set split key to be highest value in left page
    frameTuple.resetByTupleIndex(this, getTupleCount() - 1);
    int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount());
    splitKey.initData(splitKeySize);
    tupleWriter.writeTupleFields(frameTuple, 0, cmp.getKeyFieldCount(), splitKey.getBuffer().array(), 0);
    splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer().array(), 0);
}
Also used : ITreeIndexFrame(org.apache.hyracks.storage.am.common.api.ITreeIndexFrame) ByteBuffer(java.nio.ByteBuffer)

Example 5 with ITreeIndexFrame

use of org.apache.hyracks.storage.am.common.api.ITreeIndexFrame in project asterixdb by apache.

the class VirtualFreePageManager method init.

@Override
public void init(ITreeIndexFrameFactory interiorFrameFactory, ITreeIndexFrameFactory leafFrameFactory) throws HyracksDataException {
    currentPageId.set(1);
    ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, 0), true);
    page.acquireWriteLatch();
    page.releaseWriteLatch(false);
    bufferCache.unpin(page);
    page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, currentPageId.get()), true);
    if (leafFrameFactory != null) {
        page.acquireWriteLatch();
        ITreeIndexFrame leafFrame = leafFrameFactory.createFrame();
        leafFrame.setPage(page);
        leafFrame.initBuffer((byte) 0);
        page.releaseWriteLatch(true);
    }
    bufferCache.unpin(page);
}
Also used : ICachedPage(org.apache.hyracks.storage.common.buffercache.ICachedPage) ITreeIndexFrame(org.apache.hyracks.storage.am.common.api.ITreeIndexFrame)

Aggregations

ITreeIndexFrame (org.apache.hyracks.storage.am.common.api.ITreeIndexFrame)6 ByteBuffer (java.nio.ByteBuffer)2 HyracksDataException (org.apache.hyracks.api.exceptions.HyracksDataException)2 ITreeIndex (org.apache.hyracks.storage.am.common.api.ITreeIndex)2 ICachedPage (org.apache.hyracks.storage.common.buffercache.ICachedPage)2 DataOutput (java.io.DataOutput)1 VSizeFrame (org.apache.hyracks.api.comm.VSizeFrame)1 ArrayTupleBuilder (org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder)1 FrameTupleAppender (org.apache.hyracks.dataflow.common.comm.io.FrameTupleAppender)1 ITupleReference (org.apache.hyracks.dataflow.common.data.accessors.ITupleReference)1 BTreeRangeSearchCursor (org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor)1 ISplitKey (org.apache.hyracks.storage.am.common.api.ISplitKey)1 ITreeIndexAccessor (org.apache.hyracks.storage.am.common.api.ITreeIndexAccessor)1 ITreeIndexCursor (org.apache.hyracks.storage.am.common.api.ITreeIndexCursor)1 ITreeIndexMetadataFrame (org.apache.hyracks.storage.am.common.api.ITreeIndexMetadataFrame)1 TreeIndexDiskOrderScanCursor (org.apache.hyracks.storage.am.common.impls.TreeIndexDiskOrderScanCursor)1 ISearchOperationCallback (org.apache.hyracks.storage.common.ISearchOperationCallback)1 LocalResource (org.apache.hyracks.storage.common.LocalResource)1