vortex_array/vtable/
validity.rs1use vortex_error::VortexExpect;
5use vortex_error::VortexResult;
6use vortex_error::vortex_panic;
7use vortex_mask::Mask;
8
9use crate::Array;
10use crate::ArrayRef;
11use crate::validity::Validity;
12use crate::vtable::NotSupported;
13use crate::vtable::VTable;
14
15pub trait ValidityVTable<V: VTable> {
16 fn is_valid(array: &V::Array, index: usize) -> bool;
17
18 fn all_valid(array: &V::Array) -> bool;
19
20 fn all_invalid(array: &V::Array) -> bool;
21
22 fn valid_count(array: &V::Array) -> usize {
27 Self::validity_mask(array).true_count()
28 }
29
30 fn invalid_count(array: &V::Array) -> usize {
35 Self::validity_mask(array).false_count()
36 }
37
38 fn validity(array: &V::Array) -> VortexResult<Validity>;
44
45 fn validity_mask(array: &V::Array) -> Mask {
46 Self::validity(array)
47 .vortex_expect("TODO: make this fallible")
48 .to_mask(array.len())
49 }
50}
51
52impl<V: VTable> ValidityVTable<V> for NotSupported {
53 fn is_valid(array: &V::Array, _index: usize) -> bool {
54 vortex_panic!(
55 "Legacy is_valid is not supported for {} arrays",
56 array.encoding_id()
57 )
58 }
59
60 fn all_valid(array: &V::Array) -> bool {
61 vortex_panic!(
62 "Legacy all_valid is not supported for {} arrays",
63 array.encoding_id()
64 )
65 }
66
67 fn all_invalid(array: &V::Array) -> bool {
68 vortex_panic!(
69 "Legacy all_invalid is not supported for {} arrays",
70 array.encoding_id()
71 )
72 }
73
74 fn validity(array: &V::Array) -> VortexResult<Validity> {
75 vortex_panic!(
76 "Legacy validity is not supported for {} arrays",
77 array.encoding_id()
78 )
79 }
80}
81
82pub struct ValidityVTableFromValidityHelper;
84
85pub trait ValidityHelper {
87 fn validity(&self) -> &Validity;
88}
89
90impl<V: VTable> ValidityVTable<V> for ValidityVTableFromValidityHelper
91where
92 V::Array: ValidityHelper,
93{
94 fn is_valid(array: &V::Array, index: usize) -> bool {
95 array.validity().is_valid(index)
96 }
97
98 fn all_valid(array: &V::Array) -> bool {
99 array.validity().all_valid(array.len())
100 }
101
102 fn all_invalid(array: &V::Array) -> bool {
103 array.validity().all_invalid(array.len())
104 }
105
106 fn validity(array: &V::Array) -> VortexResult<Validity> {
107 Ok(array.validity().clone())
108 }
109}
110
111pub struct ValidityVTableFromValiditySliceHelper;
114
115pub trait ValiditySliceHelper {
116 fn unsliced_validity_and_slice(&self) -> (&Validity, usize, usize);
117
118 fn sliced_validity(&self) -> Validity {
119 let (unsliced_validity, start, stop) = self.unsliced_validity_and_slice();
120 unsliced_validity.slice(start..stop)
121 }
122}
123
124impl<V: VTable> ValidityVTable<V> for ValidityVTableFromValiditySliceHelper
125where
126 V::Array: ValiditySliceHelper,
127{
128 fn is_valid(array: &V::Array, index: usize) -> bool {
129 let (unsliced_validity, start, _) = array.unsliced_validity_and_slice();
130 unsliced_validity.is_valid(start + index)
131 }
132
133 fn all_valid(array: &V::Array) -> bool {
134 array.sliced_validity().all_valid(array.len())
135 }
136
137 fn all_invalid(array: &V::Array) -> bool {
138 array.sliced_validity().all_invalid(array.len())
139 }
140
141 fn validity(array: &V::Array) -> VortexResult<Validity> {
142 Ok(array.sliced_validity())
143 }
144}
145
146pub struct ValidityVTableFromChild;
149
150pub trait ValidityChild<V: VTable> {
151 fn validity_child(array: &V::Array) -> &ArrayRef;
152}
153
154impl<V: VTable> ValidityVTable<V> for ValidityVTableFromChild
155where
156 V: ValidityChild<V>,
157{
158 fn is_valid(array: &V::Array, index: usize) -> bool {
159 V::validity_child(array).is_valid(index)
160 }
161
162 fn all_valid(array: &V::Array) -> bool {
163 V::validity_child(array).all_valid()
164 }
165
166 fn all_invalid(array: &V::Array) -> bool {
167 V::validity_child(array).all_invalid()
168 }
169
170 fn validity(array: &V::Array) -> VortexResult<Validity> {
171 Ok(Validity::Array(V::validity_child(array).to_array()))
172 }
173
174 fn validity_mask(array: &V::Array) -> Mask {
175 V::validity_child(array).validity_mask()
176 }
177}
178
179pub struct ValidityVTableFromChildSliceHelper;
182
183pub trait ValidityChildSliceHelper {
184 fn unsliced_child_and_slice(&self) -> (&ArrayRef, usize, usize);
185
186 fn sliced_child_array(&self) -> ArrayRef {
187 let (unsliced_validity, start, stop) = self.unsliced_child_and_slice();
188 unsliced_validity.slice(start..stop)
189 }
190}
191
192impl<V: VTable> ValidityVTable<V> for ValidityVTableFromChildSliceHelper
193where
194 V::Array: ValidityChildSliceHelper,
195{
196 fn is_valid(array: &V::Array, index: usize) -> bool {
197 let (unsliced_validity, start, _) = array.unsliced_child_and_slice();
198 unsliced_validity.is_valid(start + index)
199 }
200
201 fn all_valid(array: &V::Array) -> bool {
202 array.sliced_child_array().all_valid()
203 }
204
205 fn all_invalid(array: &V::Array) -> bool {
206 array.sliced_child_array().all_invalid()
207 }
208
209 fn validity(array: &V::Array) -> VortexResult<Validity> {
210 array.sliced_child_array().validity()
211 }
212}