vortex_array/vtable/
validity.rs

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