Skip to content

Commit f76f7d6

Browse files
Copilotbrokkoli71
andcommitted
Refactor: Extract calculateDefaultChunks to shared Utils class
Co-authored-by: brokkoli71 <44113112+brokkoli71@users.noreply.github.com>
1 parent a435117 commit f76f7d6

3 files changed

Lines changed: 38 additions & 64 deletions

File tree

src/main/java/dev/zarr/zarrjava/utils/Utils.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,38 @@ public static int[] inversePermutation(int[] origin) {
107107
}
108108
return inverse;
109109
}
110+
111+
/**
112+
* Calculate default chunk shape when not specified.
113+
* This implements JZarr's ArrayParams.build() logic, targeting chunks of approximately 512 elements.
114+
*
115+
* The algorithm divides each dimension by 512 to determine the number of ~512-sized chunks,
116+
* then calculates chunk sizes that will cover the dimension. Note that the total coverage
117+
* may slightly exceed the dimension size (e.g., for shape=1024, chunks=342 results in
118+
* 3 chunks covering 1026 elements). This is intentional and matches JZarr behavior -
119+
* Zarr handles out-of-bounds gracefully, and the goal is approximate chunk sizes rather
120+
* than perfect tiling.
121+
*
122+
* @param shape the shape of the array
123+
* @return the calculated default chunk shape
124+
*/
125+
public static int[] calculateDefaultChunks(long[] shape) {
126+
int[] chunks = new int[shape.length];
127+
for (int i = 0; i < shape.length; i++) {
128+
long shapeDim = shape[i];
129+
int numChunks = (int) (shapeDim / 512);
130+
if (numChunks > 0) {
131+
int chunkDim = (int) (shapeDim / (numChunks + 1));
132+
if (shapeDim % chunkDim == 0) {
133+
chunks[i] = chunkDim;
134+
} else {
135+
chunks[i] = chunkDim + 1;
136+
}
137+
} else {
138+
// If dimension is smaller than 512, use the full dimension
139+
chunks[i] = (int) shapeDim;
140+
}
141+
}
142+
return chunks;
143+
}
110144
}

src/main/java/dev/zarr/zarrjava/v2/ArrayMetadataBuilder.java

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import dev.zarr.zarrjava.ZarrException;
55
import dev.zarr.zarrjava.core.Attributes;
66
import dev.zarr.zarrjava.core.chunkkeyencoding.Separator;
7+
import dev.zarr.zarrjava.utils.Utils;
78
import dev.zarr.zarrjava.v2.codec.Codec;
89
import dev.zarr.zarrjava.v2.codec.core.BloscCodec;
910
import dev.zarr.zarrjava.v2.codec.core.ZlibCodec;
@@ -152,7 +153,7 @@ public ArrayMetadata build() throws ZarrException {
152153

153154
// If chunks are not specified, calculate default chunks
154155
if (chunks == null) {
155-
chunks = calculateDefaultChunks(shape);
156+
chunks = Utils.calculateDefaultChunks(shape);
156157
}
157158

158159
return new ArrayMetadata(
@@ -168,35 +169,4 @@ public ArrayMetadata build() throws ZarrException {
168169
attributes
169170
);
170171
}
171-
172-
/**
173-
* Calculate default chunk shape when not specified.
174-
* This implements JZarr's ArrayParams.build() logic, targeting chunks of approximately 512 elements.
175-
*
176-
* The algorithm divides each dimension by 512 to determine the number of ~512-sized chunks,
177-
* then calculates chunk sizes that will cover the dimension. Note that the total coverage
178-
* may slightly exceed the dimension size (e.g., for shape=1024, chunks=342 results in
179-
* 3 chunks covering 1026 elements). This is intentional and matches JZarr behavior -
180-
* Zarr handles out-of-bounds gracefully, and the goal is approximate chunk sizes rather
181-
* than perfect tiling.
182-
*/
183-
private int[] calculateDefaultChunks(long[] shape) {
184-
int[] chunks = new int[shape.length];
185-
for (int i = 0; i < shape.length; i++) {
186-
long shapeDim = shape[i];
187-
int numChunks = (int) (shapeDim / 512);
188-
if (numChunks > 0) {
189-
int chunkDim = (int) (shapeDim / (numChunks + 1));
190-
if (shapeDim % chunkDim == 0) {
191-
chunks[i] = chunkDim;
192-
} else {
193-
chunks[i] = chunkDim + 1;
194-
}
195-
} else {
196-
// If dimension is smaller than 512, use the full dimension
197-
chunks[i] = (int) shapeDim;
198-
}
199-
}
200-
return chunks;
201-
}
202172
}

src/main/java/dev/zarr/zarrjava/v3/ArrayMetadataBuilder.java

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import dev.zarr.zarrjava.core.Attributes;
55
import dev.zarr.zarrjava.core.chunkkeyencoding.Separator;
66
import dev.zarr.zarrjava.core.codec.core.BytesCodec.Endian;
7+
import dev.zarr.zarrjava.utils.Utils;
78
import dev.zarr.zarrjava.v3.chunkgrid.ChunkGrid;
89
import dev.zarr.zarrjava.v3.chunkgrid.RegularChunkGrid;
910
import dev.zarr.zarrjava.v3.chunkkeyencoding.ChunkKeyEncoding;
@@ -164,7 +165,7 @@ public ArrayMetadata build() throws ZarrException {
164165

165166
// If chunk grid is not specified, calculate default chunks
166167
if (chunkGrid == null) {
167-
int[] defaultChunks = calculateDefaultChunks(shape);
168+
int[] defaultChunks = Utils.calculateDefaultChunks(shape);
168169
chunkGrid = new RegularChunkGrid(new RegularChunkGrid.Configuration(defaultChunks));
169170
}
170171

@@ -174,35 +175,4 @@ public ArrayMetadata build() throws ZarrException {
174175
storageTransformers
175176
);
176177
}
177-
178-
/**
179-
* Calculate default chunk shape when not specified.
180-
* This implements JZarr's ArrayParams.build() logic, targeting chunks of approximately 512 elements.
181-
*
182-
* The algorithm divides each dimension by 512 to determine the number of ~512-sized chunks,
183-
* then calculates chunk sizes that will cover the dimension. Note that the total coverage
184-
* may slightly exceed the dimension size (e.g., for shape=1024, chunks=342 results in
185-
* 3 chunks covering 1026 elements). This is intentional and matches JZarr behavior -
186-
* Zarr handles out-of-bounds gracefully, and the goal is approximate chunk sizes rather
187-
* than perfect tiling.
188-
*/
189-
private int[] calculateDefaultChunks(long[] shape) {
190-
int[] chunks = new int[shape.length];
191-
for (int i = 0; i < shape.length; i++) {
192-
long shapeDim = shape[i];
193-
int numChunks = (int) (shapeDim / 512);
194-
if (numChunks > 0) {
195-
int chunkDim = (int) (shapeDim / (numChunks + 1));
196-
if (shapeDim % chunkDim == 0) {
197-
chunks[i] = chunkDim;
198-
} else {
199-
chunks[i] = chunkDim + 1;
200-
}
201-
} else {
202-
// If dimension is smaller than 512, use the full dimension
203-
chunks[i] = (int) shapeDim;
204-
}
205-
}
206-
return chunks;
207-
}
208178
}

0 commit comments

Comments
 (0)