vortex_array/vtable/
validity.rs

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