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

vortex-data / vortex / 16991469020

15 Aug 2025 01:54PM UTC coverage: 86.018% (-1.8%) from 87.855%
16991469020

Pull #4215

github

web-flow
Merge 58201b202 into 62e231a41
Pull Request #4215: Ji/vectors

90 of 1746 new or added lines in 40 files covered. (5.15%)

117 existing lines in 25 files now uncovered.

56661 of 65871 relevant lines covered (86.02%)

614266.74 hits per line

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

0.0
/vortex-array/src/pipeline/operators/compare.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use std::any::Any;
5
use std::marker::PhantomData;
6
use std::sync::Arc;
7
use std::task::Poll;
8

9
use itertools::Itertools;
10
use vortex_dtype::{NativePType, match_each_native_ptype};
11
use vortex_error::{VortexExpect, VortexResult, vortex_bail};
12

13
use crate::compute;
14
use crate::pipeline::bits::BitView;
15
use crate::pipeline::operators::constant::ConstantOperator;
16
use crate::pipeline::operators::scalar_compare::ScalarCompareOperator;
17
use crate::pipeline::operators::{BindContext, Operator};
18
use crate::pipeline::types::{Element, VType};
19
use crate::pipeline::vector::VectorId;
20
use crate::pipeline::view::ViewMut;
21
use crate::pipeline::{Kernel, KernelContext};
22

23
#[macro_export]
24
macro_rules! match_each_compare_op {
25
    ($self:expr, | $enc:ident | $body:block) => {{
26
        match $self {
27
            $crate::compute::Operator::Eq => {
28
                type $enc = $crate::pipeline::operators::compare::Eq;
29
                $body
30
            }
31
            $crate::compute::Operator::NotEq => {
32
                type $enc = $crate::pipeline::operators::compare::NotEq;
33
                $body
34
            }
35
            $crate::compute::Operator::Gt => {
36
                type $enc = $crate::pipeline::operators::compare::Gt;
37
                $body
38
            }
39
            $crate::compute::Operator::Gte => {
40
                type $enc = $crate::pipeline::operators::compare::Gte;
41
                $body
42
            }
43
            $crate::compute::Operator::Lt => {
44
                type $enc = crate::pipeline::operators::compare::Lt;
45
                $body
46
            }
47
            $crate::compute::Operator::Lte => {
48
                type $enc = crate::pipeline::operators::compare::Lte;
49
                $body
50
            }
51
        }
52
    }};
53
}
54

55
#[derive(Debug, Hash)]
56
pub struct CompareOperator {
57
    children: [Arc<dyn Operator>; 2],
58
    op: compute::Operator,
59
}
60

61
impl CompareOperator {
NEW
62
    pub fn new(lhs: Arc<dyn Operator>, rhs: Arc<dyn Operator>, op: compute::Operator) -> Self {
×
NEW
63
        assert_eq!(lhs.vtype(), rhs.vtype(), "Operands must have the same type");
×
NEW
64
        Self {
×
NEW
65
            children: [lhs, rhs],
×
NEW
66
            op,
×
NEW
67
        }
×
NEW
68
    }
×
69
}
70

71
impl Operator for CompareOperator {
NEW
72
    fn as_any(&self) -> &dyn Any {
×
NEW
73
        self
×
NEW
74
    }
×
75

NEW
76
    fn vtype(&self) -> VType {
×
NEW
77
        VType::Bool
×
NEW
78
    }
×
79

NEW
80
    fn children(&self) -> &[Arc<dyn Operator>] {
×
NEW
81
        &self.children
×
NEW
82
    }
×
83

NEW
84
    fn with_children(&self, children: Vec<Arc<dyn Operator>>) -> Arc<dyn Operator> {
×
NEW
85
        let [lhs, rhs] = children
×
NEW
86
            .try_into()
×
NEW
87
            .ok()
×
NEW
88
            .vortex_expect("Expected 2 children");
×
NEW
89
        Arc::new(CompareOperator::new(lhs, rhs, self.op))
×
NEW
90
    }
×
91

NEW
92
    fn bind(&self, ctx: &dyn BindContext) -> VortexResult<Box<dyn Kernel>> {
×
NEW
93
        assert_eq!(self.children[0].vtype(), self.children[1].vtype());
×
94

NEW
95
        match self.children[0].vtype() {
×
NEW
96
            VType::Primitive(ptype) => {
×
NEW
97
                match_each_native_ptype!(ptype, |T| {
×
NEW
98
                    match_each_compare_op!(self.op, |Op| {
×
NEW
99
                        Ok(Box::new(ComparePrimitiveKernel::<T, Op> {
×
NEW
100
                            lhs: ctx.children()[0],
×
NEW
101
                            rhs: ctx.children()[1],
×
NEW
102
                            _phantom: PhantomData,
×
NEW
103
                        }) as Box<dyn Kernel>)
×
104
                    })
105
                })
106
            }
NEW
107
            _ => vortex_bail!(
×
NEW
108
                "Unsupported type for comparison: {}",
×
NEW
109
                self.children[0].vtype()
×
110
            ),
111
        }
NEW
112
    }
×
113

NEW
114
    fn reduce_children(&self, children: &[Arc<dyn Operator>]) -> Option<Arc<dyn Operator>> {
×
NEW
115
        let constants = children
×
NEW
116
            .iter()
×
NEW
117
            .enumerate()
×
NEW
118
            .filter_map(|(idx, c)| {
×
NEW
119
                c.as_any()
×
NEW
120
                    .downcast_ref::<ConstantOperator>()
×
NEW
121
                    .map(|c| (idx, c))
×
NEW
122
            })
×
NEW
123
            .collect_vec();
×
124

NEW
125
        if constants.len() != 1 {
×
NEW
126
            return None;
×
NEW
127
        }
×
NEW
128
        let [(idx, lhs)] = constants
×
NEW
129
            .try_into()
×
NEW
130
            .ok()
×
NEW
131
            .vortex_expect("Expected 1 constant");
×
132

NEW
133
        if idx == 0 {
×
NEW
134
            Some(Arc::new(ScalarCompareOperator::new(
×
NEW
135
                children[1].clone(),
×
NEW
136
                self.op.inverse(),
×
NEW
137
                lhs.scalar.clone(),
×
NEW
138
            )))
×
139
        } else {
NEW
140
            Some(Arc::new(ScalarCompareOperator::new(
×
NEW
141
                children[0].clone(),
×
NEW
142
                self.op,
×
NEW
143
                lhs.scalar.clone(),
×
NEW
144
            )))
×
145
        }
NEW
146
    }
×
147
}
148

