vortex_array/arrays/primitive/vtable/
mod.rs1use std::sync::Arc;
5
6use kernel::PARENT_KERNELS;
7use vortex_error::VortexExpect;
8use vortex_error::VortexResult;
9use vortex_error::vortex_bail;
10use vortex_error::vortex_ensure;
11use vortex_error::vortex_panic;
12
13use crate::ArrayRef;
14use crate::EmptyMetadata;
15use crate::ExecutionCtx;
16use crate::ExecutionResult;
17use crate::arrays::PrimitiveArray;
18use crate::buffer::BufferHandle;
19use crate::dtype::DType;
20use crate::dtype::PType;
21use crate::serde::ArrayChildren;
22use crate::validity::Validity;
23use crate::vtable;
24use crate::vtable::Array;
25use crate::vtable::VTable;
26use crate::vtable::ValidityVTableFromValidityHelper;
27use crate::vtable::validity_nchildren;
28use crate::vtable::validity_to_child;
29mod kernel;
30mod operations;
31mod validity;
32
33use std::hash::Hash;
34use std::hash::Hasher;
35
36use vortex_buffer::Alignment;
37use vortex_session::VortexSession;
38
39use crate::Precision;
40use crate::arrays::primitive::compute::rules::RULES;
41use crate::hash::ArrayEq;
42use crate::hash::ArrayHash;
43use crate::stats::StatsSetRef;
44use crate::vtable::ArrayId;
45
46vtable!(Primitive);
47
48impl VTable for Primitive {
49 type Array = PrimitiveArray;
50
51 type Metadata = EmptyMetadata;
52 type OperationsVTable = Self;
53 type ValidityVTable = ValidityVTableFromValidityHelper;
54
55 fn vtable(_array: &Self::Array) -> &Self {
56 &Primitive
57 }
58
59 fn id(&self) -> ArrayId {
60 Self::ID
61 }
62
63 fn len(array: &PrimitiveArray) -> usize {
64 array.buffer_handle().len() / array.ptype().byte_width()
65 }
66
67 fn dtype(array: &PrimitiveArray) -> &DType {
68 &array.dtype
69 }
70
71 fn stats(array: &PrimitiveArray) -> StatsSetRef<'_> {
72 array.stats_set.to_ref(array.as_ref())
73 }
74
75 fn array_hash<H: Hasher>(array: &PrimitiveArray, state: &mut H, precision: Precision) {
76 array.dtype.hash(state);
77 array.buffer.array_hash(state, precision);
78 array.validity.array_hash(state, precision);
79 }
80
81 fn array_eq(array: &PrimitiveArray, other: &PrimitiveArray, precision: Precision) -> bool {
82 array.dtype == other.dtype
83 && array.buffer.array_eq(&other.buffer, precision)
84 && array.validity.array_eq(&other.validity, precision)
85 }
86
87 fn nbuffers(_array: &PrimitiveArray) -> usize {
88 1
89 }
90
91 fn buffer(array: &PrimitiveArray, idx: usize) -> BufferHandle {
92 match idx {
93 0 => array.buffer_handle().clone(),
94 _ => vortex_panic!("PrimitiveArray buffer index {idx} out of bounds"),
95 }
96 }
97
98 fn buffer_name(_array: &PrimitiveArray, idx: usize) -> Option<String> {
99 match idx {
100 0 => Some("values".to_string()),
101 _ => None,
102 }
103 }
104
105 fn nchildren(array: &PrimitiveArray) -> usize {
106 validity_nchildren(&array.validity)
107 }
108
109 fn child(array: &PrimitiveArray, idx: usize) -> ArrayRef {
110 match idx {
111 0 => validity_to_child(&array.validity, array.len())
112 .vortex_expect("PrimitiveArray child index out of bounds"),
113 _ => vortex_panic!("PrimitiveArray child index {idx} out of bounds"),
114 }
115 }
116
117 fn child_name(_array: &PrimitiveArray, _idx: usize) -> String {
118 "validity".to_string()
119 }
120
121 fn metadata(_array: &PrimitiveArray) -> VortexResult<Self::Metadata> {
122 Ok(EmptyMetadata)
123 }
124
125 fn serialize(_metadata: Self::Metadata) -> VortexResult<Option<Vec<u8>>> {
126 Ok(Some(vec![]))
127 }
128
129 fn deserialize(
130 _bytes: &[u8],
131 _dtype: &DType,
132 _len: usize,
133 _buffers: &[BufferHandle],
134 _session: &VortexSession,
135 ) -> VortexResult<Self::Metadata> {
136 Ok(EmptyMetadata)
137 }
138
139 fn build(
140 dtype: &DType,
141 len: usize,
142 _metadata: &Self::Metadata,
143 buffers: &[BufferHandle],
144 children: &dyn ArrayChildren,
145 ) -> VortexResult<PrimitiveArray> {
146 if buffers.len() != 1 {
147 vortex_bail!("Expected 1 buffer, got {}", buffers.len());
148 }
149 let buffer = buffers[0].clone();
150
151 let validity = if children.is_empty() {
152 Validity::from(dtype.nullability())
153 } else if children.len() == 1 {
154 let validity = children.get(0, &Validity::DTYPE, len)?;
155 Validity::Array(validity)
156 } else {
157 vortex_bail!("Expected 0 or 1 child, got {}", children.len());
158 };
159
160 let ptype = PType::try_from(dtype)?;
161
162 vortex_ensure!(
163 buffer.is_aligned_to(Alignment::new(ptype.byte_width())),
164 "Misaligned buffer cannot be used to build PrimitiveArray of {ptype}"
165 );
166
167 if buffer.len() != ptype.byte_width() * len {
168 vortex_bail!(
169 "Buffer length {} does not match expected length {} for {}, {}",
170 buffer.len(),
171 ptype.byte_width() * len,
172 ptype.byte_width(),
173 len,
174 );
175 }
176
177 vortex_ensure!(
178 buffer.is_aligned_to(Alignment::new(ptype.byte_width())),
179 "PrimitiveArray::build: Buffer (align={}) must be aligned to {}",
180 buffer.alignment(),
181 ptype.byte_width()
182 );
183
184 unsafe {
186 Ok(PrimitiveArray::new_unchecked_from_handle(
187 buffer, ptype, validity,
188 ))
189 }
190 }
191
192 fn with_children(array: &mut Self::Array, children: Vec<ArrayRef>) -> VortexResult<()> {
193 vortex_ensure!(
194 children.len() <= 1,
195 "PrimitiveArray can have at most 1 child (validity), got {}",
196 children.len()
197 );
198
199 array.validity = if children.is_empty() {
200 Validity::from(array.dtype().nullability())
201 } else {
202 Validity::Array(children.into_iter().next().vortex_expect("checked"))
203 };
204
205 Ok(())
206 }
207
208 fn execute(array: Arc<Array<Self>>, _ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
209 Ok(ExecutionResult::done(array))
210 }
211
212 fn reduce_parent(
213 array: &Array<Self>,
214 parent: &ArrayRef,
215 child_idx: usize,
216 ) -> VortexResult<Option<ArrayRef>> {
217 RULES.evaluate(array, parent, child_idx)
218 }
219
220 fn execute_parent(
221 array: &Array<Self>,
222 parent: &ArrayRef,
223 child_idx: usize,
224 ctx: &mut ExecutionCtx,
225 ) -> VortexResult<Option<ArrayRef>> {
226 PARENT_KERNELS.execute(array, parent, child_idx, ctx)
227 }
228}
229
230#[derive(Clone, Debug)]
231pub struct Primitive;
232
233impl Primitive {
234 pub const ID: ArrayId = ArrayId::new_ref("vortex.primitive");
235}