Coverage Report

Created: 2025-11-17 14:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/Users/andrewlamb/Software/arrow-rs/arrow-data/src/equal/list_view.rs
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
use crate::ArrayData;
19
use crate::data::count_nulls;
20
use crate::equal::equal_values;
21
use arrow_buffer::ArrowNativeType;
22
use num_integer::Integer;
23
24
14
pub(super) fn list_view_equal<T: ArrowNativeType + Integer>(
25
14
    lhs: &ArrayData,
26
14
    rhs: &ArrayData,
27
14
    lhs_start: usize,
28
14
    rhs_start: usize,
29
14
    len: usize,
30
14
) -> bool {
31
14
    let lhs_offsets = lhs.buffer::<T>(0);
32
14
    let lhs_sizes = lhs.buffer::<T>(1);
33
34
14
    let rhs_offsets = rhs.buffer::<T>(0);
35
14
    let rhs_sizes = rhs.buffer::<T>(1);
36
37
14
    let lhs_data = &lhs.child_data()[0];
38
14
    let rhs_data = &rhs.child_data()[0];
39
40
14
    let lhs_null_count = count_nulls(lhs.nulls(), lhs_start, len);
41
14
    let rhs_null_count = count_nulls(rhs.nulls(), rhs_start, len);
42
43
14
    if lhs_null_count != rhs_null_count {
44
0
        return false;
45
14
    }
46
47
14
    if lhs_null_count == 0 {
48
        // non-null pathway: all sizes must be equal, and all values must be equal
49
4
        let lhs_range_sizes = &lhs_sizes[lhs_start..lhs_start + len];
50
4
        let rhs_range_sizes = &rhs_sizes[rhs_start..rhs_start + len];
51
52
4
        if lhs_range_sizes.len() != rhs_range_sizes.len() {
53
0
            return false;
54
4
        }
55
56
4
        if lhs_range_sizes != rhs_range_sizes {
57
0
            return false;
58
4
        }
59
60
        // Check values for equality
61
4
        let lhs_range_offsets = &lhs_offsets[lhs_start..lhs_start + len];
62
4
        let rhs_range_offsets = &rhs_offsets[rhs_start..rhs_start + len];
63
64
4
        if lhs_range_offsets.len() != rhs_range_offsets.len() {
65
0
            return false;
66
4
        }
67
68
6
        for ((&lhs_offset, &rhs_offset), &size) in 
lhs_range_offsets4
69
4
            .iter()
70
4
            .zip(rhs_range_offsets)
71
4
            .zip(lhs_range_sizes)
72
        {
73
6
            let lhs_offset = lhs_offset.to_usize().unwrap();
74
6
            let rhs_offset = rhs_offset.to_usize().unwrap();
75
6
            let size = size.to_usize().unwrap();
76
77
            // Check if offsets are valid for the given range
78
6
            if !equal_values(lhs_data, rhs_data, lhs_offset, rhs_offset, size) {
79
0
                return false;
80
6
            }
81
        }
82
    } else {
83
        // Need to integrate validity check in the inner loop.
84
        // non-null pathway: all sizes must be equal, and all values must be equal
85
10
        let lhs_range_sizes = &lhs_sizes[lhs_start..lhs_start + len];
86
10
        let rhs_range_sizes = &rhs_sizes[rhs_start..rhs_start + len];
87
88
10
        let lhs_nulls = lhs.nulls().unwrap().slice(lhs_start, len);
89
10
        let rhs_nulls = rhs.nulls().unwrap().slice(rhs_start, len);
90
91
        // Sizes can differ if values are null
92
10
        if lhs_range_sizes.len() != rhs_range_sizes.len() {
93
0
            return false;
94
10
        }
95
96
        // Check values for equality, with null checking
97
10
        let lhs_range_offsets = &lhs_offsets[lhs_start..lhs_start + len];
98
10
        let rhs_range_offsets = &rhs_offsets[rhs_start..rhs_start + len];
99
100
10
        if lhs_range_offsets.len() != rhs_range_offsets.len() {
101
0
            return false;
102
10
        }
103
104
44
        for (index, ((&lhs_offset, &rhs_offset), &size)) in 
lhs_range_offsets10
105
10
            .iter()
106
10
            .zip(rhs_range_offsets)
107
10
            .zip(lhs_range_sizes)
108
10
            .enumerate()
109
        {
110
44
            let lhs_is_null = lhs_nulls.is_null(index);
111
44
            let rhs_is_null = rhs_nulls.is_null(index);
112
113
44
            if lhs_is_null != rhs_is_null {
114
0
                return false;
115
44
            }
116
117
44
            let lhs_offset = lhs_offset.to_usize().unwrap();
118
44
            let rhs_offset = rhs_offset.to_usize().unwrap();
119
44
            let size = size.to_usize().unwrap();
120
121
            // Check if values match in the range
122
44
            if !lhs_is_null && 
!19
equal_values19
(
lhs_data19
,
rhs_data19
,
lhs_offset19
, rhs_offset, size) {
123
0
                return false;
124
44
            }
125
        }
126
    }
127
128
14
    true
129
14
}