Skip to content

Commit 5cd0a96

Browse files
authored
fix: NativePType reimplements Ord and Eq using it's own semantics (#2550)
A while ago we have added our own `total_compare` and `is_eq` methods to `NativePType`, those methods provide implementations with definitions useful for our arrays. However, at the same time we required default PartialEq and PartialOrd which for float types have different semantics. We remove usages of NativePTypes PartialOrd and PartialEq and replace it with our own functions using our own total_compare and is_eq
1 parent b955b7d commit 5cd0a96

File tree

5 files changed

+37
-15
lines changed

5 files changed

+37
-15
lines changed

encodings/fastlanes/benches/compute_between.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() {
1212
divan::main();
1313
}
1414

15-
fn generate_primitive_array<T: NativePType + NumCast + PartialOrd>(
15+
fn generate_primitive_array<T: NativePType + NumCast>(
1616
rng: &mut StdRng,
1717
len: usize,
1818
) -> PrimitiveArray {
@@ -21,7 +21,7 @@ fn generate_primitive_array<T: NativePType + NumCast + PartialOrd>(
2121
.collect::<PrimitiveArray>()
2222
}
2323

24-
fn generate_bit_pack_primitive_array<T: NativePType + NumCast + PartialOrd>(
24+
fn generate_bit_pack_primitive_array<T: NativePType + NumCast>(
2525
rng: &mut StdRng,
2626
len: usize,
2727
) -> ArrayRef {
@@ -32,7 +32,7 @@ fn generate_bit_pack_primitive_array<T: NativePType + NumCast + PartialOrd>(
3232
bitpack_to_best_bit_width(&a).vortex_expect("").into_array()
3333
}
3434

35-
fn generate_alp_bit_pack_primitive_array<T: NativePType + NumCast + PartialOrd>(
35+
fn generate_alp_bit_pack_primitive_array<T: NativePType + NumCast>(
3636
rng: &mut StdRng,
3737
len: usize,
3838
) -> ArrayRef {

encodings/fastlanes/src/for/compute/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ where
130130
.vortex_expect("Reference value cannot be null");
131131
let primitive_value: T = value.cast(array.dtype())?.as_ref().try_into()?;
132132
// Make sure that smaller values are still smaller and not larger than (which they would be after wrapping_sub)
133-
if primitive_value < min {
133+
if primitive_value.is_lt(min) {
134134
return Ok(SearchResult::NotFound(array.invalid_count()?));
135135
}
136136

vortex-array/src/arrays/primitive/compute/between.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,26 @@ fn between_impl<T: NativePType + Copy>(
3434
match (options.lower_strict, options.upper_strict) {
3535
// Note: these comparisons are explicitly passed in to allow function impl inlining
3636
(StrictComparison::Strict, StrictComparison::Strict) => {
37-
between_impl_(arr, lower, PartialOrd::lt, upper, PartialOrd::lt)
37+
between_impl_(arr, lower, NativePType::is_lt, upper, NativePType::is_lt)
3838
}
3939
(StrictComparison::Strict, StrictComparison::NonStrict) => {
40-
between_impl_(arr, lower, PartialOrd::lt, upper, PartialOrd::le)
40+
between_impl_(arr, lower, NativePType::is_lt, upper, NativePType::is_le)
4141
}
4242
(StrictComparison::NonStrict, StrictComparison::Strict) => {
43-
between_impl_(arr, lower, PartialOrd::le, upper, PartialOrd::lt)
43+
between_impl_(arr, lower, NativePType::is_le, upper, NativePType::is_lt)
4444
}
4545
(StrictComparison::NonStrict, StrictComparison::NonStrict) => {
46-
between_impl_(arr, lower, PartialOrd::le, upper, PartialOrd::le)
46+
between_impl_(arr, lower, NativePType::is_le, upper, NativePType::is_le)
4747
}
4848
}
4949
}
5050

5151
fn between_impl_<T>(
5252
arr: &PrimitiveArray,
5353
lower: T,
54-
lower_fn: impl Fn(&T, &T) -> bool,
54+
lower_fn: impl Fn(T, T) -> bool,
5555
upper: T,
56-
upper_fn: impl Fn(&T, &T) -> bool,
56+
upper_fn: impl Fn(T, T) -> bool,
5757
) -> ArrayRef
5858
where
5959
T: NativePType + Copy,
@@ -62,8 +62,8 @@ where
6262
BoolArray::new(
6363
BooleanBuffer::collect_bool(slice.len(), |idx| {
6464
// We only iterate upto arr len and |arr| == |slice|.
65-
let i = unsafe { slice.get_unchecked(idx) };
66-
lower_fn(&lower, i) & upper_fn(i, &upper)
65+
let i = unsafe { *slice.get_unchecked(idx) };
66+
lower_fn(lower, i) & upper_fn(i, upper)
6767
}),
6868
arr.validity().clone(),
6969
)

vortex-array/src/arrays/primitive/compute/is_constant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn compute_is_constant<T: NativePType>(values: &[T]) -> bool {
2323
let first_value = values[0];
2424

2525
for value in &values[1..] {
26-
if *value != first_value {
26+
if !value.is_eq(first_value) {
2727
return false;
2828
}
2929
}

vortex-dtype/src/ptype.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ pub trait NativePType:
6464
+ Copy
6565
+ Debug
6666
+ Display
67-
+ PartialEq
68-
+ PartialOrd
6967
+ Default
7068
+ RefUnwindSafe
7169
+ Num
@@ -85,6 +83,30 @@ pub trait NativePType:
8583
/// Compare another instance of this type to `self`, providing a total ordering
8684
fn total_compare(self, other: Self) -> Ordering;
8785

86+
/// Test whether self is less than or equal to the other
87+
#[inline]
88+
fn is_le(self, other: Self) -> bool {
89+
self.total_compare(other).is_le()
90+
}
91+
92+
/// Test whether self is less than the other
93+
#[inline]
94+
fn is_lt(self, other: Self) -> bool {
95+
self.total_compare(other).is_lt()
96+
}
97+
98+
/// Test whether self is greater than or equal to the other
99+
#[inline]
100+
fn is_ge(self, other: Self) -> bool {
101+
self.total_compare(other).is_ge()
102+
}
103+
104+
/// Test whether self is greater than the other
105+
#[inline]
106+
fn is_gt(self, other: Self) -> bool {
107+
self.total_compare(other).is_gt()
108+
}
109+
88110
/// Whether another instance of this type (`other`) is bitwise equal to `self`
89111
fn is_eq(self, other: Self) -> bool;
90112
}

0 commit comments

Comments
 (0)