vortex_array/arrays/primitive/vtable/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_buffer::Alignment;
5use vortex_buffer::Buffer;
6use vortex_buffer::BufferHandle;
7use vortex_dtype::DType;
8use vortex_dtype::PType;
9use vortex_dtype::match_each_native_ptype;
10use vortex_error::VortexResult;
11use vortex_error::vortex_bail;
12use vortex_vector::Vector;
13use vortex_vector::primitive::PVector;
14
15use crate::EmptyMetadata;
16use crate::arrays::PrimitiveArray;
17use crate::execution::ExecutionCtx;
18use crate::serde::ArrayChildren;
19use crate::validity::Validity;
20use crate::vtable;
21use crate::vtable::ArrayVTableExt;
22use crate::vtable::NotSupported;
23use crate::vtable::VTable;
24use crate::vtable::ValidityVTableFromValidityHelper;
25
26mod array;
27mod canonical;
28mod operations;
29pub mod operator;
30mod validity;
31mod visitor;
32
33pub use operator::PrimitiveMaskedValidityRule;
34
35use crate::vtable::ArrayId;
36use crate::vtable::ArrayVTable;
37
38vtable!(Primitive);
39
40impl VTable for PrimitiveVTable {
41    type Array = PrimitiveArray;
42
43    type Metadata = EmptyMetadata;
44
45    type ArrayVTable = Self;
46    type CanonicalVTable = Self;
47    type OperationsVTable = Self;
48    type ValidityVTable = ValidityVTableFromValidityHelper;
49    type VisitorVTable = Self;
50    type ComputeVTable = NotSupported;
51    type EncodeVTable = NotSupported;
52
53    fn id(&self) -> ArrayId {
54        ArrayId::new_ref("vortex.primitive")
55    }
56
57    fn encoding(_array: &Self::Array) -> ArrayVTable {
58        PrimitiveVTable.as_vtable()
59    }
60
61    fn metadata(_array: &PrimitiveArray) -> VortexResult<Self::Metadata> {
62        Ok(EmptyMetadata)
63    }
64
65    fn serialize(_metadata: Self::Metadata) -> VortexResult<Option<Vec<u8>>> {
66        Ok(Some(vec![]))
67    }
68
69    fn deserialize(_buffer: &[u8]) -> VortexResult<Self::Metadata> {
70        Ok(EmptyMetadata)
71    }
72
73    fn build(
74        &self,
75        dtype: &DType,
76        len: usize,
77        _metadata: &Self::Metadata,
78        buffers: &[BufferHandle],
79        children: &dyn ArrayChildren,
80    ) -> VortexResult<PrimitiveArray> {
81        if buffers.len() != 1 {
82            vortex_bail!("Expected 1 buffer, got {}", buffers.len());
83        }
84        let buffer = buffers[0].clone().try_to_bytes()?;
85
86        let validity = if children.is_empty() {
87            Validity::from(dtype.nullability())
88        } else if children.len() == 1 {
89            let validity = children.get(0, &Validity::DTYPE, len)?;
90            Validity::Array(validity)
91        } else {
92            vortex_bail!("Expected 0 or 1 child, got {}", children.len());
93        };
94
95        let ptype = PType::try_from(dtype)?;
96
97        if !buffer.is_aligned(Alignment::new(ptype.byte_width())) {
98            vortex_bail!(
99                "Buffer is not aligned to {}-byte boundary",
100                ptype.byte_width()
101            );
102        }
103        if buffer.len() != ptype.byte_width() * len {
104            vortex_bail!(
105                "Buffer length {} does not match expected length {} for {}, {}",
106                buffer.len(),
107                ptype.byte_width() * len,
108                ptype.byte_width(),
109                len,
110            );
111        }
112
113        match_each_native_ptype!(ptype, |P| {
114            let buffer = Buffer::<P>::from_byte_buffer(buffer);
115            Ok(PrimitiveArray::new(buffer, validity))
116        })
117    }
118
119    fn batch_execute(array: &Self::Array, _ctx: &mut ExecutionCtx) -> VortexResult<Vector> {
120        Ok(match_each_native_ptype!(array.ptype(), |T| {
121            PVector::new(array.buffer::<T>(), array.validity_mask()).into()
122        }))
123    }
124}
125
126#[derive(Debug)]
127pub struct PrimitiveVTable;