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