1pub use array::*;
25use vortex_array::dtype::proto::dtype as pb;
26use vortex_array::session::ArraySessionExt;
27use vortex_edition::EditionSessionExt;
28use vortex_error::VortexExpect;
29use vortex_error::VortexResult;
30use vortex_error::vortex_ensure;
31use vortex_error::vortex_err;
32use vortex_session::VortexSession;
33pub use zstd_buffers::*;
34
35mod array;
36mod compute;
37pub mod editions;
38mod rules;
39mod slice;
40mod zstd_buffers;
41
42#[cfg(test)]
43mod test;
44
45pub fn initialize(session: &VortexSession) {
47 session.arrays().register(Zstd);
48 session.arrays().register(ZstdBuffers);
49 if session.editions().find(&editions::ZSTD_2026_02).is_none() {
50 session
51 .editions()
52 .declare_family(&editions::FAMILY)
53 .map_err(|error| vortex_err!("{error}"))
54 .vortex_expect("Zstd edition family is valid");
55 session
56 .register_edition(&editions::DECLARATION)
57 .map_err(|error| vortex_err!("{error}"))
58 .vortex_expect("Zstd edition declaration is valid");
59 }
60}
61
62pub(crate) fn validate_frame_content_size(
64 frame: &[u8],
65 metadata_size: u64,
66 index: usize,
67) -> VortexResult<()> {
68 let frame_content_size = zstd::zstd_safe::get_frame_content_size(frame)
69 .map_err(|error| vortex_err!("Invalid zstd frame {index}: {error}"))?
70 .ok_or_else(|| vortex_err!("Zstd frame {index} does not declare a content size"))?;
71 vortex_ensure!(
72 metadata_size == frame_content_size,
73 "Zstd frame {index} metadata declares {metadata_size} uncompressed bytes, but its header declares {frame_content_size}"
74 );
75 Ok(())
76}
77
78#[derive(Clone, prost::Message)]
79pub struct ZstdFrameMetadata {
81 #[prost(uint64, tag = "1")]
83 pub uncompressed_size: u64,
84 #[prost(uint64, tag = "2")]
86 pub n_values: u64,
87}
88
89#[derive(Clone, prost::Message)]
90pub struct ZstdMetadata {
92 #[prost(uint32, tag = "1")]
95 pub dictionary_size: u32,
96 #[prost(message, repeated, tag = "2")]
98 pub frames: Vec<ZstdFrameMetadata>,
99}
100
101#[derive(Clone, prost::Message)]
102pub struct ZstdBuffersMetadata {
104 #[prost(string, tag = "1")]
106 pub inner_encoding_id: String,
107 #[prost(bytes = "vec", tag = "2")]
109 pub inner_metadata: Vec<u8>,
110 #[prost(uint64, repeated, tag = "3")]
112 pub uncompressed_sizes: Vec<u64>,
113 #[prost(uint32, repeated, tag = "4")]
115 pub buffer_alignments: Vec<u32>,
116 #[prost(message, repeated, tag = "5")]
120 pub child_dtypes: Vec<pb::DType>,
121 #[prost(uint64, repeated, tag = "6")]
123 pub child_lens: Vec<u64>,
124}