Skip to content

Commit 31f9b24

Browse files
committed
simplify chunktransform by remove layers
1 parent df7be19 commit 31f9b24

2 files changed

Lines changed: 15 additions & 32 deletions

File tree

src/zarr/core/codec_pipeline.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,14 @@ def fill_value_or_default(chunk_spec: ArraySpec) -> Any:
7171

7272
@dataclass(slots=True, kw_only=True)
7373
class ChunkTransform:
74-
"""A stored chunk, modeled as a layered array.
74+
"""A synchronous codec chain bound to an ArraySpec.
7575
76-
Each layer corresponds to one ArrayArrayCodec and the ArraySpec
77-
at its input boundary. ``layers[0]`` is the outermost (user-visible)
78-
transform; after the last layer comes the ArrayBytesCodec.
76+
Provides ``encode_chunk`` and ``decode_chunk`` for pure-compute
77+
codec operations (no IO, no threading, no batching).
7978
80-
The chunk's ``shape`` and ``dtype`` reflect the representation
81-
**after** all ArrayArrayCodec layers have been applied — i.e. the
82-
spec that feeds the ArrayBytesCodec.
79+
``shape`` and ``dtype`` reflect the representation **after** all
80+
ArrayArrayCodec transforms — i.e. the spec that feeds the
81+
ArrayBytesCodec.
8382
8483
All codecs must implement ``SupportsSyncCodec``. Construction will
8584
raise ``TypeError`` if any codec does not.
@@ -88,8 +87,8 @@ class ChunkTransform:
8887
codecs: tuple[Codec, ...]
8988
array_spec: ArraySpec
9089

91-
# Each element is (ArrayArrayCodec, input_spec_for_that_codec).
92-
layers: tuple[tuple[ArrayArrayCodec, ArraySpec], ...] = field(
90+
# (ArrayArrayCodec, input_spec) pairs in pipeline order.
91+
_aa_codecs: tuple[tuple[ArrayArrayCodec, ArraySpec], ...] = field(
9392
init=False, repr=False, compare=False
9493
)
9594
_ab_codec: ArrayBytesCodec = field(init=False, repr=False, compare=False)
@@ -106,25 +105,25 @@ def __post_init__(self) -> None:
106105

107106
aa, ab, bb = codecs_from_list(list(self.codecs))
108107

109-
layers: tuple[tuple[ArrayArrayCodec, ArraySpec], ...] = ()
108+
aa_codecs: tuple[tuple[ArrayArrayCodec, ArraySpec], ...] = ()
110109
spec = self.array_spec
111110
for aa_codec in aa:
112-
layers = (*layers, (aa_codec, spec))
111+
aa_codecs = (*aa_codecs, (aa_codec, spec))
113112
spec = aa_codec.resolve_metadata(spec)
114113

115-
self.layers = layers
114+
self._aa_codecs = aa_codecs
116115
self._ab_codec = ab
117116
self._ab_spec = spec
118117
self._bb_codecs = bb
119118

120119
@property
121120
def shape(self) -> tuple[int, ...]:
122-
"""Shape after all ArrayArrayCodec layers (input to the ArrayBytesCodec)."""
121+
"""Shape after all ArrayArrayCodec transforms (input to the ArrayBytesCodec)."""
123122
return self._ab_spec.shape
124123

125124
@property
126125
def dtype(self) -> ZDType[TBaseDType, TBaseScalar]:
127-
"""Dtype after all ArrayArrayCodec layers (input to the ArrayBytesCodec)."""
126+
"""Dtype after all ArrayArrayCodec transforms (input to the ArrayBytesCodec)."""
128127
return self._ab_spec.dtype
129128

130129
def decode_chunk(
@@ -141,7 +140,7 @@ def decode_chunk(
141140

142141
ab_out: Any = self._ab_codec._decode_sync(bb_out, self._ab_spec) # type: ignore[attr-defined]
143142

144-
for aa_codec, spec in reversed(self.layers):
143+
for aa_codec, spec in reversed(self._aa_codecs):
145144
ab_out = aa_codec._decode_sync(ab_out, spec) # type: ignore[attr-defined]
146145

147146
return ab_out # type: ignore[no-any-return]
@@ -156,7 +155,7 @@ def encode_chunk(
156155
"""
157156
aa_out: Any = chunk_array
158157

159-
for aa_codec, spec in self.layers:
158+
for aa_codec, spec in self._aa_codecs:
160159
if aa_out is None:
161160
return None
162161
aa_out = aa_codec._encode_sync(aa_out, spec) # type: ignore[attr-defined]

tests/test_sync_codec_pipeline.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,6 @@ def test_encode_decode_roundtrip_bytes_only(self) -> None:
6363
decoded = chain.decode_chunk(encoded)
6464
np.testing.assert_array_equal(arr, decoded.as_numpy_array())
6565

66-
def test_layers_no_aa_codecs(self) -> None:
67-
# When there are no ArrayArrayCodecs, layers should be empty.
68-
spec = _make_array_spec((100,), np.dtype("float64"))
69-
chunk = ChunkTransform(codecs=(BytesCodec(), GzipCodec()), array_spec=spec)
70-
assert chunk.layers == ()
71-
72-
def test_layers_with_transpose(self) -> None:
73-
# With one AA codec (TransposeCodec), layers should contain exactly one
74-
# entry pairing the codec with its input ArraySpec.
75-
spec = _make_array_spec((3, 4), np.dtype("float64"))
76-
transpose = TransposeCodec(order=(1, 0))
77-
chunk = ChunkTransform(codecs=(transpose, BytesCodec(), ZstdCodec()), array_spec=spec)
78-
assert len(chunk.layers) == 1
79-
assert chunk.layers[0][0] is transpose
80-
assert chunk.layers[0][1] is spec
81-
8266
def test_shape_dtype_no_aa_codecs(self) -> None:
8367
# Without AA codecs, shape and dtype should match the input ArraySpec
8468
# (no transforms applied before the AB codec).

0 commit comments

Comments
 (0)