vortex_array/vtable/
validity.rs

1use vortex_error::VortexResult;
2use vortex_mask::Mask;
3
4use crate::Array;
5use crate::validity::Validity;
6use crate::vtable::VTable;
7
8pub trait ValidityVTable<V: VTable> {
9    fn is_valid(array: &V::Array, index: usize) -> VortexResult<bool>;
10
11    fn all_valid(array: &V::Array) -> VortexResult<bool>;
12
13    fn all_invalid(array: &V::Array) -> VortexResult<bool>;
14
15    /// Returns the number of valid elements in the array.
16    ///
17    /// ## Post-conditions
18    /// - The count is less than or equal to the length of the array.
19    fn valid_count(array: &V::Array) -> VortexResult<usize> {
20        Ok(Self::validity_mask(array)?.true_count())
21    }
22
23    /// Returns the number of invalid elements in the array.
24    ///
25    /// ## Post-conditions
26    /// - The count is less than or equal to the length of the array.
27    fn invalid_count(array: &V::Array) -> VortexResult<usize> {
28        Ok(Self::validity_mask(array)?.false_count())
29    }
30
31    fn validity_mask(array: &V::Array) -> VortexResult<Mask>;
32}
33
34/// An implementation of the [`ValidityVTable`] for arrays that hold validity as a child array.
35pub struct ValidityVTableFromValidityHelper;
36
37/// Expose validity held as a child array.
38pub trait ValidityHelper {
39    fn validity(&self) -> &Validity;
40}
41
42impl<V: VTable> ValidityVTable<V> for ValidityVTableFromValidityHelper
43where
44    V::Array: ValidityHelper,
45{
46    fn is_valid(array: &V::Array, index: usize) -> VortexResult<bool> {
47        array.validity().is_valid(index)
48    }
49
50    fn all_valid(array: &V::Array) -> VortexResult<bool> {
51        array.validity().all_valid()
52    }
53
54    fn all_invalid(array: &V::Array) -> VortexResult<bool> {
55        array.validity().all_invalid()
56    }
57
58    fn validity_mask(array: &V::Array) -> VortexResult<Mask> {
59        array.validity().to_mask(array.len())
60    }
61}
62
63/// An implementation of the [`ValidityVTable`] for arrays that hold an unsliced validity
64/// and a slice into it.
65pub struct ValidityVTableFromValiditySliceHelper;
66
67pub trait ValiditySliceHelper {
68    fn unsliced_validity_and_slice(&self) -> (&Validity, usize, usize);
69
70    fn sliced_validity(&self) -> VortexResult<Validity> {
71        let (unsliced_validity, start, stop) = self.unsliced_validity_and_slice();
72        unsliced_validity.slice(start, stop)
73    }
74}
75
76impl<V: VTable> ValidityVTable<V> for ValidityVTableFromValiditySliceHelper
77where
78    V::Array: ValiditySliceHelper,
79{
80    fn is_valid(array: &V::Array, index: usize) -> VortexResult<bool> {
81        let (unsliced_validity, start, _) = array.unsliced_validity_and_slice();
82        unsliced_validity.is_valid(start + index)
83    }
84
85    fn all_valid(array: &V::Array) -> VortexResult<bool> {
86        array.sliced_validity()?.all_valid()
87    }
88
89    fn all_invalid(array: &V::Array) -> VortexResult<bool> {
90        array.sliced_validity()?.all_invalid()
91    }
92
93    fn validity_mask(array: &V::Array) -> VortexResult<Mask> {
94        array.sliced_validity()?.to_mask(array.len())
95    }
96}
97
98/// An implementation of the [`ValidityVTable`] for arrays that delegate validity entirely
99/// to a child array.
100pub struct ValidityVTableFromChild;
101
102pub trait ValidityChild<V: VTable> {
103    fn validity_child(array: &V::Array) -> &dyn Array;
104}
105
106impl<V: VTable> ValidityVTable<V> for ValidityVTableFromChild
107where
108    V: ValidityChild<V>,
109{
110    fn is_valid(array: &V::Array, index: usize) -> VortexResult<bool> {
111        V::validity_child(array).is_valid(index)
112    }
113
114    fn all_valid(array: &V::Array) -> VortexResult<bool> {
115        V::validity_child(array).all_valid()
116    }
117
118    fn all_invalid(array: &V::Array) -> VortexResult<bool> {
119        V::validity_child(array).all_invalid()
120    }
121
122    fn validity_mask(array: &V::Array) -> VortexResult<Mask> {
123        V::validity_child(array).validity_mask()
124    }
125}