Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
8e79825
add ZipStore tests
brokkoli71 Nov 28, 2025
2611738
refactor and unify outputs of Store.list
brokkoli71 Dec 1, 2025
5e2e017
read zip store
brokkoli71 Dec 1, 2025
4a9f7f0
Bump to 0.0.6 to trigger release
joshmoore Dec 4, 2025
99081e5
Bump to 0.0.7
joshmoore Dec 4, 2025
268890e
Bump to 0.0.8
joshmoore Dec 4, 2025
b9e6db4
Bump to 0.0.9
joshmoore Dec 4, 2025
08afc36
write buffer of zip store
brokkoli71 Dec 5, 2025
0cacc5b
use apache commons compress for zip file read and write
brokkoli71 Dec 5, 2025
5b74372
set Zip64Mode.AsNeeded
brokkoli71 Dec 11, 2025
ee92e27
test Zipped OME-Zarr requirements
brokkoli71 Dec 11, 2025
a344655
Sort zarr.json files in breadth-first order within BufferedZipStore
brokkoli71 Dec 11, 2025
ea16692
manually read zip comment
brokkoli71 Dec 12, 2025
7e0164f
refactor read zip comment
brokkoli71 Dec 12, 2025
02445e0
test zip store with v2
brokkoli71 Dec 12, 2025
caafad0
use com.fasterxml.jackson.databind.util.ByteBufferBackedInputStream i…
brokkoli71 Dec 12, 2025
dbc559c
add ReadOnlyZipStore
brokkoli71 Dec 12, 2025
db57be7
fix ReadOnlyZipStore for zips with
brokkoli71 Dec 12, 2025
768bd62
add BufferedZipStore parameter flushOnWrite
brokkoli71 Dec 12, 2025
38bec27
fix testMemoryStore
brokkoli71 Dec 12, 2025
bdcbc46
default flushOnWrite to false
brokkoli71 Dec 12, 2025
9014fef
fix s3 store get range
brokkoli71 Dec 15, 2025
5c74445
add store.getInputStream
brokkoli71 Dec 18, 2025
7e0e90e
add store.getSize
brokkoli71 Dec 18, 2025
086d3f8
improve performance of ReadOnlyZipStore.getArchiveComment
brokkoli71 Dec 18, 2025
7d4f487
inherit zipstores from common parent and reduce buffers in memory in …
brokkoli71 Dec 18, 2025
ca88fb5
Merge branch 'main' into zip-store
brokkoli71 Jan 5, 2026
72ef229
fix s3 test buckets
brokkoli71 Jan 5, 2026
e8fb440
reduce getArchiveComment store requests
brokkoli71 Jan 5, 2026
2927ca7
Merge branch 'main' into zip-store
brokkoli71 Jan 5, 2026
8b390bc
format
brokkoli71 Jan 5, 2026
7b064c8
fix merge
brokkoli71 Jan 5, 2026
d98767c
improve Group::list performance
brokkoli71 Jan 11, 2026
e4514b2
fix ReadOnlyZipStore::list
brokkoli71 Jan 11, 2026
76aacb8
less requests to store on read
brokkoli71 Jan 11, 2026
60e11d7
fix FilesystemStore::list
brokkoli71 Jan 11, 2026
cd349f9
fix MemoryStore::list
brokkoli71 Jan 11, 2026
a1c54ea
fix ReadOnlyZipStore::list
brokkoli71 Jan 11, 2026
a2aef00
test Store::list for local stores
brokkoli71 Jan 11, 2026
4f7bee8
less store.exists() for v2.Group.list()
brokkoli71 Jan 12, 2026
60e28cd
add S3Mock for tests
brokkoli71 Jan 12, 2026
51d0f36
fallback to chunkHandle.exists() for non listable stores
brokkoli71 Jan 12, 2026
b309922
fix ZarrV2Test::testGroup
brokkoli71 Jan 12, 2026
cac3e22
downgrade s3mock version to match java-version 11
brokkoli71 Jan 12, 2026
8d5d583
downgrade s3mock version to match java-version 11
brokkoli71 Jan 12, 2026
c64ea1c
run S3 Mock with docker
brokkoli71 Jan 16, 2026
55d5475
S3Mock tests only on linux
brokkoli71 Jan 16, 2026
5ae5ac2
fix ZarrV3Test::testGroup for windows, mac
brokkoli71 Jan 16, 2026
8c4e988
refactor and add missing store tests
brokkoli71 Jan 16, 2026
4e4f1e8
fix s3Store::list
brokkoli71 Jan 16, 2026
8d64385
fix ReadOnlyZipStore::list
brokkoli71 Jan 16, 2026
78c0e3a
add tests
brokkoli71 Jan 16, 2026
9b73829
fix tests with path collision
brokkoli71 Jan 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ jobs:
os: [ ubuntu-latest, windows-latest, macos-latest ]
fail-fast: false
runs-on: ${{ matrix.os }}
services:
s3mock:
# This service will only start if the runner is Linux
image: ${{ matrix.os == 'ubuntu-latest' && 'adobe/s3mock:3.11.0' || '' }}
ports:
- 9090:9090
env:
initialBuckets: zarr-test-bucket
defaults:
run:
shell: bash
Expand Down Expand Up @@ -49,8 +57,13 @@ jobs:
- name: Test
env:
MAVEN_OPTS: "-Xmx6g"
run: mvn --no-transfer-progress test -DargLine="-Xmx6g"

