@Override public void delete(int tupleIndex, MultiComparator cmp) { int slotOff = slotManager.getSlotOff(tupleIndex); int tupleOff = slotManager.getTupleOff(slotOff); frameTuple.resetByTupleOffset(buf.array(), tupleOff); int tupleSize = tupleWriter.bytesRequired(frameTuple); // perform deletion (we just do a memcpy to overwrite the slot) int slotStartOff = slotManager.getSlotEndOff(); int length = slotOff - slotStartOff; System.arraycopy(buf.array(), slotStartOff, buf.array(), slotStartOff + slotManager.getSlotSize(), length); // maintain space information buf.putInt(Constants.TUPLE_COUNT_OFFSET, buf.getInt(Constants.TUPLE_COUNT_OFFSET) - 1); buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) + tupleSize + slotManager.getSlotSize()); }
@Override public void insert(ITupleReference tuple, int tupleIndex) { int freeSpace = buf.getInt(Constants.FREE_SPACE_OFFSET); slotManager.insertSlot(tupleIndex, freeSpace); int bytesWritten = tupleWriter.writeTuple(tuple, buf.array(), freeSpace); buf.putInt(Constants.TUPLE_COUNT_OFFSET, buf.getInt(Constants.TUPLE_COUNT_OFFSET) + 1); buf.putInt(Constants.FREE_SPACE_OFFSET, buf.getInt(Constants.FREE_SPACE_OFFSET) + bytesWritten); buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) - bytesWritten - slotManager.getSlotSize()); }
@Override public int findUpdateTupleIndex(ITupleReference tuple) throws HyracksDataException { int tupleIndex; tupleIndex = slotManager.findTupleIndex(tuple, frameTuple, cmp, FindTupleMode.EXACT, FindTupleNoExactMatchPolicy.HIGHER_KEY); // Error indicator is set if there is no exact match. if (tupleIndex == slotManager.getErrorIndicator() || tupleIndex == slotManager.getGreatestKeyIndicator()) { throw HyracksDataException.create(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY); } return tupleIndex; }
@Override public int getTupleOffset(int slotNum) { return slotManager.getTupleOff(slotManager.getSlotStartOff() - slotNum * slotManager.getSlotSize()); }
@Override public int findInsertTupleIndex(ITupleReference tuple) throws HyracksDataException { int tupleIndex; tupleIndex = slotManager.findTupleIndex(tuple, frameTuple, cmp, FindTupleMode.EXCLUSIVE_ERROR_IF_EXISTS, FindTupleNoExactMatchPolicy.HIGHER_KEY); // Error indicator is set if there is an exact match. if (tupleIndex == slotManager.getErrorIndicator()) { throw HyracksDataException.create(ErrorCode.DUPLICATE_KEY); } return tupleIndex; }
@Override public boolean compact() { resetSpaceParams(); int tupleCount = buf.getInt(Constants.TUPLE_COUNT_OFFSET); int freeSpace = buf.getInt(Constants.FREE_SPACE_OFFSET); ArrayList<SlotOffTupleOff> sortedTupleOffs = new ArrayList<>(); sortedTupleOffs.ensureCapacity(tupleCount); for (int i = 0; i < tupleCount; i++) { int slotOff = slotManager.getSlotOff(i); int tupleOff = slotManager.getTupleOff(slotOff); sortedTupleOffs.add(new SlotOffTupleOff(i, slotOff, tupleOff)); } Collections.sort(sortedTupleOffs); for (int i = 0; i < sortedTupleOffs.size(); i++) { int tupleOff = sortedTupleOffs.get(i).tupleOff; frameTuple.resetByTupleOffset(buf.array(), tupleOff); int tupleEndOff = frameTuple.getFieldStart(frameTuple.getFieldCount() - 1) + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1); int tupleLength = tupleEndOff - tupleOff + childPtrSize; System.arraycopy(buf.array(), tupleOff, buf.array(), freeSpace, tupleLength); slotManager.setSlot(sortedTupleOffs.get(i).slotOff, freeSpace); freeSpace += tupleLength; } buf.putInt(Constants.FREE_SPACE_OFFSET, freeSpace); buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.capacity() - freeSpace - tupleCount * slotManager.getSlotSize()); return false; }
@Override public void deleteGreatest() { int slotOff = slotManager.getSlotEndOff(); int tupleOff = slotManager.getTupleOff(slotOff); frameTuple.resetByTupleOffset(buf.array(), tupleOff); int keySize = tupleWriter.bytesRequired(frameTuple); System.arraycopy(buf.array(), tupleOff + keySize, buf.array(), RIGHT_LEAF_OFFSET, CHILD_PTR_SIZE); // Maintain space information. buf.putInt(Constants.TUPLE_COUNT_OFFSET, buf.getInt(Constants.TUPLE_COUNT_OFFSET) - 1); buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) + keySize + CHILD_PTR_SIZE + slotManager.getSlotSize()); int freeSpace = buf.getInt(Constants.FREE_SPACE_OFFSET); if (freeSpace == tupleOff + keySize + CHILD_PTR_SIZE) { buf.putInt(freeSpace, freeSpace - (keySize + CHILD_PTR_SIZE)); } }
slotManager.findTupleIndex(tuple, frameTuple, targetCmp, fsm, FindTupleNoExactMatchPolicy.HIGHER_KEY); int slotOff = slotManager.getSlotOff(tupleIndex); if (tupleIndex == slotManager.getGreatestKeyIndicator()) { return buf.getInt(RIGHT_LEAF_OFFSET); int origTupleOff = slotManager.getTupleOff(slotOff); cmpFrameTuple.resetByTupleOffset(buf.array(), origTupleOff); int cmpTupleOff = origTupleOff; slotOff += slotManager.getSlotSize(); while (slotOff < maxSlotOff) { cmpTupleOff = slotManager.getTupleOff(slotOff); frameTuple.resetByTupleOffset(buf.array(), cmpTupleOff); if (targetCmp.compare(cmpFrameTuple, frameTuple) != 0) { break; slotOff += slotManager.getSlotSize(); slotOff -= slotManager.getSlotSize(); frameTuple.resetByTupleOffset(buf.array(), slotManager.getTupleOff(slotOff)); int childPageOff = getLeftChildPageOff(frameTuple);
@Override public void insert(ITupleReference tuple, int tupleIndex) { int slotOff = slotManager.insertSlot(tupleIndex, buf.getInt(Constants.FREE_SPACE_OFFSET)); int freeSpace = buf.getInt(Constants.FREE_SPACE_OFFSET); int bytesWritten = tupleWriter.writeTupleFields(tuple, 0, tuple.getFieldCount(), buf.array(), freeSpace); System.arraycopy(tuple.getFieldData(tuple.getFieldCount() - 1), getLeftChildPageOff(tuple), buf.array(), freeSpace + bytesWritten, CHILD_PTR_SIZE); int tupleSize = bytesWritten + CHILD_PTR_SIZE; buf.putInt(Constants.TUPLE_COUNT_OFFSET, buf.getInt(Constants.TUPLE_COUNT_OFFSET) + 1); buf.putInt(Constants.FREE_SPACE_OFFSET, buf.getInt(Constants.FREE_SPACE_OFFSET) + tupleSize); buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) - tupleSize - slotManager.getSlotSize()); // Did we insert into the rightmost slot? if (slotOff == slotManager.getSlotEndOff()) { System.arraycopy(tuple.getFieldData(tuple.getFieldCount() - 1), getLeftChildPageOff(tuple) + CHILD_PTR_SIZE, buf.array(), RIGHT_LEAF_OFFSET, CHILD_PTR_SIZE); } else { // If slotOff has a right (slot-)neighbor then update its child pointer. // The only time when this is NOT the case, is when this is the very first tuple // (or when the splitkey goes into the rightmost slot but that case is handled in the if above). if (buf.getInt(Constants.TUPLE_COUNT_OFFSET) > 1) { int rightNeighborOff = slotOff - slotManager.getSlotSize(); frameTuple.resetByTupleOffset(buf.array(), slotManager.getTupleOff(rightNeighborOff)); System.arraycopy(tuple.getFieldData(0), getLeftChildPageOff(tuple) + CHILD_PTR_SIZE, buf.array(), getLeftChildPageOff(frameTuple), CHILD_PTR_SIZE); } } }
@Override public int getSlotSize() { return slotManager.getSlotSize(); }
private void growCapacity(IExtraPageBlockHelper extraPageBlockHelper, IBufferCache bufferCache, int deltaPages) throws HyracksDataException { int framePagesOld = page.getFrameSizeMultiplier(); int newMultiplier = framePagesOld + deltaPages; // we need to get the old slot offsets before we grow int oldSlotEnd = slotManager.getSlotEndOff(); int oldSlotStart = slotManager.getSlotStartOff() + slotManager.getSlotSize(); bufferCache.resizePage(getPage(), newMultiplier, extraPageBlockHelper); buf = getPage().getBuffer(); // fixup the slots System.arraycopy(buf.array(), oldSlotEnd, buf.array(), slotManager.getSlotEndOff(), oldSlotStart - oldSlotEnd); // fixup total free space counter buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) + (bufferCache.getPageSize() * deltaPages)); }
@Override public void insertSorted(ITupleReference tuple) { int freeSpace = buf.getInt(Constants.FREE_SPACE_OFFSET); slotManager.insertSlot(slotManager.getGreatestKeyIndicator(), freeSpace); int bytesWritten = tupleWriter.writeTuple(tuple, buf, freeSpace); System.arraycopy(tuple.getFieldData(tuple.getFieldCount() - 1), getLeftChildPageOff(tuple), buf.array(), freeSpace + bytesWritten, CHILD_PTR_SIZE); int tupleSize = bytesWritten + CHILD_PTR_SIZE; buf.putInt(Constants.TUPLE_COUNT_OFFSET, buf.getInt(Constants.TUPLE_COUNT_OFFSET) + 1); buf.putInt(Constants.FREE_SPACE_OFFSET, buf.getInt(Constants.FREE_SPACE_OFFSET) + tupleSize); buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) - tupleSize - slotManager.getSlotSize()); System.arraycopy(tuple.getFieldData(0), getLeftChildPageOff(tuple) + CHILD_PTR_SIZE, buf.array(), RIGHT_LEAF_OFFSET, CHILD_PTR_SIZE); }
public ArrayList<Integer> getChildren(MultiComparator cmp) { ArrayList<Integer> ret = new ArrayList<>(); frameTuple.setFieldCount(cmp.getKeyFieldCount()); int tupleCount = buf.getInt(Constants.TUPLE_COUNT_OFFSET); for (int i = 0; i < tupleCount; i++) { int tupleOff = slotManager.getTupleOff(slotManager.getSlotOff(i)); frameTuple.resetByTupleOffset(buf.array(), tupleOff); int intVal = IntegerPointable.getInteger(buf.array(), frameTuple.getFieldStart(frameTuple.getFieldCount() - 1) + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1)); ret.add(intVal); } return ret; }
@Override public int getLeftmostChildPageId() { int tupleOff = slotManager.getTupleOff(slotManager.getSlotStartOff()); frameTuple.resetByTupleOffset(buf.array(), tupleOff); int childPageOff = getLeftChildPageOff(frameTuple); return buf.getInt(childPageOff); }
@Override public int findDeleteTupleIndex(ITupleReference tuple) throws HyracksDataException { return slotManager.findTupleIndex(tuple, frameTuple, cmp, FindTupleMode.INCLUSIVE, FindTupleNoExactMatchPolicy.HIGHER_KEY); }
@Override public void insertSorted(ITupleReference tuple) { insert(tuple, slotManager.getGreatestKeyIndicator()); }
@Override public void update(ITupleReference newTuple, int oldTupleIndex, boolean inPlace) { frameTuple.resetByTupleIndex(this, oldTupleIndex); int oldTupleBytes = frameTuple.getTupleSize(); int slotOff = slotManager.getSlotOff(oldTupleIndex); int bytesWritten = 0; if (inPlace) { // Overwrite the old tuple in place. bytesWritten = tupleWriter.writeTuple(newTuple, buf.array(), buf.getInt(slotOff)); } else { // Insert the new tuple at the end of the free space, and change the // slot value (effectively "deleting" the old tuple). int newTupleOff = buf.getInt(Constants.FREE_SPACE_OFFSET); bytesWritten = tupleWriter.writeTuple(newTuple, buf.array(), newTupleOff); // Update slot value. buf.putInt(slotOff, newTupleOff); // Update contiguous free space pointer. buf.putInt(Constants.FREE_SPACE_OFFSET, newTupleOff + bytesWritten); } buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) + oldTupleBytes - bytesWritten); }
sortedTupleOffs.ensureCapacity(tupleCount); for (int i = 0; i < tupleCount; i++) { int slotOff = slotManager.getSlotOff(i); int tupleOff = slotManager.getTupleOff(slotOff); sortedTupleOffs.add(new SlotOffTupleOff(i, slotOff, tupleOff)); int tupleLength = tupleEndOff - tupleOff + CHILD_PTR_SIZE; System.arraycopy(buf.array(), tupleOff, buf.array(), freeSpace, tupleLength); slotManager.setSlot(sortedTupleOffs.get(i).slotOff, freeSpace); freeSpace += tupleLength; buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.capacity() - freeSpace - tupleCount * slotManager.getSlotSize()); return false;
for (i = 0; i < tupleCount; ++i) { frameTuple.resetByTupleIndex(this, i); totalSize += tupleWriter.bytesRequired(frameTuple) + CHILD_PTR_SIZE + slotManager.getSlotSize(); if (totalSize >= halfPageSize) { break; 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); int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff()); frameTuple.resetByTupleOffset(buf.array(), tupleOff); int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount()); 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)));
public FrameOpSpaceStatus hasSpaceInsert(int bytesRequired) { if (bytesRequired + slotManager.getSlotSize() <= buf.capacity() - buf.getInt(Constants.FREE_SPACE_OFFSET) - (buf.getInt(Constants.TUPLE_COUNT_OFFSET) * slotManager.getSlotSize())) { return FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE; } else if (bytesRequired + slotManager.getSlotSize() <= buf.getInt(TOTAL_FREE_SPACE_OFFSET)) { return FrameOpSpaceStatus.SUFFICIENT_SPACE; } else { return FrameOpSpaceStatus.INSUFFICIENT_SPACE; } }