diff --git a/pom.xml b/pom.xml
index 1933a63..fbbd19b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -139,7 +139,7 @@
sign,deploy-to-scijava
- 4.0.0-alpha-9
+ 4.0.0-alpha-12-SNAPSHOT
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Reader.java b/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Reader.java
index e19a23e..84ff01e 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Reader.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Reader.java
@@ -688,8 +688,9 @@ public DatasetAttributes getDatasetAttributes(String pathName) {
new RawCompression());
}
+ @SuppressWarnings("unchecked")
@Override
- public DataBlock> readBlock(
+ public DataBlock readBlock(
String pathName,
final DatasetAttributes datasetAttributes,
final long... gridPosition) throws N5Exception {
@@ -713,7 +714,7 @@ public DataBlock> readBlock(
if (datasetAttributes.getDataType() == DataType.STRING) {
final int[] intHdf5CroppedBlockSize = Arrays.stream(hdf5CroppedBlockSize).mapToInt(i -> (int)i).toArray();
MDArray data = reader.string().readMDArrayBlockWithOffset(normalizedPathName, intHdf5CroppedBlockSize, hdf5Offset);
- return new StringDataBlock(croppedBlockSize, gridPosition, data.getAsFlatArray());
+ return (DataBlock)new StringDataBlock(croppedBlockSize, gridPosition, data.getAsFlatArray());
}
final DataType dataType = datasetAttributes.getDataType();
@@ -733,7 +734,7 @@ public DataBlock> readBlock(
H5Sclose(fileSpaceId);
H5Sclose(memorySpaceId);
}
- return block;
+ return (DataBlock)block;
}
@Override
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Writer.java b/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Writer.java
index 9997ccc..148ef5b 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Writer.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/hdf5/N5HDF5Writer.java
@@ -47,6 +47,9 @@
import org.janelia.saalfeldlab.n5.N5Writer;
import org.janelia.saalfeldlab.n5.RawCompression;
import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Util.OpenDataSetCache.OpenDataSet;
+import org.janelia.saalfeldlab.n5.shard.Region;
+import org.janelia.saalfeldlab.n5.shard.Nesting.NestedGrid;
+import org.janelia.saalfeldlab.n5.shard.Nesting.NestedPosition;
import java.io.File;
import java.io.IOException;
@@ -55,6 +58,8 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
import static hdf.hdf5lib.H5.H5Dget_space;
import static hdf.hdf5lib.H5.H5Dwrite;
@@ -564,6 +569,50 @@ public void writeShard(
writeBlock(pathName, datasetAttributes, dataBlock);
}
+ @Override
+ public void writeRegion(
+ String datasetPath,
+ DatasetAttributes datasetAttributes,
+ long[] min,
+ long[] size,
+ DataBlockSupplier dataBlocks,
+ boolean writeFully) throws N5Exception {
+
+ final NestedGrid grid = datasetAttributes.getNestedBlockGrid();
+ final Region region = new Region(min, size, grid);
+ for (long[] key : Region.gridPositions(region.minPos().key(), region.maxPos().key())) {
+ final NestedPosition pos = grid.nestedPosition(key, 0); // HDF5 is never nested, get level 0
+ final long[] gridPosition = pos.absolute(0);
+ final DataBlock existingDataBlock = writeFully || region.fullyContains(pos)
+ ? null
+ : readBlock(datasetPath, datasetAttributes, gridPosition);
+ final DataBlock dataBlock = dataBlocks.get(gridPosition, existingDataBlock);
+ // null blocks may be provided when they contain only the fill value
+ // and only non-empty blocks should be written, for example
+ if (dataBlock == null) {
+ deleteBlock(datasetPath, datasetAttributes, gridPosition);
+ } else {
+ writeBlock(datasetPath, datasetAttributes, dataBlock);
+ }
+ }
+
+ }
+
+ public void writeRegion(
+ String datasetPath,
+ DatasetAttributes datasetAttributes,
+ long[] min,
+ long[] size,
+ DataBlockSupplier dataBlocks,
+ boolean writeFully,
+ ExecutorService exec) throws N5Exception, InterruptedException, ExecutionException {
+
+ // block until the write is complete
+ exec.submit(() -> {
+ writeRegion(datasetPath, datasetAttributes, min, size, dataBlocks, writeFully);
+ }).get();
+ }
+
@Override
public boolean deleteBlock(String pathName, final long... gridPosition) throws N5Exception {