run: |
if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then
mvn --no-transfer-progress test -DargLine="-Xmx6g"
else
# Skip S3 tests on Windows/macOS where the service isn't running (labeled with @Tag("s3"))
mvn --no-transfer-progress test -DargLine="-Xmx6g" -DexcludedGroups="s3"
fi
- name: Assemble JAR
run: mvn package -DskipTests

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ build/
/main.py
/pyproject.toml
/uv.lock
**/__pycache__
**/__pycache__
/dependency-reduced-pom.xml
9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.28.0</version>
</dependency>
</dependencies>

<repositories>
Expand All @@ -139,6 +144,10 @@
<version>3.2.5</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<environmentVariables>
<!-- Force Testcontainers to use a newer Docker API version supported by your local Daemon -->
<DOCKER_API_VERSION>1.44</DOCKER_API_VERSION>
</environmentVariables>
</configuration>
</plugin>
<plugin>
Expand Down
23 changes: 20 additions & 3 deletions src/main/java/dev/zarr/zarrjava/core/Array.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dev.zarr.zarrjava.ZarrException;
import dev.zarr.zarrjava.core.codec.CodecPipeline;
import dev.zarr.zarrjava.store.FilesystemStore;
import dev.zarr.zarrjava.store.Store;
import dev.zarr.zarrjava.store.StoreHandle;
import dev.zarr.zarrjava.utils.IndexingUtils;
import dev.zarr.zarrjava.utils.MultiArrayUtils;
Expand All @@ -16,6 +17,9 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public abstract class Array extends AbstractNode {
Expand Down Expand Up @@ -289,6 +293,15 @@ public ucar.ma2.Array read(final long[] offset, final int[] shape, final boolean
if (parallel) {
chunkStream = chunkStream.parallel();
}

boolean isListableStore = storeHandle.store instanceof Store.ListableStore;
Set<List<String>> existingKeys;
if (isListableStore) {
existingKeys = storeHandle.list().map(Arrays::asList).collect(Collectors.toSet());
} else {
existingKeys = null;
}

chunkStream.forEach(
chunkCoords -> {
try {
Expand All @@ -306,9 +319,13 @@ public ucar.ma2.Array read(final long[] offset, final int[] shape, final boolean

final String[] chunkKeys = metadata.chunkKeyEncoding().encodeChunkKey(chunkCoords);
final StoreHandle chunkHandle = storeHandle.resolve(chunkKeys);
if (!chunkHandle.exists()) {
return;
}

// chunkHandle.exists() can be expensive on some store types, so we optimize for ListableStore
if (isListableStore) {
if (existingKeys.stream().noneMatch(Arrays.asList(chunkKeys)::equals))
return;
} else if (!chunkHandle.exists()) return;

if (codecPipeline.supportsPartialDecode()) {
final ucar.ma2.Array chunkArray = codecPipeline.decodePartial(chunkHandle,
Utils.toLongArray(chunkProjection.chunkOffset), chunkProjection.shape);
Expand Down
18 changes: 6 additions & 12 deletions src/main/java/dev/zarr/zarrjava/core/Group.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.stream.Stream;

public abstract class Group extends AbstractNode {
Expand Down Expand Up @@ -64,20 +63,15 @@ public static Group open(String path) throws IOException, ZarrException {
}

@Nullable
public abstract Node get(String key) throws ZarrException, IOException;
public abstract Node get(String[] key) throws ZarrException, IOException;

public Stream<Node> list() {
return storeHandle.list()
.map(key -> {
try {
return get(key);
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.filter(Objects::nonNull);
@Nullable
public Node get(String key) throws ZarrException, IOException {
return get(new String[]{key});
}

public abstract Stream<Node> list();

public Node[] listAsArray() {
try (Stream<Node> nodeStream = list()) {
return nodeStream.toArray(Node[]::new);
Expand Down
Loading
Loading