@Override public ITreeIndexMetadataFrame createFrame() { return new LIFOMetaDataFrame(); } }
@Override 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 int getFreePage() { 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; }
@Override 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; }
@Test public void test() throws HyracksDataException { LIFOMetaDataFrame frame = new LIFOMetaDataFrame(); VirtualPage page = new VirtualPage(ByteBuffer.allocate(512), 512); MutableArrayValueReference testKey = new MutableArrayValueReference("TestLSNKey".getBytes()); frame.setPage(page); frame.init(); LongPointable longPointable = (LongPointable) LongPointable.FACTORY.createPointable(); frame.get(testKey, longPointable); Assert.assertNull(longPointable.getByteArray()); byte[] longBytes = new byte[Long.BYTES]; MutableArrayValueReference value = new MutableArrayValueReference(longBytes); int space = frame.getSpace() - (value.getLength() + Integer.BYTES * 2 + testKey.getLength()); for (long l = 1L; l < 52L; l++) { LongPointable.setLong(longBytes, 0, l); frame.put(testKey, value); Assert.assertEquals(space, frame.getSpace()); frame.get(testKey, longPointable); Assert.assertEquals(l, longPointable.longValue()); Assert.assertEquals(frame.getFreePage(), -1); frame.addFreePage(i); space -= Integer.BYTES; Assert.assertEquals(space, frame.getSpace()); int freePage = frame.getFreePage(); Assert.assertEquals(freePage, i); space += Integer.BYTES; Assert.assertEquals(space, frame.getSpace());
@Override 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 boolean isFreePage() { return getLevel() == FREE_PAGE_LEVEL_INDICATOR; }
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; }
@Override public boolean isMetadataPage() { return getLevel() == META_PAGE_LEVEL_INDICATOR; }