Skip to main content

vortex_array/array/vtable/
validity.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_error::VortexResult;
5
6use crate::ArrayRef;
7use crate::array::ArrayView;
8use crate::array::VTable;
9use crate::validity::Validity;
10
11/// Validity access for nullable instances of an encoding.
12///
13/// Non-nullable arrays bypass this hook and report [`Validity::NonNullable`]. Nullable arrays call
14/// into the encoding so it can expose either a constant validity state or a row-aligned boolean
15/// child array.
16pub trait ValidityVTable<V: VTable> {
17    /// Returns the [`Validity`] of the array.
18    ///
19    /// ## Pre-conditions
20    ///
21    /// - The array DType is nullable.
22    ///
23    /// ## Post-conditions
24    ///
25    /// If this returns [`Validity::Array`], the child array must have the same length as `array`
26    /// and non-nullable boolean dtype.
27    fn validity(array: ArrayView<'_, V>) -> VortexResult<Validity>;
28}
29
30/// An implementation of the [`ValidityVTable`] for arrays that delegate validity entirely
31/// to a child array.
32pub struct ValidityVTableFromChild;
33
34/// Helper trait for encodings whose validity is exactly one child slot.
35pub trait ValidityChild<V: VTable> {
36    /// Returns the child array that carries validity for `array`.
37    fn validity_child(array: ArrayView<'_, V>) -> ArrayRef;
38}
39
40impl<V: VTable> ValidityVTable<V> for ValidityVTableFromChild
41where
42    V: ValidityChild<V>,
43{
44    fn validity(array: ArrayView<'_, V>) -> VortexResult<Validity> {
45        V::validity_child(array).validity()
46    }
47}
48
49/// An implementation of the [`ValidityVTable`] for arrays that hold an unsliced validity
50/// and a slice into it.
51pub struct ValidityVTableFromChildSliceHelper;
52
53/// Helper for encodings that keep an unsliced validity child plus a local slice range.
54pub trait ValidityChildSliceHelper {
55    /// Returns `(unsliced_validity, start, stop)` for this array's logical slice.
56    fn unsliced_child_and_slice(&self) -> (&ArrayRef, usize, usize);
57
58    /// Returns a sliced validity child array for the logical range.
59    fn sliced_child_array(&self) -> VortexResult<ArrayRef> {
60        let (unsliced_validity, start, stop) = self.unsliced_child_and_slice();
61        unsliced_validity.slice(start..stop)
62    }
63}
64
65impl<V: VTable> ValidityVTable<V> for ValidityVTableFromChildSliceHelper
66where
67    V::TypedArrayData: ValidityChildSliceHelper,
68{
69    fn validity(array: ArrayView<'_, V>) -> VortexResult<Validity> {
70        array.data().sliced_child_array()?.validity()
71    }
72}