vortex_runend/
serde.rs

1use serde::{Deserialize, Serialize};
2use vortex_array::serde::ArrayParts;
3use vortex_array::vtable::SerdeVTable;
4use vortex_array::{
5    Array, ArrayChildVisitor, ArrayContext, ArrayRef, ArrayVisitorImpl, DeserializeMetadata,
6    SerdeMetadata,
7};
8use vortex_dtype::{DType, Nullability, PType};
9use vortex_error::{VortexExpect, VortexResult};
10
11use crate::{RunEndArray, RunEndEncoding};
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct RunEndMetadata {
15    ends_ptype: PType,
16    num_runs: usize,
17    offset: usize,
18}
19
20impl ArrayVisitorImpl<SerdeMetadata<RunEndMetadata>> for RunEndArray {
21    fn _children(&self, visitor: &mut dyn ArrayChildVisitor) {
22        visitor.visit_child("ends", self.ends());
23        visitor.visit_child("values", self.values());
24    }
25
26    fn _metadata(&self) -> SerdeMetadata<RunEndMetadata> {
27        SerdeMetadata(RunEndMetadata {
28            ends_ptype: PType::try_from(self.ends().dtype()).vortex_expect("Must be a valid PType"),
29            num_runs: self.ends().len(),
30            offset: self.offset(),
31        })
32    }
33}
34
35impl SerdeVTable<&RunEndArray> for RunEndEncoding {
36    fn decode(
37        &self,
38        parts: &ArrayParts,
39        ctx: &ArrayContext,
40        dtype: DType,
41        len: usize,
42    ) -> VortexResult<ArrayRef> {
43        let metadata = SerdeMetadata::<RunEndMetadata>::deserialize(parts.metadata())?;
44
45        let ends_dtype = DType::Primitive(metadata.ends_ptype, Nullability::NonNullable);
46        let ends = parts.child(0).decode(ctx, ends_dtype, metadata.num_runs)?;
47
48        let values = parts.child(1).decode(ctx, dtype, metadata.num_runs)?;
49
50        Ok(RunEndArray::with_offset_and_length(ends, values, metadata.offset, len)?.into_array())
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use vortex_array::SerdeMetadata;
57    use vortex_array::test_harness::check_metadata;
58    use vortex_dtype::PType;
59
60    use super::*;
61
62    #[cfg_attr(miri, ignore)]
63    #[test]
64    fn test_runend_metadata() {
65        check_metadata(
66            "runend.metadata",
67            SerdeMetadata(RunEndMetadata {
68                offset: usize::MAX,
69                ends_ptype: PType::U64,
70                num_runs: usize::MAX,
71            }),
72        );
73    }
74}