Skip to content

Commit 4f80830

Browse files
committed
test store::exist, list, listChildren
1 parent ffd5deb commit 4f80830

16 files changed

Lines changed: 252 additions & 55 deletions

src/main/java/dev/zarr/zarrjava/store/BufferedZipStore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public Stream<String[]> list(String[] keys) {
246246
}
247247

248248
@Override
249-
public Stream<String[]> listChildren(String[] prefix) {
249+
public Stream<String> listChildren(String[] prefix) {
250250
return bufferStore.listChildren(prefix);
251251
}
252252

src/main/java/dev/zarr/zarrjava/store/FilesystemStore.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Path resolveKeys(String[] keys) {
3535

3636
@Override
3737
public boolean exists(String[] keys) {
38-
return Files.exists(resolveKeys(keys));
38+
return Files.isRegularFile(resolveKeys(keys));
3939
}
4040

4141
@Nullable
@@ -148,14 +148,13 @@ public Stream<String[]> list(String[] prefix) {
148148
}
149149

150150
@Override
151-
public Stream<String[]> listChildren(String[] prefix) {
151+
public Stream<String> listChildren(String[] prefix) {
152152
Path rootPath = resolveKeys(prefix);
153153
if (!Files.exists(rootPath) || !Files.isDirectory(rootPath)) {
154154
return Stream.empty();
155155
}
156156
try {
157-
return Files.list(rootPath) // note: Files.list is non-recursive
158-
.map(path -> pathToKeyArray(rootPath, path, prefix));
157+
return Files.list(rootPath).map(path -> path.getFileName().toString());
159158
} catch (IOException e) {
160159
throw new RuntimeException("Failed to list store children", e);
161160
}

src/main/java/dev/zarr/zarrjava/store/MemoryStore.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import javax.annotation.Nullable;
55
import java.io.InputStream;
66
import java.nio.ByteBuffer;
7-
import java.util.*;
7+
import java.util.ArrayList;
8+
import java.util.Arrays;
9+
import java.util.List;
10+
import java.util.Map;
811
import java.util.concurrent.ConcurrentHashMap;
912
import java.util.stream.Stream;
1013

@@ -71,21 +74,14 @@ public Stream<String[]> list(String[] prefix) {
7174
}
7275

7376
@Override
74-
public Stream<String[]> listChildren(String[] prefix) {
77+
public Stream<String> listChildren(String[] prefix) {
7578
List<String> prefixList = resolveKeys(prefix);
7679
int prefixSize = prefixList.size();
7780

7881
return map.keySet().stream()
7982
.filter(key -> key.size() > prefixSize && key.subList(0, prefixSize).equals(prefixList))
80-
// Identify the immediate child segment
81-
// e.g. if prefix is [a], and key is [a, b, c], the child is [a, b]
82-
.map(key -> {
83-
List<String> childPath = new ArrayList<>(prefixList);
84-
childPath.add(key.get(prefixSize));
85-
return childPath;
86-
})
87-
.distinct()
88-
.map(list -> list.toArray(new String[0]));
83+
.map(key -> key.get(prefixSize))
84+
.distinct();
8985
}
9086

9187
@Nonnull

src/main/java/dev/zarr/zarrjava/store/ReadOnlyZipStore.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import java.nio.ByteBuffer;
1313
import java.nio.file.Path;
1414
import java.nio.file.Paths;
15+
import java.util.LinkedHashSet;
16+
import java.util.Set;
1517
import java.util.stream.Stream;
1618

1719

@@ -143,13 +145,14 @@ public Stream<String[]> list(String[] prefixKeys) {
143145
builder.add(resolveEntryKeys(name.substring(prefix.length())));
144146
}
145147
}
146-
} catch (IOException ignored) {}
148+
} catch (IOException ignored) {
149+
}
147150
return builder.build();
148151
}
149152

150153
@Override
151-
public Stream<String[]> listChildren(String[] prefixKeys) {
152-
java.util.Set<String> children = new java.util.LinkedHashSet<>();
154+
public Stream<String> listChildren(String[] prefixKeys) {
155+
Set<String> children = new LinkedHashSet<>();
153156
InputStream inputStream = underlyingStore.getInputStream();
154157
if (inputStream == null) return Stream.empty();
155158

@@ -166,19 +169,13 @@ public Stream<String[]> listChildren(String[] prefixKeys) {
166169
if (name.startsWith(prefix) && !name.equals(prefix)) {
167170
String relative = name.substring(prefix.length());
168171
String[] parts = relative.split("/");
169-
// The child is the prefix + the very next segment
170-
String childSegment = parts[0];
171-
children.add(childSegment);
172+
children.add(parts[0]);
172173
}
173174
}
174-
} catch (IOException ignored) {}
175-
176-
return children.stream().map(segment -> {
177-
String[] result = new String[prefixKeys.length + 1];
178-
System.arraycopy(prefixKeys, 0, result, 0, prefixKeys.length);
179-
result[prefixKeys.length] = segment;
180-
return result;
181-
});
175+
} catch (IOException ignored) {
176+
}
177+
178+
return children.stream();
182179
}
183180

