From 82cb1216a47f44fdd02ad93a1785e456ac9bd9b2 Mon Sep 17 00:00:00 2001 From: James Mudd Date: Wed, 20 Nov 2024 20:57:04 +0000 Subject: [PATCH] Convert to lazy init data block --- .../chunked/indexing/FixedArrayIndex.java | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/jhdf/src/main/java/io/jhdf/dataset/chunked/indexing/FixedArrayIndex.java b/jhdf/src/main/java/io/jhdf/dataset/chunked/indexing/FixedArrayIndex.java index 8199bf91..f90a4d43 100644 --- a/jhdf/src/main/java/io/jhdf/dataset/chunked/indexing/FixedArrayIndex.java +++ b/jhdf/src/main/java/io/jhdf/dataset/chunked/indexing/FixedArrayIndex.java @@ -15,8 +15,11 @@ import io.jhdf.dataset.chunked.DatasetInfo; import io.jhdf.exceptions.HdfException; import io.jhdf.storage.HdfBackingStorage; +import org.apache.commons.lang3.concurrent.ConcurrentException; +import org.apache.commons.lang3.concurrent.LazyInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -30,6 +33,8 @@ public class FixedArrayIndex implements ChunkIndex { private static final byte[] FIXED_ARRAY_HEADER_SIGNATURE = "FAHD".getBytes(StandardCharsets.US_ASCII); private static final byte[] FIXED_ARRAY_DATA_BLOCK_SIGNATURE = "FADB".getBytes(StandardCharsets.US_ASCII); + private static final Logger logger = LoggerFactory.getLogger(FixedArrayIndex.class); + private final long address; private final int unfilteredChunkSize; @@ -42,9 +47,10 @@ public class FixedArrayIndex implements ChunkIndex { private final int maxNumberOfEntries; private final long dataBlockAddress; private final int pages; - private final List chunks; private final int pageSize; + private final FixedArrayDataBlockInitializer dataBlockInitializer; + public FixedArrayIndex(HdfBackingStorage hdfBackingStorage, long address, DatasetInfo datasetInfo) { this.address = address; this.unfilteredChunkSize = datasetInfo.getChunkSizeInBytes(); @@ -78,18 +84,37 @@ public FixedArrayIndex(HdfBackingStorage hdfBackingStorage, long address, Datase dataBlockAddress = Utils.readBytesAsUnsignedLong(bb, hdfBackingStorage.getSizeOfOffsets()); - chunks = new ArrayList<>(maxNumberOfEntries); - // Checksum bb.rewind(); ChecksumUtils.validateChecksum(bb); + logger.info("Read fixed array index header. pages=[{}], maxEntries=[{}]", pages, maxNumberOfEntries); + // Building the object fills the chunks. Probably should be changed - new FixedArrayDataBlock(this, hdfBackingStorage, dataBlockAddress); +// new FixedArrayDataBlock(this, hdfBackingStorage, dataBlockAddress); + dataBlockInitializer = new FixedArrayDataBlockInitializer(hdfBackingStorage); + } + + private class FixedArrayDataBlockInitializer extends LazyInitializer { + + private final HdfBackingStorage hdfBackingStorage; + + public FixedArrayDataBlockInitializer(HdfBackingStorage hdfBackingStorage) { + this.hdfBackingStorage = hdfBackingStorage; + } + + @Override + protected FixedArrayDataBlock initialize() { + logger.info("Initializing data block"); + return new FixedArrayDataBlock(FixedArrayIndex.this, hdfBackingStorage, FixedArrayIndex.this.dataBlockAddress); + } + } private class FixedArrayDataBlock { + private final List chunks = new ArrayList<>(maxNumberOfEntries); + private FixedArrayDataBlock(FixedArrayIndex fixedArrayIndex, HdfBackingStorage hdfBackingStorage, long address) { // TODO header size ignoring paging @@ -184,18 +209,22 @@ private void readFiltered(FixedArrayIndex fixedArrayIndex, HdfBackingStorage hdf final BitSet filterMask = BitSet.valueOf(new byte[]{bb.get(), bb.get(), bb.get(), bb.get()}); final int[] chunkOffset = Utils.chunkIndexToChunkOffset(i, fixedArrayIndex.chunkDimensions, fixedArrayIndex.datasetDimensions); - fixedArrayIndex.chunks.add(new ChunkImpl(chunkAddress, chunkSizeInBytes, chunkOffset, filterMask)); + chunks.add(new ChunkImpl(chunkAddress, chunkSizeInBytes, chunkOffset, filterMask)); } private void readUnfiltered(FixedArrayIndex fixedArrayIndex, int sizeOfOffsets, ByteBuffer bb, int chunkIndex) { final long chunkAddress = Utils.readBytesAsUnsignedLong(bb, sizeOfOffsets); final int[] chunkOffset = Utils.chunkIndexToChunkOffset(chunkIndex, fixedArrayIndex.chunkDimensions, fixedArrayIndex.datasetDimensions); - fixedArrayIndex.chunks.add(new ChunkImpl(chunkAddress, fixedArrayIndex.unfilteredChunkSize, chunkOffset)); + chunks.add(new ChunkImpl(chunkAddress, fixedArrayIndex.unfilteredChunkSize, chunkOffset)); } } @Override public Collection getAllChunks() { - return chunks; + try { + return this.dataBlockInitializer.get().chunks; + } catch (ConcurrentException e) { + throw new HdfException("Error initializing data block", e); + } } }