You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -140,25 +141,33 @@ Sharding can be configured per array in the :ref:`array-metadata` as follows::
140
141
``codecs``
141
142
142
143
Specifies a list of codecs to be used for encoding and decoding inner chunks.
143
-
The value must be an array of objects, as specified in the
144
+
The value must be an array of objects, as specified in the
144
145
:ref:`array-metadata`. The ``codecs`` member is required and needs to contain
145
146
exactly one ``array -> bytes`` codec.
146
147
147
148
``index_codecs``
148
149
149
-
Specifies a list of codecs to be used for encoding and decoding shard index.
150
-
The value must be an array of objects, as specified in the
150
+
Specifies a list of codecs to be used for encoding and decoding a shard index.
151
+
The shard index is an array with a ``shape`` of ``[N,2]`` and a ``data_type`` of
152
+
``uint64`` where ``N`` is the number of chunks to be indexed in the shard.
153
+
The ``index_codecs`` value must be an array of objects, as specified in the
151
154
:ref:`array-metadata`. The ``index_codecs`` member is required and needs to
152
-
contain exactly one ``array -> bytes`` codec. Codecs that produce
153
-
variable-sized encoded representation, such as compression codecs, MUST NOT
154
-
be used for index codecs. It is RECOMMENDED to use a little-endian codec
155
-
followed by a crc32c checksum as index codecs.
155
+
contain exactly one ``array -> bytes`` codec. That codec MAY be preceded by
156
+
``array -> array`` codecs that modify either the ``shape`` or ``data_type``
157
+
of the array. Codecs that produce variable-sized encoded representation,
158
+
such as compression codecs, MUST NOT be used for index codecs. It is
159
+
RECOMMENDED to use a little-endian codec followed by a crc32c checksum as
160
+
index codecs.
156
161
157
162
``index_location``
158
163
159
-
Specifies whether the shard index is located at the beginning or end of the
160
-
file. The parameter value must be either the string ``start`` or ``end``.
161
-
If the parameter is not present, the value defaults to ``end``.
164
+
Specifies whether the shard index is located at the beginning of the file,
165
+
the end of the file, or external to the file in its own key. The parameter
166
+
value must be either the string ``start``, ``end``, or ``external``. A value
167
+
of external indicates the shard index has been written to an external file
168
+
referred to by a key constructed by appending ".shard_index" to the key of
169
+
the sharded chunk. If the parameter is not present, the value defaults to
170
+
``end``.
162
171
163
172
Definitions
164
173
===========
@@ -180,8 +189,8 @@ Binary shard format
180
189
This is an ``array -> bytes`` codec.
181
190
182
191
In the ``sharding_indexed`` binary format, inner chunks are written successively in a
183
-
shard, where unused space between them is allowed, followed by an index
184
-
referencing them.
192
+
shard, where unused space between them is allowed. An index referencing them may
193
+
precede, follow, or exist external to the shard.
185
194
186
195
The index is an array with 64-bit unsigned integers with a shape that matches the
187
196
chunks per shard tuple with an appended dimension of size 2.
@@ -199,11 +208,11 @@ Empty inner chunks are interpreted as being filled with the fill value. The inde
199
208
always has the full shape of all possible inner chunks per shard, even if they extend
200
209
beyond the array shape.
201
210
202
-
The index is either placed at the end of the file or at the beginning of the file,
203
-
as configured by the ``index_location`` parameter. The index is encoded into binary
204
-
representations using the specified index codecs. The byte size of the index is
205
-
determined by the number of inner chunks in the shard ``n``, i.e. the product of
206
-
chunks per shard, and the choice of index codecs.
211
+
The index is either placed at the end of the file or, at the beginning of the file,
212
+
or under its own key, as configured by the ``index_location`` parameter. The index
213
+
is encoded into binary representations using the specified index codecs. The byte
214
+
size of the index is determined by the number of inner chunks in the shard ``n``,
215
+
i.e. the product of chunks per shard, and the choice of index codecs.
207
216
208
217
For an example, consider a shard shape of ``[64, 64]``, an inner chunk shape of
209
218
``[32, 32]`` and an index codec combination of a little-endian codec followed by
@@ -250,12 +259,12 @@ common optimizations.
250
259
* **Decoding**: A simple implementation to decode inner chunks in a shard would (a)
251
260
read the entire value from the store into a byte buffer, (b) parse the shard
252
261
index as specified above from the beginning or end (according to the
253
-
``index_location``) of the buffer and (c) cut out the relevant bytes that belong
254
-
to the requested chunk. The relevant bytes are determined by the
255
-
``offset,nbytes`` pair in the shard index. This bytestream then needs to be
256
-
decoded with the inner codecs as specified in the sharding configuration applying
257
-
the :ref:`decoding_procedure`. This is similar to how an implementation would
258
-
access a sub-slice of a chunk.
262
+
``index_location``) of the buffer or from an external index and (c) cut out
263
+
the relevant bytes that belong to the requested chunk. The relevant bytes are
264
+
determined by the ``offset,nbytes`` pair in the shard index. This bytestream
265
+
then needs to be decoded with the inner codecs as specified in the sharding
266
+
configuration applying the :ref:`decoding_procedure`. This is similar to how
267
+
an implementation would access a sub-slice of a chunk.
259
268
260
269
The size of the index can be determined by applying ``c.compute_encoded_size``
261
270
for each index codec recursively. The initial size is the byte size of the index
@@ -277,24 +286,35 @@ common optimizations.
277
286
encode the new chunk per :ref:`encoding_procedure` in a byte buffer using the
278
287
shard's inner codecs, (b) read an existing shard from the store, (c) create a
279
288
new bytestream with all encoded inner chunks of that shard including the overwritten
280
-
chunk, (d) generate a new shard index that is prepended or appended (according
281
-
to the ``index_location``) to the chunk bytestream and (e) writes the shard to
282
-
the store. If there was no existing shard, an empty shard is assumed. When
283
-
writing entire inner chunks, reading the existing shard first may be skipped.
289
+
chunk, (d) generate a new shard index that is prepended, appended, or
290
+
externally written (according to the ``index_location``) to the chunk
291
+
bytestream and (e) writes the shard to the store. If there was no existing
292
+
shard, an empty shard is assumed. When writing entire inner chunks, reading
293
+
the existing shard first may be skipped.
284
294
285
295
When working with inner chunks that have a fixed byte size (e.g., uncompressed) and
286
296
a store that supports partial writes, a optimization would be to replace the
287
297
new chunk by writing to the store at the specified byte range.
288
298
289
299
On stores with random-write capabilities, it may be useful to (a) place the shard
290
-
index at the beginning of the file, (b) write out inner chunks in
291
-
application-specific order, and (c) update the shard index accordingly.
300
+
index at the beginning of the file or in a separate file, (b) write out inner
301
+
chunks in application-specific order, and (c) update the shard index accordingly.
292
302
Synchronization of parallelly written inner chunks needs to be handled by the
293
303
application.
294
304
295
305
Other use case-specific optimizations may be available, e.g., for append-only
296
306
workloads.
297
307
308
+
* **Nesting**: The ``sharding_indexed`` codec can be used as part of a codec
309
+
chain of another ``sharding_indexed`` codec. This means that an inner chunk
310
+
MAY itself be a shard nested within an outer chunk, creating a hierarchical
311
+
index and multiple levels of partitioning. While the number of nested levels
312
+
of shards is not restricted, some implementations MAY support a limited
313
+
number of nested shards or MAY NOT support nesting. Primary shards that
314
+
are not contained within other shards MAY have an ``index_location`` value of
315
+
``start``, ``end``, or ``external``. Nested shards MAY have an
316
+
``index_location`` value of ``start`` or ``end``. Nested shards MUST NOT have
317
+
an ``index_location`` value of ``external``.
298
318
299
319
References
300
320
==========
@@ -306,6 +326,8 @@ References
306
326
Change log
307
327
==========
308
328
329
+
* Add ``external`` as a parameter value for ``index_location`` to Version 1.1 and clarified nesting. `PR ABC <https://github.com/zarr-developers/zarr-specs/pull/ABC>`_
0 commit comments