149
/// A compare operator for primitive types that compares two vectors element-wise using a binary
150
/// operation.
151
pub struct ComparePrimitiveKernel<T, Op> {
152
    lhs: VectorId,
153
    rhs: VectorId,
154
    _phantom: PhantomData<(T, Op)>,
155
}
156

157
impl<T: Element + NativePType, Op: CompareOp<T>> Kernel for ComparePrimitiveKernel<T, Op> {
NEW
158
    fn seek(&mut self, chunk_idx: usize) -> VortexResult<()> {
×
NEW
159
        todo!()
×
160
    }
161

NEW
162
    fn step(
×
NEW
163
        &mut self,
×
NEW
164
        ctx: &dyn KernelContext,
×
NEW
165
        selected: BitView,
×
NEW
166
        out: &mut ViewMut,
×
NEW
167
    ) -> Poll<VortexResult<()>> {
×
NEW
168
        let lhs_vec = ctx.vector(self.lhs);
×
NEW
169
        let lhs = lhs_vec.as_slice::<T>();
×
NEW
170
        let rhs_vec = ctx.vector(self.rhs);
×
NEW
171
        let rhs = rhs_vec.as_slice::<T>();
×
NEW
172
        let bools = out.as_slice_mut::<bool>();
×
173

NEW
174
        assert_eq!(
×
NEW
175
            lhs.len(),
×
NEW
176
            rhs.len(),
×
NEW
177
            "LHS and RHS must have the same length"
×
178
        );
179

NEW
180
        for i in 0..selected.true_count() {
×
NEW
181
            bools[i] = unsafe { Op::compare(lhs.get_unchecked(i), rhs.get_unchecked(i)) };
×
NEW
182
        }
×
183

NEW
184
        Poll::Ready(Ok(()))
×
NEW
185
    }
×
186
}
187

188
pub(crate) trait CompareOp<T> {
189
    fn compare(lhs: &T, rhs: &T) -> bool;
190
}
191

192
pub struct Eq;
193
impl<T: PartialEq> CompareOp<T> for Eq {
194
    #[inline(always)]
NEW
195
    fn compare(lhs: &T, rhs: &T) -> bool {
×
NEW
196
        lhs == rhs
×
NEW
197
    }
×
198
}
199

200
pub struct NotEq;
201
impl<T: PartialEq> CompareOp<T> for NotEq {
202
    #[inline(always)]
NEW
203
    fn compare(lhs: &T, rhs: &T) -> bool {
×
NEW
204
        lhs != rhs
×
NEW
205
    }
×
206
}
207

208
pub struct Gt;
209
impl<T: PartialOrd> CompareOp<T> for Gt {
210
    #[inline(always)]
NEW
211
    fn compare(lhs: &T, rhs: &T) -> bool {
×
NEW
212
        lhs > rhs
×
NEW
213
    }
×
214
}
215

216
pub struct Gte;
217
impl<T: PartialOrd> CompareOp<T> for Gte {
218
    #[inline(always)]
NEW
219
    fn compare(lhs: &T, rhs: &T) -> bool {
×
NEW
220
        lhs >= rhs
×
NEW
221
    }
×
222
}
223

224
pub struct Lt;
225
impl<T: PartialOrd> CompareOp<T> for Lt {
226
    #[inline(always)]
NEW
227
    fn compare(lhs: &T, rhs: &T) -> bool {
×
NEW
228
        lhs < rhs
×
NEW
229
    }
×
230
}
231

232
pub struct Lte;
233
impl<T: PartialOrd> CompareOp<T> for Lte {
234
    #[inline(always)]
NEW
235
    fn compare(lhs: &T, rhs: &T) -> bool {
×
NEW
236
        lhs <= rhs
×
NEW
237
    }
×
238
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc