• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16728097825

04 Aug 2025 04:00PM UTC coverage: 48.355% (-35.1%) from 83.429%
16728097825

Pull #4108

github

web-flow
Merge 1b2d27fd8 into 649ba9576
Pull Request #4108: perf[vortex-array]: use all_valid instead of `invalid_count() == 0`

1 of 1 new or added line in 1 file covered. (100.0%)

11596 existing lines in 378 files now uncovered.

18635 of 38538 relevant lines covered (48.35%)

151786.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/vortex-array/src/arrays/null/compute.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use vortex_dtype::match_each_integer_ptype;
5
use vortex_error::{VortexResult, vortex_bail};
6
use vortex_mask::Mask;
7

8
use crate::arrays::NullVTable;
9
use crate::arrays::null::NullArray;
10
use crate::compute::{
11
    FilterKernel, FilterKernelAdapter, MaskKernel, MaskKernelAdapter, MinMaxKernel,
12
    MinMaxKernelAdapter, MinMaxResult, TakeKernel, TakeKernelAdapter,
13
};
14
use crate::{Array, ArrayRef, IntoArray, ToCanonical, register_kernel};
15

16
impl FilterKernel for NullVTable {
UNCOV
17
    fn filter(&self, _array: &Self::Array, mask: &Mask) -> VortexResult<ArrayRef> {
×
UNCOV
18
        Ok(NullArray::new(mask.true_count()).into_array())
×
UNCOV
19
    }
×
20
}
21

22
register_kernel!(FilterKernelAdapter(NullVTable).lift());
23

24
impl MaskKernel for NullVTable {
UNCOV
25
    fn mask(&self, array: &NullArray, _mask: &Mask) -> VortexResult<ArrayRef> {
×
UNCOV
26
        Ok(array.to_array())
×
UNCOV
27
    }
×
28
}
29

30
register_kernel!(MaskKernelAdapter(NullVTable).lift());
31

32
impl TakeKernel for NullVTable {
33
    #[allow(clippy::cast_possible_truncation)]
UNCOV
34
    fn take(&self, array: &NullArray, indices: &dyn Array) -> VortexResult<ArrayRef> {
×
UNCOV
35
        let indices = indices.to_primitive()?;
×
36

37
        // Enforce all indices are valid
UNCOV
38
        match_each_integer_ptype!(indices.ptype(), |T| {
×
39
            for index in indices.as_slice::<T>() {
×
40
                if (*index as usize) >= array.len() {
×
41
                    vortex_bail!(OutOfBounds: *index as usize, 0, array.len());
×
42
                }
×
43
            }
44
        });
45

UNCOV
46
        Ok(NullArray::new(indices.len()).into_array())
×
UNCOV
47
    }
×
48
}
49

50
register_kernel!(TakeKernelAdapter(NullVTable).lift());
51

52
impl MinMaxKernel for NullVTable {
53
    fn min_max(&self, _array: &NullArray) -> VortexResult<Option<MinMaxResult>> {
×
54
        Ok(None)
×
55
    }
×
56
}
57

58
register_kernel!(MinMaxKernelAdapter(NullVTable).lift());
59

60
#[cfg(test)]
61
mod test {
62
    use vortex_buffer::buffer;
63
    use vortex_dtype::DType;
64
    use vortex_mask::Mask;
65

66
    use crate::arrays::null::NullArray;
67
    use crate::compute::conformance::filter::test_filter_conformance;
68
    use crate::compute::conformance::mask::test_mask_conformance;
69
    use crate::compute::conformance::take::test_take_conformance;
70
    use crate::compute::take;
71
    use crate::{IntoArray, ToCanonical};
72

73
    #[test]
74
    fn test_slice_nulls() {
75
        let nulls = NullArray::new(10);
76
        let sliced = nulls.slice(0, 4).unwrap().to_null().unwrap();
77

78
        assert_eq!(sliced.len(), 4);
79
        assert!(matches!(sliced.validity_mask().unwrap(), Mask::AllFalse(4)));
80
    }
81

82
    #[test]
83
    fn test_take_nulls() {
84
        let nulls = NullArray::new(10);
85
        let taken = take(nulls.as_ref(), &buffer![0u64, 2, 4, 6, 8].into_array())
86
            .unwrap()
87
            .to_null()
88
            .unwrap();
89

90
        assert_eq!(taken.len(), 5);
91
        assert!(matches!(taken.validity_mask().unwrap(), Mask::AllFalse(5)));
92
    }
93

94
    #[test]
95
    fn test_scalar_at_nulls() {
96
        let nulls = NullArray::new(10);
97

98
        let scalar = nulls.scalar_at(0).unwrap();
99
        assert!(scalar.is_null());
100
        assert_eq!(scalar.dtype().clone(), DType::Null);
101
    }
102

103
    #[test]
104
    fn test_filter_null_array() {
105
        test_filter_conformance(NullArray::new(5).as_ref());
106
        test_filter_conformance(NullArray::new(1).as_ref());
107
        test_filter_conformance(NullArray::new(10).as_ref());
108
    }
109

110
    #[test]
111
    fn test_mask_null_array() {
112
        test_mask_conformance(NullArray::new(5).as_ref());
113
    }
114

115
    #[test]
116
    fn test_take_null_array_conformance() {
117
        test_take_conformance(NullArray::new(5).as_ref());
118
        test_take_conformance(NullArray::new(1).as_ref());
119
        test_take_conformance(NullArray::new(10).as_ref());
120
    }
121
}
122

123
#[cfg(test)]
124
mod tests {
125
    use rstest::rstest;
126

127
    use crate::arrays::NullArray;
128
    use crate::compute::conformance::consistency::test_array_consistency;
129

130
    #[rstest]
131
    // From test_all_consistency
132
    #[case::null_array_small(NullArray::new(5))]
133
    #[case::null_array_medium(NullArray::new(100))]
134
    // Additional test cases
135
    #[case::null_array_single(NullArray::new(1))]
136
    #[case::null_array_large(NullArray::new(1000))]
137
    #[case::null_array_empty(NullArray::new(0))]
138
    fn test_null_consistency(#[case] array: NullArray) {
139
        test_array_consistency(array.as_ref());
140
    }
141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc