vortex_btrblocks/
canonical_compressor.rs1use std::ops::Deref;
7
8use vortex_array::ArrayRef;
9use vortex_array::ExecutionCtx;
10use vortex_error::VortexResult;
11
12use crate::BtrBlocksCompressorBuilder;
13use crate::CascadingCompressor;
14
15#[derive(Clone)]
35pub struct BtrBlocksCompressor(
36 pub CascadingCompressor,
38);
39
40impl BtrBlocksCompressor {
41 pub fn compress(&self, array: &ArrayRef, ctx: &mut ExecutionCtx) -> VortexResult<ArrayRef> {
43 self.0.compress(array, ctx)
44 }
45}
46
47impl Deref for BtrBlocksCompressor {
48 type Target = CascadingCompressor;
49
50 fn deref(&self) -> &CascadingCompressor {
51 &self.0
52 }
53}
54
55impl Default for BtrBlocksCompressor {
56 fn default() -> Self {
57 BtrBlocksCompressorBuilder::default().build()
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use std::sync::LazyLock;
64
65 use rstest::rstest;
66 use vortex_array::IntoArray;
67 use vortex_array::VortexSessionExecute;
68 use vortex_array::arrays::BoolArray;
69 use vortex_array::arrays::Constant;
70 use vortex_array::arrays::List;
71 use vortex_array::arrays::ListView;
72 use vortex_array::arrays::ListViewArray;
73 use vortex_array::assert_arrays_eq;
74 use vortex_array::session::ArraySession;
75 use vortex_array::validity::Validity;
76 use vortex_buffer::BitBuffer;
77 use vortex_buffer::buffer;
78 use vortex_error::VortexResult;
79 use vortex_session::VortexSession;
80
81 use crate::BtrBlocksCompressor;
82
83 static SESSION: LazyLock<VortexSession> =
84 LazyLock::new(|| VortexSession::empty().with::<ArraySession>());
85
86 #[rstest]
87 #[case::zctl(
88 unsafe {
89 ListViewArray::new_unchecked(
90 buffer![1i32, 2, 3, 4, 5].into_array(),
91 buffer![0i32, 3].into_array(),
92 buffer![3i32, 2].into_array(),
93 Validity::NonNullable,
94 ).with_zero_copy_to_list(true)
95 },
96 true,
97 )]
98 #[case::overlapping(
99 ListViewArray::new(
100 buffer![1i32, 2, 3].into_array(),
101 buffer![0i32, 0, 0].into_array(),
102 buffer![3i32, 3, 3].into_array(),
103 Validity::NonNullable,
104 ),
105 false,
106 )]
107 fn listview_compress_roundtrip(
108 #[case] input: ListViewArray,
109 #[case] expect_list: bool,
110 ) -> VortexResult<()> {
111 let array_ref = input.clone().into_array();
112 let result = BtrBlocksCompressor::default()
113 .compress(&array_ref, &mut SESSION.create_execution_ctx())?;
114 if expect_list {
115 assert!(result.as_opt::<List>().is_some());
116 } else {
117 assert!(result.as_opt::<ListView>().is_some());
118 }
119 assert_arrays_eq!(result, input);
120 Ok(())
121 }
122
123 #[test]
124 fn test_constant_all_true() -> VortexResult<()> {
125 let array = BoolArray::new(BitBuffer::from(vec![true; 100]), Validity::NonNullable);
126 let btr = BtrBlocksCompressor::default();
127 let compressed = btr.compress(
128 &array.clone().into_array(),
129 &mut SESSION.create_execution_ctx(),
130 )?;
131 assert!(compressed.is::<Constant>());
132 assert_arrays_eq!(compressed, array);
133 Ok(())
134 }
135
136 #[test]
137 fn test_constant_all_false() -> VortexResult<()> {
138 let array = BoolArray::new(BitBuffer::from(vec![false; 100]), Validity::NonNullable);
139 let btr = BtrBlocksCompressor::default();
140 let compressed = btr.compress(
141 &array.clone().into_array(),
142 &mut SESSION.create_execution_ctx(),
143 )?;
144 assert!(compressed.is::<Constant>());
145 assert_arrays_eq!(compressed, array);
146 Ok(())
147 }
148
149 #[test]
150 fn test_nullable_all_valid_compressed() -> VortexResult<()> {
151 let array = BoolArray::new(
152 BitBuffer::from(vec![true; 100]),
153 Validity::from(BitBuffer::from(vec![true; 100])),
154 );
155 let btr = BtrBlocksCompressor::default();
156 let compressed = btr.compress(
157 &array.clone().into_array(),
158 &mut SESSION.create_execution_ctx(),
159 )?;
160 assert!(compressed.is::<Constant>());
161 assert_arrays_eq!(compressed, array);
162 Ok(())
163 }
164
165 #[test]
166 fn test_nullable_with_nulls_not_compressed() -> VortexResult<()> {
167 let validity = Validity::from(BitBuffer::from_iter((0..100).map(|i| i % 3 != 0)));
168 let array = BoolArray::new(BitBuffer::from(vec![true; 100]), validity);
169 let btr = BtrBlocksCompressor::default();
170 let compressed = btr.compress(
171 &array.clone().into_array(),
172 &mut SESSION.create_execution_ctx(),
173 )?;
174 assert!(!compressed.is::<Constant>());
175 assert_arrays_eq!(compressed, array);
176 Ok(())
177 }
178
179 #[test]
180 fn test_mixed_not_constant() -> VortexResult<()> {
181 let array = BoolArray::new(
182 BitBuffer::from(vec![true, false, true, false, true]),
183 Validity::NonNullable,
184 );
185 let btr = BtrBlocksCompressor::default();
186 let compressed = btr.compress(
187 &array.clone().into_array(),
188 &mut SESSION.create_execution_ctx(),
189 )?;
190 assert!(!compressed.is::<Constant>());
191 assert_arrays_eq!(compressed, array);
192 Ok(())
193 }
194}