Skip to content

Commit 7808c5b

Browse files
authored
Merge pull request #80 from konstibob/fix/sub_shard_read
Fix S3 suffix byte-range requests when reading sharded chunks
2 parents d5552e7 + 176bc40 commit 7808c5b

2 files changed

Lines changed: 40 additions & 9 deletions

File tree

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

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
package dev.zarr.zarrjava.store;
22

3-
import dev.zarr.zarrjava.utils.Utils;
4-
import software.amazon.awssdk.core.ResponseInputStream;
5-
import software.amazon.awssdk.core.sync.RequestBody;
6-
import software.amazon.awssdk.services.s3.S3Client;
7-
import software.amazon.awssdk.services.s3.model.*;
8-
9-
import javax.annotation.Nonnull;
10-
import javax.annotation.Nullable;
113
import java.io.IOException;
124
import java.io.InputStream;
135
import java.nio.ByteBuffer;
146
import java.util.stream.Stream;
157

8+
import javax.annotation.Nonnull;
9+
import javax.annotation.Nullable;
10+
11+
import dev.zarr.zarrjava.utils.Utils;
12+
import software.amazon.awssdk.core.ResponseInputStream;
13+
import software.amazon.awssdk.core.sync.RequestBody;
14+
import software.amazon.awssdk.services.s3.S3Client;
15+
import software.amazon.awssdk.services.s3.model.CommonPrefix;
16+
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
17+
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
18+
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
19+
import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
20+
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
21+
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
22+
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
23+
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
24+
import software.amazon.awssdk.services.s3.model.S3Exception;
25+
import software.amazon.awssdk.services.s3.model.S3Object;
26+
1627
public class S3Store implements Store, Store.ListableStore {
1728

1829
@Nonnull
@@ -82,7 +93,9 @@ public ByteBuffer get(String[] keys, long start) {
8293
GetObjectRequest req = GetObjectRequest.builder()
8394
.bucket(bucketName)
8495
.key(resolveKeys(keys))
85-
.range(String.format("bytes=%d-", start))
96+
.range(start < 0 // negative start implies indexing from the end, i.e. last bytes
97+
? String.format("bytes=%d", start)
98+
: String.format("bytes=%d-", start))
8699
.build();
87100
return get(req);
88101
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ public void testGet() {
6060
Assertions.assertEquals(10, bufferWithStartAndEnd.remaining());
6161
}
6262

63+
@Test
64+
public void testReadSuffix() {
65+
StoreHandle storeHandle = storeHandleWithData();
66+
ByteBuffer fullBuffer = storeHandle.read();
67+
long size = fullBuffer.remaining();
68+
Assertions.assertTrue(size >= 20, "Store size is too small to test suffix read");
69+
70+
ByteBuffer suffixBuffer = storeHandle.read(-10);
71+
Assertions.assertEquals(10, suffixBuffer.remaining());
72+
73+
byte[] expectedBytes = new byte[10];
74+
fullBuffer.position((int) (size - 10));
75+
fullBuffer.get(expectedBytes);
76+
byte[] actualBytes = new byte[10];
77+
suffixBuffer.get(actualBytes);
78+
Assertions.assertArrayEquals(expectedBytes, actualBytes);
79+
}
80+
6381
@Override
6482
StoreHandle storeHandleWithData() {
6583
return storeHandle.resolve("zarr.json");

0 commit comments

Comments
 (0)