FractalHeap { public ByteBuffer getId(ByteBuffer buffer) { if (buffer.remaining() != idLength) { throw new HdfException("ID length is incorrect accessing fractal heap at address " + address + ". IDs should be " + idLength + " bytes but was " + buffer.capacity() + " bytes."); } BitSet idFlags = BitSet.valueOf(new byte[] { buffer.get() }); final int version = bitsToInt(idFlags, 6, 2); if (version != 0) { throw new HdfException("Unsupported btree v2 ID version detected. Version: " + version); } final int type = bitsToInt(idFlags, 4, 2); switch (type) { case 0: long offset = readBytesAsUnsignedLong(buffer, bytesToStoreOffset); int length = readBytesAsUnsignedInt(buffer, bytesToStoreLength); logger.debug("Getting ID at offset={} length={}", offset, length); Entry<Long, DirectBlock> entry = directBlocks.floorEntry(offset); ByteBuffer bb = entry.getValue().getData(); bb.order(LITTLE_ENDIAN); bb.position(Math.toIntExact(offset - entry.getKey())); return createSubBuffer(bb, length); case 1: if (this.bTreeAddressOfHugeObjects <= 0) { throw new UnsupportedHdfException("Huge objects without BTreev2 are currently not supported"); } BTreeV2<HugeFractalHeapObjectUnfilteredRecord> hugeObjectBTree = new BTreeV2<>(this.hdfFc, this.bTreeAddressOfHugeObjects); if (hugeObjectBTree.getRecords().size() != 1) { throw new UnsupportedHdfException("Only Huge objects BTrees with 1 record are currently supported"); } HugeFractalHeapObjectUnfilteredRecord ho = hugeObjectBTree.getRecords().get(0); return this.hdfFc.readBufferFromAddress(ho.getAddress(), (int) ho.getLength()); case 2: throw new UnsupportedHdfException("Tiny objects are currently not supported"); default: throw new HdfException("Unrecognized ID type, type=" + type); } } FractalHeap(HdfFileChannel hdfFc, long address); ByteBuffer getId(ByteBuffer buffer); @Override String toString(); long getAddress(); int getMaxDirectBlockSize(); long getMaxSizeOfManagedObjects(); int getIdLength(); int getIoFiltersLength(); int getStartingRowsInRootIndirectBlock(); long getNumberOfTinyObjectsInHeap(); long getSizeOfTinyObjectsInHeap(); long getNumberOfHugeObjectsInHeap(); long getSizeOfHugeObjectsInHeap(); long getNumberOfManagedObjectsInHeap(); long getOffsetOfDirectBlockAllocationIteratorInManagedSpace(); long getAmountOfAllocatedManagedSpaceInHeap(); long getAmountOfManagedSpaceInHeap(); long getAddressOfManagedBlocksFreeSpaceManager(); long getFreeSpaceInManagedBlocks(); long getBTreeAddressOfHugeObjects(); long getNextHugeObjectId();  }
@Test void testGetIdWorksForValidId() { ByteBuffer id = ByteBuffer.allocate(7); id.put(new byte[] { 0 }); id.putInt(3129); id.putShort((short) 18); id.rewind(); ByteBuffer data = fractalHeap.getId(id); assertThat(data.position(), is(equalTo(0))); assertThat(data.limit(), is(equalTo(18))); }
@Test void testWrongIdLengthThrows() { ByteBuffer bb = ByteBuffer.allocate(12); assertThrows(HdfException.class, () -> fractalHeap.getId(bb)); }