vortex_array/operator/
hash.rs1use std::any::Any;
5use std::hash::{Hash, Hasher};
6use std::sync::Arc;
7
8use vortex_buffer::Buffer;
9use vortex_mask::Mask;
10
11use crate::ArrayRef;
12use crate::operator::{Operator, OperatorRef};
13use crate::validity::Validity;
14
15pub trait OperatorHash {
21 fn operator_hash<H: Hasher>(&self, state: &mut H);
22}
23
24pub trait DynOperatorHash: private::SealedHash {
25 fn dyn_operator_hash(&self, state: &mut dyn Hasher);
26}
27
28impl<T: OperatorHash + ?Sized> DynOperatorHash for T {
29 fn dyn_operator_hash(&self, mut state: &mut dyn Hasher) {
30 OperatorHash::operator_hash(self, &mut state);
31 }
32}
33
34pub trait OperatorEq {
37 fn operator_eq(&self, other: &Self) -> bool;
38}
39
40pub trait DynOperatorEq: private::SealedEq {
41 fn dyn_operator_eq(&self, other: &dyn Any) -> bool;
42}
43
44impl<T: OperatorEq + 'static> DynOperatorEq for T {
45 fn dyn_operator_eq(&self, other: &dyn Any) -> bool {
46 other
47 .downcast_ref::<Self>()
48 .is_some_and(|other| OperatorEq::operator_eq(self, other))
49 }
50}
51
52mod private {
53 use crate::operator::{OperatorEq, OperatorHash};
54
55 pub trait SealedHash {}
56 impl<T: OperatorHash + ?Sized> SealedHash for T {}
57 pub trait SealedEq {}
58 impl<T: OperatorEq + ?Sized> SealedEq for T {}
59}
60
61impl OperatorHash for dyn Operator + '_ {
62 fn operator_hash<H: Hasher>(&self, state: &mut H) {
63 self.dyn_operator_hash(state);
64 }
65}
66
67impl OperatorEq for dyn Operator + '_ {
68 fn operator_eq(&self, other: &Self) -> bool {
69 self.dyn_operator_eq(other.as_any())
70 }
71}
72
73impl OperatorHash for OperatorRef {
74 fn operator_hash<H: Hasher>(&self, state: &mut H) {
75 self.as_ref().operator_hash(state);
76 }
77}
78
79impl OperatorEq for OperatorRef {
80 fn operator_eq(&self, other: &Self) -> bool {
81 self.as_ref().operator_eq(other.as_ref())
82 }
83}
84
85pub struct OperatorKey<T>(pub T);
88impl<T: OperatorHash> Hash for OperatorKey<T> {
89 fn hash<H: Hasher>(&self, state: &mut H) {
90 self.0.operator_hash(state);
91 }
92}
93impl<T: OperatorEq + Any> PartialEq for OperatorKey<T> {
94 fn eq(&self, other: &Self) -> bool {
95 self.0.operator_eq(&other.0)
96 }
97}
98impl<T: OperatorEq + Any> Eq for OperatorKey<T> {}
99
100impl<T> OperatorHash for Buffer<T> {
101 fn operator_hash<H: Hasher>(&self, state: &mut H) {
102 self.as_ptr().hash(state);
103 self.len().hash(state);
104 }
105}
106impl<T> OperatorEq for Buffer<T> {
107 fn operator_eq(&self, other: &Self) -> bool {
108 self.as_ptr() == other.as_ptr() && self.len() == other.len()
109 }
110}
111
112impl OperatorHash for Mask {
113 fn operator_hash<H: Hasher>(&self, state: &mut H) {
114 std::mem::discriminant(self).hash(state);
115 match self {
116 Mask::AllTrue(len) => {
117 len.hash(state);
118 }
119 Mask::AllFalse(len) => {
120 len.hash(state);
121 }
122 Mask::Values(values) => {
123 let buffer = values.boolean_buffer();
124 buffer.offset().hash(state);
125 buffer.len().hash(state);
126 buffer.inner().as_ptr().hash(state);
127 }
128 }
129 }
130}
131impl OperatorEq for Mask {
132 fn operator_eq(&self, other: &Self) -> bool {
133 match (self, other) {
134 (Mask::AllTrue(len1), Mask::AllTrue(len2)) => len1 == len2,
135 (Mask::AllFalse(len1), Mask::AllFalse(len2)) => len1 == len2,
136 (Mask::Values(buf1), Mask::Values(buf2)) => {
137 let b1 = buf1.boolean_buffer();
138 let b2 = buf2.boolean_buffer();
139 b1.offset() == b2.offset()
140 && b1.len() == b2.len()
141 && b1.inner().as_ptr() == b2.inner().as_ptr()
142 }
143 _ => false,
144 }
145 }
146}
147
148impl OperatorHash for Validity {
149 fn operator_hash<H: Hasher>(&self, state: &mut H) {
150 std::mem::discriminant(self).hash(state);
151 if let Validity::Array(array) = self {
152 Arc::as_ptr(array).hash(state);
153 }
154 }
155}
156impl OperatorEq for Validity {
157 fn operator_eq(&self, other: &Self) -> bool {
158 match (self, other) {
159 (Validity::AllValid, Validity::AllValid) => true,
160 (Validity::AllInvalid, Validity::AllInvalid) => true,
161 (Validity::NonNullable, Validity::NonNullable) => true,
162 (Validity::Array(arr1), Validity::Array(arr2)) => Arc::ptr_eq(arr1, arr2),
163 _ => false,
164 }
165 }
166}
167
168impl OperatorHash for ArrayRef {
169 fn operator_hash<H: Hasher>(&self, state: &mut H) {
170 Arc::as_ptr(self).hash(state);
171 }
172}
173impl OperatorEq for ArrayRef {
174 fn operator_eq(&self, other: &Self) -> bool {
175 Arc::ptr_eq(self, other)
176 }
177}