184181
private String normalizeEntryName(String name) {

src/main/java/dev/zarr/zarrjava/store/S3Store.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
import java.io.IOException;
1313
import java.io.InputStream;
1414
import java.nio.ByteBuffer;
15-
import java.util.ArrayList;
16-
import java.util.List;
1715
import java.util.stream.Stream;
1816

1917
public class S3Store implements Store, Store.ListableStore {
@@ -52,9 +50,6 @@ ByteBuffer get(GetObjectRequest getObjectRequest) {
5250

5351
@Override
5452
public boolean exists(String[] keys) {
55-
if (keys == null || keys.length == 0) {
56-
return true;
57-
}
5853
HeadObjectRequest req = HeadObjectRequest.builder().bucket(bucketName).key(resolveKeys(keys)).build();
5954
try {
6055
return s3client.headObject(req).sdkHttpResponse().statusCode() == 200;
@@ -152,7 +147,7 @@ public Stream<String[]> list(String[] keys) {
152147
}
153148

154149
@Override
155-
public Stream<String[]> listChildren(String[] keys) {
150+
public Stream<String> listChildren(String[] keys) {
156151
String fullPrefix = resolveKeys(keys);
157152
if (!fullPrefix.isEmpty() && !fullPrefix.endsWith("/")) {
158153
fullPrefix += "/";
@@ -173,7 +168,7 @@ public Stream<String[]> listChildren(String[] keys) {
173168
.filter(key -> !key.equals(finalFullPrefix));
174169

175170
return Stream.concat(folders, files)
176-
.map(k -> keyToRelativeArray(k, finalFullPrefix));
171+
.map(k -> keyToRelativeArray(k, finalFullPrefix)[0]);
177172
}
178173

179174
/**

src/main/java/dev/zarr/zarrjava/store/Store.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ interface ListableStore extends Store {
5151
* Directory-only entries are excluded.
5252
*
5353
* @param prefix The prefix keys to match.
54-
* @return A stream of full key arrays containing data.
54+
* @return A stream of key arrays containing data.
5555
*/
5656
Stream<String[]> list(String[] prefix);
5757

@@ -60,12 +60,23 @@ interface ListableStore extends Store {
6060
* This is useful for UI navigation or browsing the store hierarchy.
6161
*
6262
* @param prefix The prefix keys to explore.
63-
* @return A stream of key arrays representing one level deeper than the prefix.
63+
* @return A stream of keys representing one level deeper than the prefix.
6464
*/
65-
Stream<String[]> listChildren(String[] prefix);
65+
Stream<String> listChildren(String[] prefix);
66+
67+
/**
68+
* Lists the immediate children (files and virtual directories) under the store root.
69+
*
70+
* @return A stream of keys.
71+
*/
72+
default Stream<String> listChildren() {
73+
return listChildren(new String[]{});
74+
}
6675

6776
/**
6877
* Lists all data-bearing keys in the entire store.
78+
*
79+
* @return A stream of key arrays containing data.
6980
*/
7081
default Stream<String[]> list() {
7182
return list(new String[]{});

src/main/java/dev/zarr/zarrjava/store/StoreHandle.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ public Stream<String[]> list() {
7373
return ((Store.ListableStore) store).list(keys);
7474
}
7575

76+
public Stream<String> listChildren() {
77+
if (!(store instanceof Store.ListableStore)) {
78+
throw new UnsupportedOperationException("The underlying store does not support listing.");
79+
}
80+
return ((Store.ListableStore) store).listChildren(keys);
81+
}
82+
7683
public long getSize() {
7784
return store.getSize(keys);
7885
}

src/test/java/dev/zarr/zarrjava/store/BufferedZipStoreTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ StoreHandle storeHandleWithData() {
3838
return new BufferedZipStore(testGroupDir).resolve("zarr.json");
3939
}
4040

41+
@Override
42+
StoreHandle storeHandleWithoutData() {
43+
return new BufferedZipStore(testGroupDir).resolve("nonexistent", "path", "zarr.json");
44+
}
45+
46+
@Override
47+
Store storeWithArrays() {
48+
return new BufferedZipStore(testGroupDir);
49+
}
50+
4151
@Test
4252
public void testOpenZipStore() throws ZarrException, IOException {
4353
BufferedZipStore zipStore = new BufferedZipStore(testGroupDir);

src/test/java/dev/zarr/zarrjava/store/FileSystemStoreTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ StoreHandle storeHandleWithData() {
1818
return new FilesystemStore(TESTDATA).resolve("l4_sample", "zarr.json");
1919
}
2020

21+
@Override
22+
StoreHandle storeHandleWithoutData() {
23+
return new FilesystemStore(TESTDATA).resolve("nonexistent_key");
24+
}
25+
26+
@Override
27+
Store storeWithArrays() {
28+
return new FilesystemStore(TESTDATA.resolve("l4_sample"));
29+
}
30+
2131
@Test
2232
public void testFileSystemStores() throws IOException, ZarrException {
2333
FilesystemStore fsStore = new FilesystemStore(TESTDATA);

src/test/java/dev/zarr/zarrjava/store/HttpStoreTest.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,28 @@
33
import dev.zarr.zarrjava.ZarrException;
44
import dev.zarr.zarrjava.core.Array;
55
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Disabled;
67
import org.junit.jupiter.api.Test;
78

89
import java.io.IOException;
910

10-
public class HttpStoreTest extends StoreTest {
11+
class HttpStoreTest extends StoreTest {
1112

1213
@Override
1314
StoreHandle storeHandleWithData() {
1415
return br00109990StoreHandle().resolve("c", "0", "0", "0");
1516
}
1617

18+
@Override
19+
StoreHandle storeHandleWithoutData() {
20+
return br00109990StoreHandle().resolve("nonexistent", "path", "to", "data");
21+
}
22+
23+
@Override
24+
Store storeWithArrays() {
25+
return br00109990StoreHandle().store;
26+
}
27+
1728
StoreHandle br00109990StoreHandle() {
1829
HttpStore httpStore = new dev.zarr.zarrjava.store.HttpStore("https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.5/idr0033A");
1930
return httpStore.resolve("BR00109990_C2.zarr", "0", "0");
@@ -26,7 +37,22 @@ public void testOpen() throws IOException, ZarrException {
2637
}
2738

2839
@Override
29-
void testList() throws ZarrException, IOException {
30-
// listing is not supported in HttpStore
40+
@Test
41+
@Disabled("List is not supported in HttpStore")
42+
public void testList() {
3143
}
44+
45+
@Override
46+
@Test
47+
@Disabled("List is not supported in HttpStore")
48+
public void testListedItemsExist() {
49+
}
50+
51+
@Override
52+
@Test
53+
@Disabled("List is not supported in HttpStore")
54+
public void testListChildren() {
55+
}
56+
57+
3258
}

0 commit comments

Comments
 (0)