Search in sources :

Example 1 with ISplitKey

use of org.apache.hyracks.storage.am.common.api.ISplitKey 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)

Aggregations

ByteBuffer (java.nio.ByteBuffer)1 ISplitKey (org.apache.hyracks.storage.am.common.api.ISplitKey)1 ITreeIndexFrame (org.apache.hyracks.storage.am.common.api.ITreeIndexFrame)1