Skip to content

Commit 277b386

Browse files
committed
extract _ignore_nullability methods out and fix ordering
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
1 parent c1f559d commit 277b386

3 files changed

Lines changed: 76 additions & 47 deletions

File tree

vortex-array/src/dtype/dtype_impl.rs

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -122,21 +122,9 @@ impl DType {
122122
lhs_size == rhs_size && lhs_dtype.eq_ignore_nullability(rhs_dtype)
123123
}
124124
(Struct(lhs_dtype, _), Struct(rhs_dtype, _)) => {
125-
(lhs_dtype.names() == rhs_dtype.names())
126-
&& (lhs_dtype
127-
.fields()
128-
.zip_eq(rhs_dtype.fields())
129-
.all(|(l, r)| l.eq_ignore_nullability(&r)))
130-
}
131-
(Union(lhs, _), Union(rhs, _)) => {
132-
// Equal `names` implies equal length by FieldNames equality.
133-
lhs.names() == rhs.names()
134-
&& lhs.type_ids() == rhs.type_ids()
135-
&& lhs
136-
.variants()
137-
.zip_eq(rhs.variants())
138-
.all(|(l, r)| l.eq_ignore_nullability(&r))
125+
lhs_dtype.eq_ignore_nullability(rhs_dtype)
139126
}
127+
(Union(lhs, _), Union(rhs, _)) => lhs.eq_ignore_nullability(rhs),
140128
(Variant(_), Variant(_)) => true,
141129
(Extension(lhs_extdtype), Extension(rhs_extdtype)) => {
142130
lhs_extdtype.eq_ignore_nullability(rhs_extdtype)
@@ -155,22 +143,11 @@ impl DType {
155143
Decimal(decimal, _) => decimal.hash(state),
156144
List(element, _) => element.hash_ignore_nullability(state),
157145
FixedSizeList(element, size, _) => {
158-
size.hash(state);
159146
element.hash_ignore_nullability(state);
147+
size.hash(state);
160148
}
161-
Struct(fields, _) => {
162-
fields.names().hash(state);
163-
for field in fields.fields() {
164-
field.hash_ignore_nullability(state);
165-
}
166-
}
167-
Union(variants) => {
168-
variants.names().hash(state);
169-
variants.type_ids().hash(state);
170-
for variant in variants.variants() {
171-
variant.hash_ignore_nullability(state);
172-
}
173-
}
149+
Struct(fields, _) => fields.hash_ignore_nullability(state),
150+
Union(variants, _) => variants.hash_ignore_nullability(state),
174151
Extension(ext) => ext.hash_ignore_nullability(state),
175152
}
176153
}
@@ -586,22 +563,28 @@ mod tests {
586563

587564
#[test]
588565
fn test_union_dtype_hash_ignores_variant_nullability() -> VortexResult<()> {
589-
let lhs = DType::Union(UnionVariants::try_new(
590-
["int", "string"].into(),
591-
vec![
592-
DType::Primitive(PType::I32, Nullable),
593-
DType::Utf8(NonNullable),
594-
],
595-
vec![5, 9],
596-
)?);
597-
let rhs = DType::Union(UnionVariants::try_new(
598-
["int", "string"].into(),
599-
vec![
600-
DType::Primitive(PType::I32, NonNullable),
601-
DType::Utf8(Nullable),
602-
],
603-
vec![5, 9],
604-
)?);
566+
let lhs = DType::Union(
567+
UnionVariants::try_new(
568+
["int", "string"].into(),
569+
vec![
570+
DType::Primitive(PType::I32, Nullable),
571+
DType::Utf8(NonNullable),
572+
],
573+
vec![5, 9],
574+
)?,
575+
NonNullable,
576+
);
577+
let rhs = DType::Union(
578+
UnionVariants::try_new(
579+
["int", "string"].into(),
580+
vec![
581+
DType::Primitive(PType::I32, NonNullable),
582+
DType::Utf8(Nullable),
583+
],
584+
vec![5, 9],
585+
)?,
586+
NonNullable,
587+
);
605588

606589
assert!(lhs.eq_ignore_nullability(&rhs));
607590
assert_eq!(hash_ignore_nullability(&lhs), hash_ignore_nullability(&rhs));

vortex-array/src/dtype/struct_.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::fmt::Display;
55
use std::fmt::Formatter;
66
use std::hash::Hash;
7+
use std::hash::Hasher;
78
use std::sync::Arc;
89
use std::sync::OnceLock;
910

@@ -83,7 +84,7 @@ impl PartialEq for FieldDTypeInner {
8384
impl Eq for FieldDTypeInner {}
8485

8586
impl Hash for FieldDTypeInner {
86-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
87+
fn hash<H: Hasher>(&self, state: &mut H) {
8788
match self {
8889
FieldDTypeInner::Owned(owned) => {
8990
owned.hash(state);
@@ -255,12 +256,33 @@ impl PartialEq for StructFieldsInner {
255256
impl Eq for StructFieldsInner {}
256257

257258
impl Hash for StructFieldsInner {
258-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
259+
fn hash<H: Hasher>(&self, state: &mut H) {
259260
self.names.hash(state);
260261
self.dtypes.hash(state);
261262
}
262263
}
263264

265+
impl StructFields {
266+
/// Check if these struct fields are equal, ignoring field dtype nullability recursively.
267+
pub fn eq_ignore_nullability(&self, other: &Self) -> bool {
268+
Arc::ptr_eq(&self.0, &other.0)
269+
|| (self.0.names == other.0.names
270+
&& self
271+
.fields()
272+
.zip_eq(other.fields())
273+
.all(|(lhs, rhs)| lhs.eq_ignore_nullability(&rhs)))
274+
}
275+
276+
/// Hash these struct fields using the same equivalence relation as
277+
/// [`Self::eq_ignore_nullability`].
278+
pub(crate) fn hash_ignore_nullability<H: Hasher>(&self, state: &mut H) {
279+
self.0.names.hash(state);
280+
for field in self.fields() {
281+
field.hash_ignore_nullability(state);
282+
}
283+
}
284+
}
285+
264286
impl Default for StructFields {
265287
fn default() -> Self {
266288
Self::empty()

vortex-array/src/dtype/union.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use std::fmt;
55
use std::hash::Hash;
6+
use std::hash::Hasher;
67
use std::sync::Arc;
78

89
use itertools::Itertools;
@@ -133,13 +134,36 @@ impl PartialEq for UnionVariantsInner {
133134
impl Eq for UnionVariantsInner {}
134135

135136
impl Hash for UnionVariantsInner {
136-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
137+
fn hash<H: Hasher>(&self, state: &mut H) {
137138
self.names.hash(state);
138139
self.dtypes.hash(state);
139140
self.type_ids.hash(state);
140141
}
141142
}
142143

144+
impl UnionVariants {
145+
/// Check if these union variants are equal, ignoring variant dtype nullability recursively.
146+
pub fn eq_ignore_nullability(&self, other: &Self) -> bool {
147+
Arc::ptr_eq(&self.0, &other.0)
148+
|| (self.0.names == other.0.names
149+
&& self
150+
.variants()
151+
.zip_eq(other.variants())
152+
.all(|(lhs, rhs)| lhs.eq_ignore_nullability(&rhs))
153+
&& self.0.type_ids == other.0.type_ids)
154+
}
155+
156+
/// Hash these union variants using the same equivalence relation as
157+
/// [`Self::eq_ignore_nullability`].
158+
pub(crate) fn hash_ignore_nullability<H: Hasher>(&self, state: &mut H) {
159+
self.0.names.hash(state);
160+
for variant in self.variants() {
161+
variant.hash_ignore_nullability(state);
162+
}
163+
self.0.type_ids.hash(state);
164+
}
165+
}
166+
143167
impl Default for UnionVariants {
144168
fn default() -> Self {
145169
Self::empty()

0 commit comments

Comments
 (0)