vortex_array/arrays/constant/vtable/
pipeline.rs1use std::any::Any;
5use std::hash::{Hash, Hasher};
6use std::sync::Arc;
7
8use vortex_dtype::{DType, NativePType, match_each_native_ptype};
9use vortex_error::{VortexExpect, VortexResult};
10
11use crate::arrays::{ConstantArray, ConstantVTable};
12use crate::operator::{LengthBounds, Operator, OperatorEq, OperatorHash, OperatorId, OperatorRef};
13use crate::pipeline::bits::BitView;
14use crate::pipeline::vec::Selection;
15use crate::pipeline::view::ViewMut;
16use crate::pipeline::{
17 BindContext, Element, Kernel, KernelContext, N, PipelinedOperator, RowSelection,
18};
19use crate::vtable::PipelineVTable;
20
21impl PipelineVTable<ConstantVTable> for ConstantVTable {
22 fn to_operator(array: &ConstantArray) -> VortexResult<Option<OperatorRef>> {
23 Ok(Some(Arc::new(array.clone())))
24 }
25}
26
27impl OperatorHash for ConstantArray {
28 fn operator_hash<H: Hasher>(&self, state: &mut H) {
29 self.scalar.hash(state);
30 self.len.hash(state);
31 }
32}
33
34impl OperatorEq for ConstantArray {
35 fn operator_eq(&self, other: &Self) -> bool {
36 self.scalar == other.scalar && self.len == other.len
37 }
38}
39
40impl Operator for ConstantArray {
41 fn id(&self) -> OperatorId {
42 self.encoding_id()
43 }
44
45 fn as_any(&self) -> &dyn Any {
46 self
47 }
48
49 fn dtype(&self) -> &DType {
50 self.scalar.dtype()
51 }
52
53 fn bounds(&self) -> LengthBounds {
54 self.len.into()
55 }
56
57 fn children(&self) -> &[OperatorRef] {
58 &[]
59 }
60
61 fn with_children(self: Arc<Self>, _children: Vec<OperatorRef>) -> VortexResult<OperatorRef> {
62 Ok(self)
63 }
64}
65
66impl PipelinedOperator for ConstantArray {
67 fn row_selection(&self) -> RowSelection {
68 RowSelection::Domain(self.len)
69 }
70
71 fn bind(&self, _ctx: &dyn BindContext) -> VortexResult<Box<dyn Kernel>> {
72 debug_assert!(matches!(
73 self.dtype(),
74 DType::Bool(_) | DType::Primitive(..)
75 ));
76 match self.scalar.dtype() {
77 DType::Bool(_) => Ok(Box::new(BoolConstantKernel {
78 value: self
79 .scalar
80 .as_bool()
81 .value()
82 .vortex_expect("scalar value not bool"),
83 })),
84 DType::Primitive(..) => Ok(match_each_native_ptype!(
85 self.scalar.as_primitive().ptype(),
86 |T| {
87 Box::new(ConstantKernel::<T> {
88 value: self
89 .scalar
90 .as_primitive()
91 .typed_value::<T>()
92 .vortex_expect("scalar value not of type T"),
93 })
94 }
95 )),
96 _ => todo!(
97 "Unsupported scalar type for constant: {:?}",
98 self.scalar.dtype()
99 ),
100 }
101 }
102
103 fn vector_children(&self) -> Vec<usize> {
104 vec![]
105 }
106
107 fn batch_children(&self) -> Vec<usize> {
108 vec![]
109 }
110}
111
112pub struct ConstantKernel<T: NativePType> {
114 value: T,
115}
116
117pub struct BoolConstantKernel {
119 value: bool,
120}
121
122impl<T: Element + NativePType> Kernel for ConstantKernel<T> {
123 fn step(
124 &self,
125 _ctx: &KernelContext,
126 _chunk_idx: usize,
127 _selection: &BitView,
128 out: &mut ViewMut,
129 ) -> VortexResult<()> {
130 out.as_array_mut::<T>()[..N].fill(self.value);
132 out.set_selection(Selection::Prefix);
133 Ok(())
134 }
135}
136
137impl Kernel for BoolConstantKernel {
138 fn step(
139 &self,
140 _ctx: &KernelContext,
141 _chunk_idx: usize,
142 _selection: &BitView,
143 out: &mut ViewMut,
144 ) -> VortexResult<()> {
145 out.as_array_mut::<bool>()[..N].fill(self.value);
147 out.set_selection(Selection::Prefix);
148 Ok(())
149 }
150}