Skip to content

Commit 8f508b0

Browse files
authored
fix: support for Zarr V2 zstd encoded data created with numcodecs < 0.13 (#121)
1 parent 15187a0 commit 8f508b0

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Add `ArrayShardedExt::is_exclusively_sharded`
1414
- Add `ArrayShardedReadableExtCache::array_is_exclusively_sharded`
1515
- Add `Vlen{Array,Bytes,Utf8}Codec`, replacing `VlenV2Codec`
16+
- Add `ZstdCodecConfigurationNumCodecs`
17+
- Adds support for Zarr V2 `zstd` encoded data created with `numcodecs` < 0.13
1618

1719
### Changed
1820
- **Breaking**: Seal `Array` extension traits: `ArraySharded[Readable]Ext` and `ArrayChunkCacheExt`

zarrs/tests/data/v3/array_zstd.zarr/zarr.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
{
3333
"name": "zstd",
3434
"configuration": {
35-
"checksum": false,
36-
"level": 5
35+
"level": 5,
36+
"checksum": false
3737
}
3838
}
3939
],
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,40 @@
1+
use derive_more::derive::{Display, From};
2+
use serde::{Deserialize, Serialize};
3+
14
pub use crate::v3::array::codec::zstd::ZstdCodecConfigurationV1;
5+
6+
use crate::v3::array::codec::zstd::{ZstdCodecConfiguration, ZstdCompressionLevel};
7+
8+
type ZstdCodecConfigurationNumCodecs0_13 = ZstdCodecConfigurationV1;
9+
10+
/// A wrapper to handle various versions of `zstd` codec configuration parameters.
11+
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display, From)]
12+
#[serde(untagged)]
13+
pub enum ZstdCodecConfigurationNumCodecs {
14+
/// `numcodecs` version 0.13.
15+
V0_13(ZstdCodecConfigurationNumCodecs0_13),
16+
/// `numcodecs` version 0.1.
17+
V0_1(ZstdCodecConfigurationNumCodecs0_1),
18+
}
19+
20+
/// Configuration parameters for the `zstd` codec (`numcodecs` version 0.1).
21+
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display)]
22+
#[serde(deny_unknown_fields)]
23+
#[display("{}", serde_json::to_string(self).unwrap_or_default())]
24+
pub struct ZstdCodecConfigurationNumCodecs0_1 {
25+
/// The compression level.
26+
pub level: ZstdCompressionLevel,
27+
}
28+
29+
/// Convert [`ZstdCodecConfigurationNumCodecs`] to [`ZstdCodecConfiguration`].
30+
#[must_use]
31+
pub fn codec_zstd_v2_numcodecs_to_v3(
32+
zstd: &ZstdCodecConfigurationNumCodecs,
33+
) -> ZstdCodecConfiguration {
34+
match zstd {
35+
ZstdCodecConfigurationNumCodecs::V0_13(zstd) => ZstdCodecConfiguration::V1(zstd.clone()),
36+
ZstdCodecConfigurationNumCodecs::V0_1(zstd) => {
37+
ZstdCodecConfiguration::V1(ZstdCodecConfigurationV1::new(zstd.level.clone(), false))
38+
}
39+
}
40+
}

zarrs_metadata/src/v2_to_v3.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
codec::{
77
blosc::{codec_blosc_v2_numcodecs_to_v3, BloscCodecConfigurationNumcodecs},
88
zfpy::{codec_zfpy_v2_numcodecs_to_v3, ZfpyCodecConfigurationNumcodecs},
9+
zstd::{codec_zstd_v2_numcodecs_to_v3, ZstdCodecConfigurationNumCodecs},
910
},
1011
data_type_metadata_v2_to_endianness, ArrayMetadataV2Order, DataTypeMetadataV2,
1112
DataTypeMetadataV2InvalidEndiannessError, FillValueMetadataV2,
@@ -214,6 +215,16 @@ pub fn array_metadata_v2_to_v3(
214215
&configuration,
215216
)?);
216217
}
218+
crate::v3::array::codec::zstd::IDENTIFIER => {
219+
let zstd = serde_json::from_value::<ZstdCodecConfigurationNumCodecs>(
220+
serde_json::to_value(compressor.configuration())?,
221+
)?;
222+
let configuration = codec_zstd_v2_numcodecs_to_v3(&zstd);
223+
codecs.push(MetadataV3::new_with_serializable_configuration(
224+
crate::v3::array::codec::zstd::IDENTIFIER,
225+
&configuration,
226+
)?);
227+
}
217228
_ => codecs.push(MetadataV3::new_with_configuration(
218229
compressor.id(),
219230
compressor.configuration().clone(),

0 commit comments

Comments
 (0)