http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java index 9505f8a..e59523c 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java @@ -45,8 +45,8 @@ import org.apache.hyracks.storage.common.buffercache.IExtraPageBlockHelper; public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeInteriorFrame { - private static final int rightLeafOff = flagOff + 1; // 22 - private static final int childPtrSize = 4; + private static final int RIGHT_LEAF_OFFSET = TreeIndexNSMFrame.RESERVED_HEADER_SIZE; + private static final int CHILD_PTR_SIZE = 4; private final ITreeIndexTupleReference cmpFrameTuple; private final ITreeIndexTupleReference previousFt; @@ -61,13 +61,13 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn @Override public int getBytesRequiredToWriteTuple(ITupleReference tuple) { - return tupleWriter.bytesRequired(tuple) + childPtrSize + slotManager.getSlotSize(); + return tupleWriter.bytesRequired(tuple) + CHILD_PTR_SIZE + slotManager.getSlotSize(); } @Override public void initBuffer(byte level) { super.initBuffer(level); - buf.putInt(rightLeafOff, -1); + buf.putInt(RIGHT_LEAF_OFFSET, -1); } @Override @@ -82,7 +82,7 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn @Override public FrameOpSpaceStatus hasSpaceInsert(ITupleReference tuple) throws HyracksDataException { - int tupleSize = tupleWriter.bytesRequired(tuple) + childPtrSize; + int tupleSize = tupleWriter.bytesRequired(tuple) + CHILD_PTR_SIZE; if (tupleSize > getMaxTupleSize(buf.capacity())) { return FrameOpSpaceStatus.TOO_LARGE; } @@ -99,28 +99,29 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn @Override public void insert(ITupleReference tuple, int tupleIndex) { - int slotOff = slotManager.insertSlot(tupleIndex, buf.getInt(freeSpaceOff)); - int freeSpace = buf.getInt(freeSpaceOff); + 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, childPtrSize); - int tupleSize = bytesWritten + childPtrSize; - buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1); - buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + tupleSize); - buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - tupleSize - slotManager.getSlotSize()); + 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) + childPtrSize, - buf.array(), rightLeafOff, childPtrSize); + 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(tupleCountOff) > 1) { + if (buf.getInt(Constants.TUPLE_COUNT_OFFSET) > 1) { int rightNeighborOff = slotOff - slotManager.getSlotSize(); - frameTuple.resetByTupleOffset(buf, slotManager.getTupleOff(rightNeighborOff)); - System.arraycopy(tuple.getFieldData(0), getLeftChildPageOff(tuple) + childPtrSize, buf.array(), - getLeftChildPageOff(frameTuple), childPtrSize); + frameTuple.resetByTupleOffset(buf.array(), slotManager.getTupleOff(rightNeighborOff)); + System.arraycopy(tuple.getFieldData(0), getLeftChildPageOff(tuple) + CHILD_PTR_SIZE, buf.array(), + getLeftChildPageOff(frameTuple), CHILD_PTR_SIZE); } } } @@ -142,13 +143,13 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn int keySize; if (tupleIndex == slotManager.getGreatestKeyIndicator()) { tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff()); - frameTuple.resetByTupleOffset(buf, tupleOff); + frameTuple.resetByTupleOffset(buf.array(), tupleOff); keySize = frameTuple.getTupleSize(); // Copy new rightmost pointer. - System.arraycopy(buf.array(), tupleOff + keySize, buf.array(), rightLeafOff, childPtrSize); + System.arraycopy(buf.array(), tupleOff + keySize, buf.array(), RIGHT_LEAF_OFFSET, CHILD_PTR_SIZE); } else { tupleOff = slotManager.getTupleOff(slotOff); - frameTuple.resetByTupleOffset(buf, tupleOff); + frameTuple.resetByTupleOffset(buf.array(), tupleOff); keySize = frameTuple.getTupleSize(); // Perform deletion (we just do a memcpy to overwrite the slot). int slotStartOff = slotManager.getSlotEndOff(); @@ -156,25 +157,25 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn System.arraycopy(buf.array(), slotStartOff, buf.array(), slotStartOff + slotManager.getSlotSize(), length); } // Maintain space information. - buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1); - buf.putInt(totalFreeSpaceOff, - buf.getInt(totalFreeSpaceOff) + keySize + childPtrSize + slotManager.getSlotSize()); + 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()); } @Override public void deleteGreatest() { int slotOff = slotManager.getSlotEndOff(); int tupleOff = slotManager.getTupleOff(slotOff); - frameTuple.resetByTupleOffset(buf, tupleOff); + frameTuple.resetByTupleOffset(buf.array(), tupleOff); int keySize = tupleWriter.bytesRequired(frameTuple); - System.arraycopy(buf.array(), tupleOff + keySize, buf.array(), rightLeafOff, childPtrSize); + System.arraycopy(buf.array(), tupleOff + keySize, buf.array(), RIGHT_LEAF_OFFSET, CHILD_PTR_SIZE); // Maintain space information. - buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1); - buf.putInt(totalFreeSpaceOff, - buf.getInt(totalFreeSpaceOff) + keySize + childPtrSize + slotManager.getSlotSize()); - int freeSpace = buf.getInt(freeSpaceOff); - if (freeSpace == tupleOff + keySize + childPtrSize) { - buf.putInt(freeSpace, freeSpace - (keySize + childPtrSize)); + 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)); } } @@ -185,17 +186,19 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn @Override public void insertSorted(ITupleReference tuple) { - int freeSpace = buf.getInt(freeSpaceOff); + 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, childPtrSize); - int tupleSize = bytesWritten + childPtrSize; - buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1); - buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + tupleSize); - buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - tupleSize - slotManager.getSlotSize()); - System.arraycopy(tuple.getFieldData(0), getLeftChildPageOff(tuple) + childPtrSize, buf.array(), rightLeafOff, - childPtrSize); + 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); } @Override @@ -219,7 +222,7 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn int i; for (i = 0; i < tupleCount; ++i) { frameTuple.resetByTupleIndex(this, i); - totalSize += tupleWriter.bytesRequired(frameTuple) + childPtrSize + slotManager.getSlotSize(); + totalSize += tupleWriter.bytesRequired(frameTuple) + CHILD_PTR_SIZE + slotManager.getSlotSize(); if (totalSize >= halfPageSize) { break; } @@ -243,11 +246,11 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn + tuplesToLeft * rightFrame.getSlotManager().getSlotSize(); int length = rightFrame.getSlotManager().getSlotSize() * tuplesToRight; System.arraycopy(right.array(), src, right.array(), dest, length); - right.putInt(tupleCountOff, tuplesToRight); + 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(tupleCountOff, tuplesToLeft); + 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 @@ -256,16 +259,16 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn // Set split key to be highest value in left page. int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff()); - frameTuple.resetByTupleOffset(buf, tupleOff); + 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(), 0); + splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer().array(), 0); int deleteTupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff()); - frameTuple.resetByTupleOffset(buf, deleteTupleOff); - buf.putInt(rightLeafOff, buf.getInt(getLeftChildPageOff(frameTuple))); - buf.putInt(tupleCountOff, tuplesToLeft - 1); + 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(); @@ -284,10 +287,10 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn @Override public boolean compact() { resetSpaceParams(); - int tupleCount = buf.getInt(tupleCountOff); - int freeSpace = buf.getInt(freeSpaceOff); + int tupleCount = buf.getInt(Constants.TUPLE_COUNT_OFFSET); + int freeSpace = buf.getInt(Constants.FREE_SPACE_OFFSET); // Sort the slots by the tuple offset they point to. - ArrayList<SlotOffTupleOff> sortedTupleOffs = new ArrayList<SlotOffTupleOff>(); + ArrayList<SlotOffTupleOff> sortedTupleOffs = new ArrayList<>(); sortedTupleOffs.ensureCapacity(tupleCount); for (int i = 0; i < tupleCount; i++) { int slotOff = slotManager.getSlotOff(i); @@ -299,25 +302,25 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn // the left, reclaiming free space. for (int i = 0; i < sortedTupleOffs.size(); i++) { int tupleOff = sortedTupleOffs.get(i).tupleOff; - frameTuple.resetByTupleOffset(buf, tupleOff); + frameTuple.resetByTupleOffset(buf.array(), tupleOff); int tupleEndOff = frameTuple.getFieldStart(frameTuple.getFieldCount() - 1) + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1); - int tupleLength = tupleEndOff - tupleOff + childPtrSize; + 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; } // Update contiguous free space pointer and total free space indicator. - buf.putInt(freeSpaceOff, freeSpace); - buf.putInt(totalFreeSpaceOff, buf.capacity() - freeSpace - tupleCount * slotManager.getSlotSize()); + buf.putInt(Constants.FREE_SPACE_OFFSET, freeSpace); + buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.capacity() - freeSpace - tupleCount * slotManager.getSlotSize()); return false; } @Override public int getChildPageId(RangePredicate pred) throws HyracksDataException { // Trivial case where there is only a child pointer (and no key). - if (buf.getInt(tupleCountOff) == 0) { - return buf.getInt(rightLeafOff); + if (buf.getInt(Constants.TUPLE_COUNT_OFFSET) == 0) { + return buf.getInt(RIGHT_LEAF_OFFSET); } // Trivial cases where no low key or high key was given (e.g. during an // index scan). @@ -340,7 +343,7 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn int slotOff = slotManager.getSlotOff(tupleIndex); // Follow the rightmost (greatest) child pointer. if (tupleIndex == slotManager.getGreatestKeyIndicator()) { - return buf.getInt(rightLeafOff); + return buf.getInt(RIGHT_LEAF_OFFSET); } // Deal with prefix searches. // slotManager.findTupleIndex() will return an arbitrary tuple matching @@ -348,7 +351,7 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn // To make sure we traverse the right path, we must find the // leftmost or rightmost tuple that matches the prefix. int origTupleOff = slotManager.getTupleOff(slotOff); - cmpFrameTuple.resetByTupleOffset(buf, origTupleOff); + cmpFrameTuple.resetByTupleOffset(buf.array(), origTupleOff); int cmpTupleOff = origTupleOff; // The answer set begins with the lowest key matching the prefix. // We must follow the child pointer of the lowest (leftmost) key @@ -357,14 +360,14 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn slotOff += slotManager.getSlotSize(); while (slotOff < maxSlotOff) { cmpTupleOff = slotManager.getTupleOff(slotOff); - frameTuple.resetByTupleOffset(buf, cmpTupleOff); + frameTuple.resetByTupleOffset(buf.array(), cmpTupleOff); if (targetCmp.compare(cmpFrameTuple, frameTuple) != 0) { break; } slotOff += slotManager.getSlotSize(); } slotOff -= slotManager.getSlotSize(); - frameTuple.resetByTupleOffset(buf, slotManager.getTupleOff(slotOff)); + frameTuple.resetByTupleOffset(buf.array(), slotManager.getTupleOff(slotOff)); int childPageOff = getLeftChildPageOff(frameTuple); return buf.getInt(childPageOff); @@ -373,24 +376,24 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn @Override public int getLeftmostChildPageId() { int tupleOff = slotManager.getTupleOff(slotManager.getSlotStartOff()); - frameTuple.resetByTupleOffset(buf, tupleOff); + frameTuple.resetByTupleOffset(buf.array(), tupleOff); int childPageOff = getLeftChildPageOff(frameTuple); return buf.getInt(childPageOff); } @Override public int getRightmostChildPageId() { - return buf.getInt(rightLeafOff); + return buf.getInt(RIGHT_LEAF_OFFSET); } @Override public void setRightmostChildPageId(int pageId) { - buf.putInt(rightLeafOff, pageId); + buf.putInt(RIGHT_LEAF_OFFSET, pageId); } @Override public int getPageHeaderSize() { - return rightLeafOff + 4; + return RIGHT_LEAF_OFFSET + 4; } private int getLeftChildPageOff(ITupleReference tuple) { @@ -414,25 +417,27 @@ public class BTreeNSMInteriorFrame extends TreeIndexNSMFrame implements IBTreeIn // For debugging. public ArrayList<Integer> getChildren(MultiComparator cmp) { - ArrayList<Integer> ret = new ArrayList<Integer>(); + ArrayList<Integer> ret = new ArrayList<>(); frameTuple.setFieldCount(cmp.getKeyFieldCount()); - int tupleCount = buf.getInt(tupleCountOff); + 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, tupleOff); + frameTuple.resetByTupleOffset(buf.array(), tupleOff); int intVal = IntegerPointable.getInteger(buf.array(), frameTuple.getFieldStart(frameTuple.getFieldCount() - 1) + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1)); ret.add(intVal); } if (!isLeaf()) { - int rightLeaf = buf.getInt(rightLeafOff); - if (rightLeaf > 0) - ret.add(buf.getInt(rightLeafOff)); + int rightLeaf = buf.getInt(RIGHT_LEAF_OFFSET); + if (rightLeaf > 0) { + ret.add(buf.getInt(RIGHT_LEAF_OFFSET)); + } } return ret; } + @Override public void validate(PageValidationInfo pvi) throws HyracksDataException { int tupleCount = getTupleCount(); for (int i = 0; i < tupleCount; i++) {
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java index f7af7ad..6a957b5 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java @@ -41,7 +41,7 @@ import org.apache.hyracks.storage.common.buffercache.IBufferCache; import org.apache.hyracks.storage.common.buffercache.IExtraPageBlockHelper; public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFrame { - protected static final int nextLeafOff = flagOff + 1; // 22 + protected static final int NEXT_LEAF_OFFSET = TreeIndexNSMFrame.RESERVED_HEADER_SIZE; private MultiComparator cmp; @@ -54,7 +54,7 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr @Override public int getPageHeaderSize() { - return nextLeafOff + 4; + return NEXT_LEAF_OFFSET + 4; } @Override @@ -65,17 +65,17 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr @Override public void initBuffer(byte level) { super.initBuffer(level); - buf.putInt(nextLeafOff, -1); + buf.putInt(NEXT_LEAF_OFFSET, -1); } @Override public void setNextLeaf(int page) { - buf.putInt(nextLeafOff, page); + buf.putInt(NEXT_LEAF_OFFSET, page); } @Override public int getNextLeaf() { - return buf.getInt(nextLeafOff); + return buf.getInt(NEXT_LEAF_OFFSET); } @Override @@ -161,12 +161,13 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr @Override public void insert(ITupleReference tuple, int tupleIndex) { - int freeSpace = buf.getInt(freeSpaceOff); + int freeSpace = buf.getInt(Constants.FREE_SPACE_OFFSET); slotManager.insertSlot(tupleIndex, freeSpace); int bytesWritten = tupleWriter.writeTuple(tuple, buf.array(), freeSpace); - buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1); - buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + bytesWritten); - buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - bytesWritten - slotManager.getSlotSize()); + 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 @@ -261,10 +262,10 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr + tuplesToLeft * rightFrame.getSlotManager().getSlotSize(); int length = rightFrame.getSlotManager().getSlotSize() * tuplesToRight; System.arraycopy(right.array(), src, right.array(), dest, length); - right.putInt(tupleCountOff, tuplesToRight); + right.putInt(Constants.TUPLE_COUNT_OFFSET, tuplesToRight); // On left page only change the tupleCount indicator. - buf.putInt(tupleCountOff, tuplesToLeft); + buf.putInt(Constants.TUPLE_COUNT_OFFSET, tuplesToLeft); // Compact both pages. rightFrame.compact(); @@ -288,13 +289,14 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr // Set the split key to be highest key in the left page. int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff()); - frameTuple.resetByTupleOffset(buf, tupleOff); + frameTuple.resetByTupleOffset(buf.array(), tupleOff); 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(), 0); + splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer().array(), 0); } + @Override public void ensureCapacity(IBufferCache bufferCache, ITupleReference tuple, IExtraPageBlockHelper extraPageBlockHelper) throws HyracksDataException { // we call ensureCapacity() for large tuples- ensure large flag is set @@ -323,7 +325,8 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr System.arraycopy(buf.array(), oldSlotEnd, buf.array(), slotManager.getSlotEndOff(), oldSlotStart - oldSlotEnd); // fixup total free space counter - buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + (bufferCache.getPageSize() * deltaPages)); + buf.putInt(TOTAL_FREE_SPACE_OFFSET, buf.getInt(TOTAL_FREE_SPACE_OFFSET) + (bufferCache.getPageSize() + * deltaPages)); } @Override @@ -342,6 +345,7 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr this.cmp = cmp; } + @Override public void validate(PageValidationInfo pvi) throws HyracksDataException { int tupleCount = getTupleCount(); for (int i = 0; i < tupleCount; i++) { @@ -364,7 +368,7 @@ public class BTreeNSMLeafFrame extends TreeIndexNSMFrame implements IBTreeLeafFr @Override public String printHeader() { StringBuilder strBuilder = new StringBuilder(super.printHeader()); - strBuilder.append("nextLeafOff: " + nextLeafOff + "\n"); + strBuilder.append("nextLeafOff: " + NEXT_LEAF_OFFSET + "\n"); return strBuilder.toString(); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java index b6a64fa..5fdd943 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java @@ -1041,7 +1041,7 @@ public class BTree extends AbstractTreeIndex { splitKey.initData(splitKeySize); tupleWriter.writeTupleFields(leafFrontier.lastTuple, 0, cmp.getKeyFieldCount(), splitKey.getBuffer().array(), 0); - splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer(), 0); + splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer().array(), 0); splitKey.setLeftPage(leafFrontier.pageId); propagateBulk(1, pagesToWrite); @@ -1137,7 +1137,7 @@ public class BTree extends AbstractTreeIndex { splitKey.initData(splitKeySize); tupleWriter.writeTupleFields(frontier.lastTuple, 0, cmp.getKeyFieldCount(), splitKey.getBuffer().array(), 0); - splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer(), 0); + splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer().array(), 0); ((IBTreeInteriorFrame) interiorFrame).deleteGreatest(); int finalPageId = freePageManager.takePage(metaFrame); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java index 3de9a0c..3c5d0e5 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java @@ -38,7 +38,7 @@ import org.apache.hyracks.storage.am.common.api.IModificationOperationCallback; import org.apache.hyracks.storage.am.common.api.ISearchOperationCallback; import org.apache.hyracks.storage.am.common.api.ITreeIndexCursor; import org.apache.hyracks.storage.am.common.api.ITreeIndexFrameFactory; -import org.apache.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame; +import org.apache.hyracks.storage.am.common.api.ITreeIndexMetadataFrame; import org.apache.hyracks.storage.am.common.api.ITreeIndexTupleReference; import org.apache.hyracks.storage.am.common.ophelpers.IndexOperation; import org.apache.hyracks.storage.am.common.ophelpers.MultiComparator; @@ -56,7 +56,7 @@ public class BTreeOpContext implements IIndexOperationContext, IExtraPageBlockHe public IBTreeLeafFrame leafFrame; public IBTreeInteriorFrame interiorFrame; public final IPageManager freePageManager; - public final ITreeIndexMetaDataFrame metaFrame; + public final ITreeIndexMetadataFrame metaFrame; public IndexOperation op; public ITreeIndexCursor cursor; public BTreeCursorInitialState cursorInitialState; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeSplitKey.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeSplitKey.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeSplitKey.java index f500a1a..4700ea3 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeSplitKey.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeSplitKey.java @@ -35,6 +35,7 @@ public class BTreeSplitKey implements ISplitKey { this.tuple = tuple; } + @Override public void initData(int keySize) { // try to reuse existing memory from a lower-level split if possible this.keySize = keySize; @@ -48,49 +49,58 @@ public class BTreeSplitKey implements ISplitKey { buf = ByteBuffer.wrap(data); } - tuple.resetByTupleOffset(buf, 0); + tuple.resetByTupleOffset(buf.array(), 0); } + @Override public void reset() { data = null; buf = null; } + @Override public ByteBuffer getBuffer() { return buf; } + @Override public ITreeIndexTupleReference getTuple() { return tuple; } + @Override public int getLeftPage() { return buf.getInt(keySize); } + @Override public int getRightPage() { return buf.getInt(keySize + 4); } + @Override public void setLeftPage(int leftPage) { buf.putInt(keySize, leftPage); } + @Override public void setRightPage(int rightPage) { buf.putInt(keySize + 4, rightPage); } + @Override public void setPages(int leftPage, int rightPage) { buf.putInt(keySize, leftPage); buf.putInt(keySize + 4, rightPage); } + @Override public BTreeSplitKey duplicate(ITreeIndexTupleReference copyTuple) { BTreeSplitKey copy = new BTreeSplitKey(copyTuple); copy.data = data.clone(); copy.buf = ByteBuffer.wrap(copy.data); copy.tuple.setFieldCount(tuple.getFieldCount()); - copy.tuple.resetByTupleOffset(copy.buf, 0); + copy.tuple.resetByTupleOffset(copy.buf.array(), 0); return copy; } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixPrefixTupleReference.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixPrefixTupleReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixPrefixTupleReference.java index e110370..b767537 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixPrefixTupleReference.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixPrefixTupleReference.java @@ -40,7 +40,7 @@ public class FieldPrefixPrefixTupleReference extends TypeAwareTupleReference { int prefixSlot = concreteFrame.getBuffer().getInt(prefixSlotOff); setFieldCount(slotManager.decodeFirstSlotField(prefixSlot)); tupleStartOff = slotManager.decodeSecondSlotField(prefixSlot); - buf = concreteFrame.getBuffer(); + buf = concreteFrame.getBuffer().array(); resetByTupleOffset(buf, tupleStartOff); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixTupleReference.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixTupleReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixTupleReference.java index a249fbb..566947d 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixTupleReference.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/FieldPrefixTupleReference.java @@ -18,8 +18,6 @@ */ package org.apache.hyracks.storage.am.btree.impls; -import java.nio.ByteBuffer; - import org.apache.hyracks.storage.am.btree.api.IPrefixSlotManager; import org.apache.hyracks.storage.am.btree.frames.BTreeFieldPrefixNSMLeafFrame; import org.apache.hyracks.storage.am.common.api.ITreeIndexFrame; @@ -84,11 +82,11 @@ public class FieldPrefixTupleReference implements ITreeIndexTupleReference { public int getFieldLength(int fIdx) { if (fIdx < numPrefixFields) { helperTuple.setFieldCount(numPrefixFields); - helperTuple.resetByTupleOffset(frame.getBuffer(), prefixTupleStartOff); + helperTuple.resetByTupleOffset(frame.getBuffer().array(), prefixTupleStartOff); return helperTuple.getFieldLength(fIdx); } else { helperTuple.setFieldCount(numPrefixFields, fieldCount - numPrefixFields); - helperTuple.resetByTupleOffset(frame.getBuffer(), suffixTupleStartOff); + helperTuple.resetByTupleOffset(frame.getBuffer().array(), suffixTupleStartOff); return helperTuple.getFieldLength(fIdx - numPrefixFields); } } @@ -97,18 +95,18 @@ public class FieldPrefixTupleReference implements ITreeIndexTupleReference { public int getFieldStart(int fIdx) { if (fIdx < numPrefixFields) { helperTuple.setFieldCount(numPrefixFields); - helperTuple.resetByTupleOffset(frame.getBuffer(), prefixTupleStartOff); + helperTuple.resetByTupleOffset(frame.getBuffer().array(), prefixTupleStartOff); return helperTuple.getFieldStart(fIdx); } else { helperTuple.setFieldCount(numPrefixFields, fieldCount - numPrefixFields); - helperTuple.resetByTupleOffset(frame.getBuffer(), suffixTupleStartOff); + helperTuple.resetByTupleOffset(frame.getBuffer().array(), suffixTupleStartOff); return helperTuple.getFieldStart(fIdx - numPrefixFields); } } // unsupported operation @Override - public void resetByTupleOffset(ByteBuffer buf, int tupleStartOffset) { + public void resetByTupleOffset(byte[] buf, int tupleStartOffset) { throw new UnsupportedOperationException("Resetting this type of frame by offset is not supported."); } @@ -119,15 +117,16 @@ public class FieldPrefixTupleReference implements ITreeIndexTupleReference { public int getSuffixTupleSize() { helperTuple.setFieldCount(numPrefixFields, fieldCount - numPrefixFields); - helperTuple.resetByTupleOffset(frame.getBuffer(), suffixTupleStartOff); + helperTuple.resetByTupleOffset(frame.getBuffer().array(), suffixTupleStartOff); return helperTuple.getTupleSize(); } public int getPrefixTupleSize() { - if (numPrefixFields == 0) + if (numPrefixFields == 0) { return 0; + } helperTuple.setFieldCount(numPrefixFields); - helperTuple.resetByTupleOffset(frame.getBuffer(), prefixTupleStartOff); + helperTuple.resetByTupleOffset(frame.getBuffer().array(), prefixTupleStartOff); return helperTuple.getTupleSize(); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/pom.xml ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/pom.xml b/hyracks-fullstack/hyracks/hyracks-storage-am-common/pom.xml index 7ebd27f..1d69439 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/pom.xml +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/pom.xml @@ -80,5 +80,10 @@ <artifactId>hyracks-data-std</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project> http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IMetadataPageManager.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IMetadataPageManager.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IMetadataPageManager.java index 02390c8..58c837b 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IMetadataPageManager.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IMetadataPageManager.java @@ -19,55 +19,38 @@ package org.apache.hyracks.storage.am.common.api; import org.apache.hyracks.api.exceptions.HyracksDataException; -import org.apache.hyracks.storage.common.buffercache.ICachedPage; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.api.IValueReference; /** * Used to read from and write to index metadata. - * The index metadata contains information such as: - * --The LSN of the index. - * --Free page information {Set of free pages} - * --Filter information. - * TODO: This interface needs to change to have calls to request memory space and write to those bytes + * The index metadata contains key-value pairs */ public interface IMetadataPageManager extends IPageManager { - public static class Constants { - public static final long INVALID_LSN_OFFSET = -1; - private Constants() { - } - } - - /** - * Locate the filter page in an index file - * - * @return The offset of the filter page if it exists, or less than zero if no filter page exists yet - * @throws HyracksDataException - */ - int getFilterPageId() throws HyracksDataException; - void setFilterPageId(int filterPageId) throws HyracksDataException; - long getLSN() throws HyracksDataException; - void setLSN(long lsn) throws HyracksDataException; - /** - * Set the cached page to manage for filter data - * - * @param page - * The page to manage + * put the key value pair in the metadata page using the passed frame + * @param frame + * @param key + * @param value * @throws HyracksDataException */ - void setFilterPage(ICachedPage page) throws HyracksDataException; + void put(ITreeIndexMetadataFrame frame, IValueReference key, IValueReference value) throws HyracksDataException; /** - * Get filter page if exists, create and return a new one if it doesn't - * @return + * get the value of the key from the metadata page using the passed frame + * @param frame + * @param key + * @param value * @throws HyracksDataException */ - ICachedPage getFilterPage() throws HyracksDataException; + void get(ITreeIndexMetadataFrame frame, IValueReference key, IPointable value) throws HyracksDataException; /** - * @return The LSN byte offset in the LSM disk component if the index is valid, - * otherwise {@link #INVALID_LSN_OFFSET}. + * @param frame + * @param key + * @return The byte offset in the index file for the entry with the passed key if the index is valid and the key + * exists, returns -1 otherwise. use the passed frame to read the metadata page * @throws HyracksDataException */ - long getLSNOffset() throws HyracksDataException; - long getLastMarkerLSN() throws HyracksDataException; + long getFileOffset(ITreeIndexMetadataFrame frame, IValueReference key) throws HyracksDataException; } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IPageManager.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IPageManager.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IPageManager.java index 2aee403..b7987f8 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IPageManager.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IPageManager.java @@ -50,7 +50,7 @@ public interface IPageManager { * Create a metadata frame to be used for reading and writing to metadata pages * @return a new metadata frame */ - ITreeIndexMetaDataFrame createMetadataFrame(); + ITreeIndexMetadataFrame createMetadataFrame(); /** * Determines where the main metadata page is located in an index file @@ -82,7 +82,7 @@ public interface IPageManager { * @return A page location, or -1 if no free page could be found or allocated * @throws HyracksDataException */ - int takePage(ITreeIndexMetaDataFrame frame) throws HyracksDataException; + int takePage(ITreeIndexMetadataFrame frame) throws HyracksDataException; /** * Get the location of a block of free pages to use for index operations @@ -92,7 +92,7 @@ public interface IPageManager { * @return The starting page location, or -1 if a block of free pages could be found or allocated * @throws HyracksDataException */ - int takeBlock(ITreeIndexMetaDataFrame frame, int count) throws HyracksDataException; + int takeBlock(ITreeIndexMetadataFrame frame, int count) throws HyracksDataException; /** * Add a page back to the pool of free pages within an index file @@ -103,7 +103,7 @@ public interface IPageManager { * The page to be returned to the set of free pages * @throws HyracksDataException */ - void releasePage(ITreeIndexMetaDataFrame frame, int page) throws HyracksDataException; + void releasePage(ITreeIndexMetadataFrame frame, int page) throws HyracksDataException; /** * Add a page back to the pool of free pages within an index file @@ -115,7 +115,7 @@ public interface IPageManager { * the number of regular sized pages in the free pages block * @throws HyracksDataException */ - void releaseBlock(ITreeIndexMetaDataFrame frame, int page, int count) throws HyracksDataException; + void releaseBlock(ITreeIndexMetadataFrame frame, int page, int count) throws HyracksDataException; /** * Gets the highest page offset according to the metadata @@ -125,7 +125,7 @@ public interface IPageManager { * @return The locaiton of the highest offset page * @throws HyracksDataException */ - int getMaxPageId(ITreeIndexMetaDataFrame frame) throws HyracksDataException; + int getMaxPageId(ITreeIndexMetadataFrame frame) throws HyracksDataException; /** * Check whether the index is empty or not. http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexFrame.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexFrame.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexFrame.java index 037c183..8e7834f 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexFrame.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexFrame.java @@ -31,6 +31,21 @@ import org.apache.hyracks.storage.common.buffercache.IExtraPageBlockHelper; public interface ITreeIndexFrame { + public static class Constants { + /* + * Storage version #. Change this if you alter any tree frame formats to stop + * possible corruption from old versions reading new formats. + */ + public static final int VERSION = 5; + public static final int TUPLE_COUNT_OFFSET = 0; + public static final int FREE_SPACE_OFFSET = TUPLE_COUNT_OFFSET + 4; + public static final int LEVEL_OFFSET = FREE_SPACE_OFFSET + 4; + public static final int RESERVED_HEADER_SIZE = LEVEL_OFFSET + 1; + + private Constants() { + } + } + public void initBuffer(byte level); public FrameOpSpaceStatus hasSpaceInsert(ITupleReference tuple) throws HyracksDataException; @@ -73,7 +88,7 @@ public interface ITreeIndexFrame { public String printHeader(); public void split(ITreeIndexFrame rightFrame, ITupleReference tuple, ISplitKey splitKey, - IExtraPageBlockHelper extraPageBlockHelper, IBufferCache bufferCache) + IExtraPageBlockHelper extraPageBlockHelper, IBufferCache bufferCache) throws HyracksDataException, TreeIndexException; public ISlotManager getSlotManager(); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrame.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrame.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrame.java deleted file mode 100644 index f49972c..0000000 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrame.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hyracks.storage.am.common.api; - -import org.apache.hyracks.storage.common.buffercache.ICachedPage; - -public interface ITreeIndexMetaDataFrame { - - // Storage version #. Change this if you alter any tree frame formats to stop - // possible corruption from old versions reading new formats. - int VERSION = 4; - - public void initBuffer(); - - public void setPage(ICachedPage page); - - public ICachedPage getPage(); - - public byte getLevel(); - - public void setLevel(byte level); - - public int getNextMetadataPage(); - - public void setNextPage(int nextPage); - - public int getMaxPage(); - - public void setMaxPage(int maxPage); - - public int getFreePage(); - - public boolean hasSpace(); - - public void addFreePage(int freePage); - - // Special flag for LSM-Components to mark whether they are valid or not. - public boolean isValid(); - - // Set special validity flag. - public void setValid(boolean isValid); - - // Return the lsm component filter page id. - public int getLSMComponentFilterPageId(); - - // Set the lsm component filter page id. - public void setLSMComponentFilterPageId(int filterPage); - - // Special placeholder for LSN information. Used for transactional LSM indexes. - public long getLSN(); - - public void setLSN(long lsn); - - public int getVersion(); - - // Special placeholder for LSN information of a marker log. used for rollback information - public long getLastMarkerLSN(); - - public void setLastMarkerLSN(long lsn); - - void setRootPageNumber(int rootPage); - - int getRootPageNumber(); - - boolean isMetadataPage(); - - boolean isFreePage(); -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrameFactory.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrameFactory.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrameFactory.java deleted file mode 100644 index ff7deaf..0000000 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetaDataFrameFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hyracks.storage.am.common.api; - -public interface ITreeIndexMetaDataFrameFactory { - public ITreeIndexMetaDataFrame createFrame(); -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrame.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrame.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrame.java new file mode 100644 index 0000000..7efc469 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrame.java @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.hyracks.storage.am.common.api; + +import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.api.IValueReference; +import org.apache.hyracks.storage.common.buffercache.ICachedPage; + +/** + * A frame for reading and writing metadata pages of an index + * It can also be used to read metadata of non metadata pages + */ +public interface ITreeIndexMetadataFrame { + /** + * initialize the metadata page + */ + void init(); + + /** + * Set the page in the frame + * @param page + */ + void setPage(ICachedPage page); + + /** + * @return the page set in this frame + */ + ICachedPage getPage(); + + /** + * The page level. + * This method can be run on any type of page + */ + byte getLevel(); + + /** + * Set the page level + * @param level + */ + void setLevel(byte level); + + /** + * Get the next metadata page if this page is linked to other metadata pages + * Return a negative value otherwise + * @return + */ + int getNextMetadataPage(); + + /** + * Link this metadata page to another one + * @param nextPage + */ + void setNextMetadataPage(int nextPage); + + /** + * @return the max index file page as indicated by the current metadata page + */ + int getMaxPage(); + + /** + * Set the max page of the file + * @param maxPage + */ + void setMaxPage(int maxPage); + + /** + * Get a free page from the page + * @return + */ + int getFreePage(); + + /** + * Get the remaining space in the metadata page + * @return + */ + int getSpace(); + + /** + * add a new free page to the metadata page + * @param freePage + */ + void addFreePage(int freePage); + + /** + * get the value with the key = key + * @param key + * @param value + */ + void get(IValueReference key, IPointable value); + + /** + * set the value with the key = key + * @param key + * @param value + * @throws HyracksDataException + */ + void put(IValueReference key, IValueReference value) throws HyracksDataException; + + /** + * @return true if the index is valid according to the metadata page, false otherwise + */ + boolean isValid(); + + /** + * Sets the index to be valid in the metadata page + * @param valid + */ + void setValid(boolean valid); + + /** + * Get the storage version associated with this index + * @return + */ + int getVersion(); + + /** + * Set the index root page id + * @param rootPage + */ + void setRootPageId(int rootPage); + + /** + * @return the index root page id + */ + int getRootPageId(); + + /** + * @return the number of key value pairs + */ + int getTupleCount(); + + /** + * return the offset to the entry of the passed key, -1, otherwise + * @param key + */ + int getOffset(IValueReference key); + + /** + * @return true if the inspected page is a metadata page, false otherwise + */ + boolean isMetadataPage(); + + /** + * @return true if the inspected page is a free page, false otherwise + */ + boolean isFreePage(); +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrameFactory.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrameFactory.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrameFactory.java new file mode 100644 index 0000000..7018743 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexMetadataFrameFactory.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.hyracks.storage.am.common.api; + +@FunctionalInterface +public interface ITreeIndexMetadataFrameFactory { + ITreeIndexMetadataFrame createFrame(); +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexTupleReference.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexTupleReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexTupleReference.java index 6b041eb..42f0ed5 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexTupleReference.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexTupleReference.java @@ -19,8 +19,6 @@ package org.apache.hyracks.storage.am.common.api; -import java.nio.ByteBuffer; - import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference; public interface ITreeIndexTupleReference extends ITupleReference { @@ -28,7 +26,7 @@ public interface ITreeIndexTupleReference extends ITupleReference { public void setFieldCount(int fieldStartIndex, int fieldCount); - public void resetByTupleOffset(ByteBuffer buf, int tupleStartOffset); + public void resetByTupleOffset(byte[] buf, int tupleStartOffset); public void resetByTupleIndex(ITreeIndexFrame frame, int tupleIndex); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java index 5099df1..c6d4e35 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java @@ -30,7 +30,7 @@ import org.apache.hyracks.storage.am.common.api.IIndex; import org.apache.hyracks.storage.am.common.api.IIndexDataflowHelper; import org.apache.hyracks.storage.am.common.api.IPageManagerFactory; import org.apache.hyracks.storage.am.common.api.IResourceLifecycleManager; -import org.apache.hyracks.storage.am.common.frames.LIFOMetaDataFrame; +import org.apache.hyracks.storage.am.common.api.ITreeIndexFrame; import org.apache.hyracks.storage.common.file.ILocalResourceFactory; import org.apache.hyracks.storage.common.file.ILocalResourceRepository; import org.apache.hyracks.storage.common.file.IResourceIdFactory; @@ -99,7 +99,7 @@ public abstract class IndexDataflowHelper implements IIndexDataflowHelper { .getLocalResourceFactory(); localResourceRepository.insert(localResourceFactory.createLocalResource(resourceID, resourceRef .getRelativePath(), - LIFOMetaDataFrame.VERSION, partition)); + ITreeIndexFrame.Constants.VERSION, partition)); } catch (IOException e) { throw new HyracksDataException(e); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrame.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrame.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrame.java index 7d33519..de890c4 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrame.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrame.java @@ -16,44 +16,40 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.hyracks.storage.am.common.frames; import java.nio.ByteBuffer; -import org.apache.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame; +import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.api.IValueReference; +import org.apache.hyracks.storage.am.common.api.ITreeIndexFrame; +import org.apache.hyracks.storage.am.common.api.ITreeIndexFrame.Constants; +import org.apache.hyracks.storage.am.common.api.ITreeIndexMetadataFrame; import org.apache.hyracks.storage.common.buffercache.ICachedPage; -// all meta pages of this kind have a negative level -// the first meta page has level -1, all other meta pages have level -2 -// the first meta page is special because it guarantees to have a correct max page -// other meta pages (i.e., with level -2) have junk in the max page field - -public class LIFOMetaDataFrame implements ITreeIndexMetaDataFrame { +/** + * Frame content + * [ Headers defined in {@link ITreeIndexFrame}][max page][next page][valid] + * [storage version][root page][free page count][k1 length][k1][v1 length][v1] + * [k2 length][k2][v2 length][v2]....... + * .... + * .... + * [free page 5][free page 4][free page 3][free page 2][free page 1] + * + */ +public class LIFOMetaDataFrame implements ITreeIndexMetadataFrame { private static final byte META_PAGE_LEVEL_INDICATOR = -1; private static final byte FREE_PAGE_LEVEL_INDICATOR = -2; - - // Arbitrarily chosen magic integer. - protected static final int OBSOLETE_MAGIC_VALID_INT = 0x5bd1e995; protected static final int MAGIC_VALID_INT = 0x1B16DA7A; - - protected static final int TUPLE_COUNT_OFFSET = 0; //0 - protected static final int FREE_SPACE_OFFSET = TUPLE_COUNT_OFFSET + 4; //4 - protected static final int MAX_PAGE_OFFSET = FREE_SPACE_OFFSET + 4; //8 - protected static final int LEVEL_OFFSET = MAX_PAGE_OFFSET + 12; //20 - protected static final int NEXT_PAGE_OFFSET = LEVEL_OFFSET + 1; // 21 - protected static final int VALID_OFFSET = NEXT_PAGE_OFFSET + 4; // 25 - - // The ADDITIONAL_FILTERING_PAGE_OFF is used only for LSM indexes. - // We store the page id that will be used to store the information of the the filter that is associated with a disk component. - // It is only set in the first meta page other meta pages (i.e., with level -2) have junk in the max page field. - private static final int ADDITIONAL_FILTERING_PAGE_OFFSET = VALID_OFFSET + 4; // 29 - public static final int LSN_OFFSET = ADDITIONAL_FILTERING_PAGE_OFFSET + 4; // 33 - private static final int LAST_MARKER_LSN_OFFSET = LSN_OFFSET + 8; // 41 - public static final int STORAGE_VERSION_OFFSET = LAST_MARKER_LSN_OFFSET + 4; //45 - public static final int ROOT_PAGE_NUMBER = STORAGE_VERSION_OFFSET + 4; //49 - private static final int HEADER_END_OFFSET = ROOT_PAGE_NUMBER + 4; // 53 + protected static final int MAX_PAGE_OFFSET = ITreeIndexFrame.Constants.RESERVED_HEADER_SIZE; + protected static final int NEXT_PAGE_OFFSET = MAX_PAGE_OFFSET + 4; + protected static final int VALID_OFFSET = NEXT_PAGE_OFFSET + 4; + protected static final int STORAGE_VERSION_OFFSET = VALID_OFFSET + 4; + protected static final int ROOT_PAGE_OFFSET = STORAGE_VERSION_OFFSET + 4; + protected static final int FREE_PAGE_COUNT_OFFSET = ROOT_PAGE_OFFSET + 4; + protected static final int HEADER_END_OFFSET = FREE_PAGE_COUNT_OFFSET + 4; protected ICachedPage page = null; protected ByteBuffer buf = null; @@ -70,44 +66,35 @@ public class LIFOMetaDataFrame implements ITreeIndexMetaDataFrame { @Override public int getFreePage() { - int tupleCount = buf.getInt(TUPLE_COUNT_OFFSET); - if (tupleCount > 0) { - // return the last page from the linked list of free pages - // TODO: this is a dumb policy, but good enough for now - int lastPageOff = buf.getInt(FREE_SPACE_OFFSET) - 4; - buf.putInt(FREE_SPACE_OFFSET, lastPageOff); - buf.putInt(TUPLE_COUNT_OFFSET, tupleCount - 1); - return buf.getInt(lastPageOff); - } else { - return -1; + int freePages = buf.getInt(FREE_PAGE_COUNT_OFFSET); + if (freePages > 0) { + decrement(FREE_PAGE_COUNT_OFFSET); + return buf.getInt(buf.array().length - Integer.BYTES * freePages); } + return -1; } - // must be checked before adding free page - // user of this class is responsible for getting a free page as a new meta - // page, latching it, etc. if there is no space on this page @Override - public boolean hasSpace() { - return buf.getInt(FREE_SPACE_OFFSET) + 4 < buf.capacity(); + public int getSpace() { + return buf.array().length - buf.getInt(Constants.FREE_SPACE_OFFSET) - (Integer.BYTES * buf.getInt( + FREE_PAGE_COUNT_OFFSET)); } - // no bounds checking is done, there must be free space @Override public void addFreePage(int freePage) { - int freeSpace = buf.getInt(FREE_SPACE_OFFSET); - buf.putInt(freeSpace, freePage); - buf.putInt(FREE_SPACE_OFFSET, freeSpace + 4); - buf.putInt(TUPLE_COUNT_OFFSET, buf.getInt(TUPLE_COUNT_OFFSET) + 1); + increment(FREE_PAGE_COUNT_OFFSET); + int numFreePages = buf.getInt(FREE_PAGE_COUNT_OFFSET); + buf.putInt(buf.array().length - (Integer.BYTES * numFreePages), freePage); } @Override public byte getLevel() { - return buf.get(LEVEL_OFFSET); + return buf.get(Constants.LEVEL_OFFSET); } @Override public void setLevel(byte level) { - buf.put(LEVEL_OFFSET, level); + buf.put(Constants.LEVEL_OFFSET, level); } @Override @@ -122,16 +109,15 @@ public class LIFOMetaDataFrame implements ITreeIndexMetaDataFrame { } @Override - public void initBuffer() { - buf.putInt(TUPLE_COUNT_OFFSET, 0); - buf.putInt(FREE_SPACE_OFFSET, HEADER_END_OFFSET); + public void init() { + buf.putInt(Constants.TUPLE_COUNT_OFFSET, 0); + buf.putInt(Constants.FREE_SPACE_OFFSET, HEADER_END_OFFSET); buf.putInt(MAX_PAGE_OFFSET, 0); - buf.put(LEVEL_OFFSET, META_PAGE_LEVEL_INDICATOR); + buf.put(Constants.LEVEL_OFFSET, META_PAGE_LEVEL_INDICATOR); buf.putInt(NEXT_PAGE_OFFSET, -1); - buf.putInt(ADDITIONAL_FILTERING_PAGE_OFFSET, -1); - buf.putLong(LAST_MARKER_LSN_OFFSET, -1L); - buf.putInt(ROOT_PAGE_NUMBER, 1); - buf.putInt(STORAGE_VERSION_OFFSET, VERSION); + buf.putInt(ROOT_PAGE_OFFSET, 1); + buf.putInt(FREE_PAGE_COUNT_OFFSET, 0); + buf.putInt(STORAGE_VERSION_OFFSET, ITreeIndexFrame.Constants.VERSION); setValid(false); } @@ -141,80 +127,191 @@ public class LIFOMetaDataFrame implements ITreeIndexMetaDataFrame { } @Override - public void setNextPage(int nextPage) { + public void setNextMetadataPage(int nextPage) { buf.putInt(NEXT_PAGE_OFFSET, nextPage); } @Override public boolean isValid() { - return buf.getInt(VALID_OFFSET) == MAGIC_VALID_INT || buf.getInt(VALID_OFFSET) == OBSOLETE_MAGIC_VALID_INT; + return buf.getInt(VALID_OFFSET) == MAGIC_VALID_INT; } @Override public void setValid(boolean isValid) { - if (isValid) { - buf.putInt(VALID_OFFSET, MAGIC_VALID_INT); - } else { - buf.putInt(VALID_OFFSET, 0); - } + buf.putInt(VALID_OFFSET, isValid ? MAGIC_VALID_INT : 0); } @Override - public long getLSN() { - return buf.getLong(LSN_OFFSET); + public int getVersion() { + return buf.getInt(STORAGE_VERSION_OFFSET); } @Override - public void setLSN(long lsn) { - buf.putLong(LSN_OFFSET, lsn); + public void setRootPageId(int rootPage) { + buf.putInt(ROOT_PAGE_OFFSET, rootPage); } @Override - public int getVersion() { - if (buf.getInt(VALID_OFFSET) == OBSOLETE_MAGIC_VALID_INT) { - return VERSION * -1; - } else { - return buf.getInt(STORAGE_VERSION_OFFSET); - } + public int getRootPageId() { + return buf.getInt(ROOT_PAGE_OFFSET); } @Override - public long getLastMarkerLSN() { - return buf.getLong(LAST_MARKER_LSN_OFFSET); + public boolean isMetadataPage() { + return getLevel() == META_PAGE_LEVEL_INDICATOR; } @Override - public void setLastMarkerLSN(long lsn) { - buf.putLong(LAST_MARKER_LSN_OFFSET, lsn); + public boolean isFreePage() { + return getLevel() == FREE_PAGE_LEVEL_INDICATOR; } @Override - public int getLSMComponentFilterPageId() { - return buf.getInt(ADDITIONAL_FILTERING_PAGE_OFFSET); + public void get(IValueReference key, IPointable value) { + int tupleCount = getTupleCount(); + int tupleStart = getTupleStart(0); + for (int i = 0; i < tupleCount; i++) { + if (isInner(key, tupleStart)) { + get(tupleStart + key.getLength() + Integer.BYTES, value); + return; + } + tupleStart = getNextTupleStart(tupleStart); + } + value.set(null, 0, 0); } - @Override - public void setLSMComponentFilterPageId(int filterPage) { - buf.putInt(ADDITIONAL_FILTERING_PAGE_OFFSET, filterPage); + private int find(IValueReference key) { + int tupleCount = getTupleCount(); + int tupleStart = getTupleStart(0); + for (int i = 0; i < tupleCount; i++) { + if (isInner(key, tupleStart)) { + return i; + } + tupleStart = getNextTupleStart(tupleStart); + } + return -1; + } + + private void get(int offset, IPointable value) { + int valueLength = buf.getInt(offset); + value.set(buf.array(), offset + Integer.BYTES, valueLength); + } + + private static final int compare(byte[] b1, int s1, byte[] b2, int s2, int l) { + for (int i = 0; i < l; i++) { + if (b1[s1 + i] != b2[s2 + i]) { + return b1[s1 + i] - b2[s2 + i]; + } + } + return 0; + } + + private boolean isInner(IValueReference key, int tupleOffset) { + int keySize = buf.getInt(tupleOffset); + if (keySize == key.getLength()) { + return LIFOMetaDataFrame.compare(key.getByteArray(), key.getStartOffset(), buf.array(), tupleOffset + + Integer.BYTES, keySize) == 0; + } + return false; + } + + private int getTupleStart(int index) { + int offset = HEADER_END_OFFSET; + int i = 0; + while (i < index) { + i++; + offset = getNextTupleStart(offset); + } + return offset; + } + + private int getNextTupleStart(int prevTupleOffset) { + int keyLength = buf.getInt(prevTupleOffset); + int offset = prevTupleOffset + keyLength + Integer.BYTES; + return offset + buf.getInt(offset) + Integer.BYTES; + } + + private void put(int index, IValueReference value) throws HyracksDataException { + int offset = getTupleStart(index); + int length = buf.getInt(offset); + offset += Integer.BYTES + length; + length = buf.getInt(offset); + if (length != value.getLength()) { + throw new HyracksDataException("This frame doesn't support overwriting dynamically sized values"); + } + offset += Integer.BYTES; + System.arraycopy(value.getByteArray(), value.getStartOffset(), buf.array(), offset, value.getLength()); } @Override - public void setRootPageNumber(int rootPage) { - buf.putInt(ROOT_PAGE_NUMBER, rootPage); + public void put(IValueReference key, IValueReference value) throws HyracksDataException { + int index = find(key); + if (index >= 0) { + put(index, value); + } else { + int offset = buf.getInt(Constants.FREE_SPACE_OFFSET); + int available = getSpace(); + int required = key.getLength() + Integer.BYTES + Integer.BYTES + value.getLength(); + if (available < required) { + throw new HyracksDataException("Available space in the page (" + + available + ") is not enough to store the key value pair(" + required + ")"); + } + buf.putInt(offset, key.getLength()); + offset += Integer.BYTES; + System.arraycopy(key.getByteArray(), key.getStartOffset(), buf.array(), offset, key.getLength()); + offset += key.getLength(); + buf.putInt(offset, value.getLength()); + offset += Integer.BYTES; + System.arraycopy(value.getByteArray(), value.getStartOffset(), buf.array(), offset, value.getLength()); + offset += value.getLength(); + increment(Constants.TUPLE_COUNT_OFFSET); + buf.putInt(Constants.FREE_SPACE_OFFSET, offset); + } } @Override - public int getRootPageNumber() { - return buf.getInt(ROOT_PAGE_NUMBER); + public int getTupleCount() { + return buf.getInt(Constants.TUPLE_COUNT_OFFSET); + } + + private void increment(int offset) { + buf.putInt(offset, buf.getInt(offset) + 1); + } + + private void decrement(int offset) { + buf.putInt(offset, buf.getInt(offset) - 1); } @Override - public boolean isMetadataPage() { - return getLevel() == META_PAGE_LEVEL_INDICATOR; + public int getOffset(IValueReference key) { + int index = find(key); + if (index >= 0) { + int offset = getTupleStart(index); + return offset + key.getLength() + 2 * Integer.BYTES; + } + return -1; } @Override - public boolean isFreePage() { - return getLevel() == FREE_PAGE_LEVEL_INDICATOR; + public String toString() { + StringBuilder aString = new StringBuilder(this.getClass().getSimpleName()).append('\n'). + append("Tuple Count: " + getTupleCount()).append('\n'). + append("Free Space offset: " + buf.getInt(Constants.FREE_SPACE_OFFSET)).append('\n'). + append("Level: " + buf.get(Constants.LEVEL_OFFSET)).append('\n'). + append("Version: " + buf.getInt(STORAGE_VERSION_OFFSET)).append('\n'). + append("Max Page: " + buf.getInt(MAX_PAGE_OFFSET)).append('\n'). + append("Root Page: " + buf.getInt(ROOT_PAGE_OFFSET)).append('\n'). + append("Number of free pages: " + buf.getInt(FREE_PAGE_COUNT_OFFSET)); + int tupleCount = getTupleCount(); + int offset; + for (int i = 0; i < tupleCount; i++) { + offset = getTupleStart(i); + int keyLength = buf.getInt(offset); + aString.append('\n').append("Key " + i + " size = " + keyLength); + offset += Integer.BYTES + keyLength; + int valueLength = buf.getInt(offset); + aString.append(", Value " + i + " size = " + valueLength); + } + return aString.toString(); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/90cdbac7/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrameFactory.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrameFactory.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrameFactory.java index b0406c2..4dbba02 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrameFactory.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/frames/LIFOMetaDataFrameFactory.java @@ -18,12 +18,12 @@ */ package org.apache.hyracks.storage.am.common.frames; -import org.apache.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame; -import org.apache.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory; +import org.apache.hyracks.storage.am.common.api.ITreeIndexMetadataFrame; +import org.apache.hyracks.storage.am.common.api.ITreeIndexMetadataFrameFactory; -public class LIFOMetaDataFrameFactory implements ITreeIndexMetaDataFrameFactory { +public class LIFOMetaDataFrameFactory implements ITreeIndexMetadataFrameFactory { @Override - public ITreeIndexMetaDataFrame createFrame() { + public ITreeIndexMetadataFrame createFrame() { return new LIFOMetaDataFrame(); } }