Repository navigation
Add Array.prepend and the regular_bounded chunk grid - #4516
Draft
rhoadesScholar wants to merge 7 commits into
Draft
rhoadesScholar wants to merge 7 commits into
rhoadesScholar wants to merge 7 commits into
Conversation
The `offset` encoding stores each chunk under the `default` key of its grid coordinate plus a fixed per-dimension integer offset, so that an array grows in the negative direction of an axis by whole chunks as a metadata-only change: `shape` grows, `offset` drops, and every existing chunk keeps its key. `Array.prepend_chunks` performs that edit and `Array.prepend` grows and writes in one call; both refuse an array on another encoding rather than rename its chunks. The offset must have one entry per dimension, checked when the metadata is built; the `ChunkKeyEncodingParams` shortcut carries `offset` through to the configuration instead of dropping it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSaEKF9nB55gU7PQgQ22X5
The store key addresses a shard, so the unit of growth is the chunk grid's shape, not the inner chunk; and a negative axis has to be normalised before the preserved-shape check and the write selection use it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSaEKF9nB55gU7PQgQ22X5
Drops the public prepend_chunks; Array.prepend grows the array by the data's extent (whole chunks, or shards when sharded) and writes it. Docstrings and the docs paragraph are cut to what the API needs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSaEKF9nB55gU7PQgQ22X5
This was referenced Oct 15, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSaEKF9nB55gU7PQgQ22X5
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4516 +/- ##
==========================================
+ Coverage 94.71% 94.72% +0.01%
==========================================
Files 94 94
Lines 13663 13767 +104
==========================================
+ Hits 12941 13041 +100
- Misses 722 726 +4
🚀 New features to boost your workflow:
|
rhoadesScholar
marked this pull request as ready for review
October 16, 2026 00:13
Author
|
Ready for review; the registry entry is zarr-developers/zarr-extensions#80. cc @d-v-b |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSaEKF9nB55gU7PQgQ22X5
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSaEKF9nB55gU7PQgQ22X5
Contributor
|
thanks for this PR! I really want to see this feature added to |
rhoadesScholar
marked this pull request as draft
October 16, 2026 19:48
Author
|
Converting to draft while the design is worked out in zarr-developers/zarr-extensions#79. This branch is a prototype and will be reworked to match. |
… encoding Rework following zarr-extensions#79: the `offset` chunk key encoding is removed. `regular_bounded` is a regular chunk grid with an `origin` (the array coordinate where chunk 0 starts) and a `lower_bound` (the coordinate of the first element), so chunk grid indices can be negative and the first chunk can be partly filled, mirroring the last chunk. `Array.prepend` no longer needs whole chunks or an opt-in at creation: the first prepend switches a `regular` grid to `regular_bounded`, and existing chunks keep their keys and bytes. `Array.domain` reports each dimension's coordinate range; indexing stays zero-based. Internally a regular dimension gains a `shift` (where the first element sits in the first chunk), and `buffer_offset` gives where a chunk's data starts inside its buffer, which the indexers add when converting to chunk-local positions. Key decoding rejects `-0` components. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSaEKF9nB55gU7PQgQ22X5
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prototype for zarr-developers/zarr-extensions#79, using the
regular_boundedchunk grid proposed in zarr-developers/zarr-extensions#81.Array.prepend(data, axis)adds data before index 0 of an axis, the wayappendadds it after the end. It grows by any number of elements and never touches an existing chunk:The first prepend switches the chunk grid from
regulartoregular_bounded, a regular grid with anoriginand alower_bound, so readers without that grid refuse the array rather than misread it. Indexing stays zero-based: indexiis coordinatelower_bound + i, andArray.domainreports the coordinate range.To try it:
pip install "zarr @ git+https://github.com/zarr-developers/zarr-python@refs/pull/4516/head"What growing in front costs. Two chunk rows in front of an array of 64³ uint8 chunks, one machine (NVMe), wall seconds:
prepend's metadata stepScript: https://github.com/rhoadesScholar/zarr-chunk-offset/tree/main/bench
How it works
RegularBoundedChunkGridMetadatasubclassesRegularChunkGridMetadata, so code that checks for a regular grid keeps working.shift, the position of the first element inside the first chunk. A newbuffer_offset(chunk)gives where a chunk's data starts inside its buffer, which is 0 except for a partly filled first chunk. The indexers add it at the six places they convert array positions to chunk-local ones. A partly filled first chunk is then handled like a partly filled last chunk, write path included.-0.Tests. 22 new cases. Every selection type is read and written against NumPy on an array whose first chunk is partly filled, and removing the buffer offset at any one of the six indexer sites fails a test. Also covered: prepending by part of a chunk, whole chunks and part of a shard; repeated prepends followed by
resize; reopening; and the grid's validation. The full suite passes (12,618 tests), and mypy and ruff are clean.Not covered here: rectilinear grids, Zarr v2 arrays, and switching an array to
regular_boundedwithout prepending.Refs zarr-developers/zarr-specs#9, zarr-developers/zarr-extensions#30.