Skip to main content

vortex_zigzag/
compress.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_array::arrays::PrimitiveArray;
5use vortex_array::dtype::NativePType;
6use vortex_array::dtype::PType;
7use vortex_array::validity::Validity;
8use vortex_array::vtable::ValidityHelper;
9use vortex_buffer::BufferMut;
10use vortex_error::VortexResult;
11use vortex_error::vortex_bail;
12use vortex_error::vortex_panic;
13use zigzag::ZigZag as ExternalZigZag;
14
15use crate::ZigZagArray;
16
17pub fn zigzag_encode(parray: PrimitiveArray) -> VortexResult<ZigZagArray> {
18    let validity = parray.validity().clone();
19    let encoded = match parray.ptype() {
20        PType::I8 => zigzag_encode_primitive::<i8>(parray.into_buffer_mut(), validity),
21        PType::I16 => zigzag_encode_primitive::<i16>(parray.into_buffer_mut(), validity),
22        PType::I32 => zigzag_encode_primitive::<i32>(parray.into_buffer_mut(), validity),
23        PType::I64 => zigzag_encode_primitive::<i64>(parray.into_buffer_mut(), validity),
24        _ => vortex_bail!(
25            "ZigZag can only encode signed integers, got {}",
26            parray.ptype()
27        ),
28    };
29    ZigZagArray::try_new(encoded.to_array())
30}
31
32fn zigzag_encode_primitive<T: ExternalZigZag + NativePType>(
33    values: BufferMut<T>,
34    validity: Validity,
35) -> PrimitiveArray
36where
37    <T as ExternalZigZag>::UInt: NativePType,
38{
39    PrimitiveArray::new(
40        values.map_each_in_place(|v| T::encode(v)).freeze(),
41        validity,
42    )
43}
44
45pub fn zigzag_decode(parray: PrimitiveArray) -> PrimitiveArray {
46    let validity = parray.validity().clone();
47    match parray.ptype() {
48        PType::U8 => zigzag_decode_primitive::<i8>(parray.into_buffer_mut(), validity),
49        PType::U16 => zigzag_decode_primitive::<i16>(parray.into_buffer_mut(), validity),
50        PType::U32 => zigzag_decode_primitive::<i32>(parray.into_buffer_mut(), validity),
51        PType::U64 => zigzag_decode_primitive::<i64>(parray.into_buffer_mut(), validity),
52        _ => vortex_panic!(
53            "ZigZag can only decode unsigned integers, got {}",
54            parray.ptype()
55        ),
56    }
57}
58
59fn zigzag_decode_primitive<T: ExternalZigZag + NativePType>(
60    values: BufferMut<T::UInt>,
61    validity: Validity,
62) -> PrimitiveArray
63where
64    <T as ExternalZigZag>::UInt: NativePType,
65{
66    PrimitiveArray::new(
67        values.map_each_in_place(|v| T::decode(v)).freeze(),
68        validity,
69    )
70}
71
72#[cfg(test)]
73mod test {
74    use vortex_array::ToCanonical;
75    use vortex_array::assert_arrays_eq;
76
77    use super::*;
78    use crate::ZigZagVTable;
79
80    #[test]
81    fn test_compress_i8() {
82        let compressed = zigzag_encode(PrimitiveArray::from_iter(-100_i8..100)).unwrap();
83        assert!(compressed.is::<ZigZagVTable>());
84        assert_arrays_eq!(
85            compressed.to_primitive(),
86            PrimitiveArray::from_iter(-100_i8..100)
87        );
88    }
89    #[test]
90    fn test_compress_i16() {
91        let compressed = zigzag_encode(PrimitiveArray::from_iter(-100_i16..100)).unwrap();
92        assert!(compressed.is::<ZigZagVTable>());
93        assert_arrays_eq!(
94            compressed.to_primitive(),
95            PrimitiveArray::from_iter(-100_i16..100)
96        );
97    }
98    #[test]
99    fn test_compress_i32() {
100        let compressed = zigzag_encode(PrimitiveArray::from_iter(-100_i32..100)).unwrap();
101        assert!(compressed.is::<ZigZagVTable>());
102        assert_arrays_eq!(
103            compressed.to_primitive(),
104            PrimitiveArray::from_iter(-100_i32..100)
105        );
106    }
107    #[test]
108    fn test_compress_i64() {
109        let compressed = zigzag_encode(PrimitiveArray::from_iter(-100_i64..100)).unwrap();
110        assert!(compressed.is::<ZigZagVTable>());
111        assert_arrays_eq!(
112            compressed.to_primitive(),
113            PrimitiveArray::from_iter(-100_i64..100)
114        );
115    }
116}