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);
}
Aggregations