Skip to content

Commit 86a215d

Browse files
committed
Flat Layout Execution
Signed-off-by: Nicholas Gates <[email protected]>
1 parent 97ab8b8 commit 86a215d

File tree

5 files changed

+66
-111
lines changed

5 files changed

+66
-111
lines changed

vortex-array/src/arrays/constant/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ pub use array::ConstantArray;
66

77
mod compute;
88

9-
mod vector;
109
mod vtable;
1110

1211
pub use vtable::ConstantVTable;

vortex-array/src/arrays/constant/vector.rs

Lines changed: 0 additions & 98 deletions
This file was deleted.

vortex-array/src/arrays/constant/vtable/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ use vortex_error::VortexResult;
77
use vortex_error::vortex_bail;
88
use vortex_scalar::Scalar;
99
use vortex_scalar::ScalarValue;
10+
use vortex_vector::ScalarOps;
1011
use vortex_vector::Vector;
1112
use vortex_vector::VectorMutOps;
1213

1314
use crate::EmptyMetadata;
1415
use crate::arrays::ConstantArray;
15-
use crate::arrays::constant::vector::to_vector;
1616
use crate::execution::ExecutionCtx;
1717
use crate::serde::ArrayChildren;
1818
use crate::vtable;
@@ -86,6 +86,10 @@ impl VTable for ConstantVTable {
8686
}
8787

8888
fn batch_execute(array: &Self::Array, _ctx: &mut ExecutionCtx) -> VortexResult<Vector> {
89-
Ok(to_vector(array.scalar().clone(), array.len()).freeze())
89+
Ok(array
90+
.scalar()
91+
.to_vector_scalar()
92+
.repeat(array.len())
93+
.freeze())
9094
}
9195
}

vortex-array/src/expr/exprs/list_contains.rs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@ use std::ops::Deref;
77

88
use arrow_buffer::bit_iterator::BitIndexIterator;
99
use vortex_buffer::BitBuffer;
10+
use vortex_compute::comparison::Compare;
11+
use vortex_compute::comparison::Equal;
12+
use vortex_compute::logical::LogicalOr;
1013
use vortex_dtype::DType;
1114
use vortex_dtype::IntegerPType;
1215
use vortex_dtype::Nullability;
1316
use vortex_dtype::PTypeDowncastExt;
1417
use vortex_dtype::match_each_integer_ptype;
18+
use vortex_error::VortexExpect;
1519
use vortex_error::VortexResult;
1620
use vortex_error::vortex_bail;
1721
use vortex_error::vortex_err;
22+
use vortex_mask::Mask;
23+
use vortex_vector::BoolDatum;
1824
use vortex_vector::Datum;
25+
use vortex_vector::Vector;
1926
use vortex_vector::VectorOps;
2027
use vortex_vector::bool::BoolVector;
2128
use vortex_vector::listview::ListViewScalar;
@@ -121,15 +128,26 @@ impl VTable for ListContains {
121128
.try_into()
122129
.map_err(|_| vortex_err!("Wrong number of arguments for ListContains expression"))?;
123130

124-
let rhs = rhs
125-
.into_scalar()
126-
.ok_or_else(|| vortex_err!("Only supports constant RHS"))?;
131+
let matches = match (lhs.as_scalar().is_some(), rhs.as_scalar().is_some()) {
132+
(true, true) => {
133+
todo!("Implement ListContains for two scalars")
134+
}
135+
(true, false) => constant_list_scalar_contains(
136+
lhs.into_scalar().vortex_expect("scalar").into_list(),
137+
rhs.into_vector().vortex_expect("vector"),
138+
),
139+
(false, true) => list_contains_scalar(
140+
lhs.ensure_vector(args.row_count).into_list(),
141+
rhs.into_scalar().vortex_expect("scalar").into_list(),
142+
),
143+
(false, false) => {
144+
vortex_bail!(
145+
"ListContains currently only supports constant needle (RHS) or constant list (LHS)"
146+
)
147+
}
148+
}?;
127149

128-
let result = list_contains_scalar(
129-
lhs.ensure_vector(args.row_count).into_list(),
130-
rhs.into_list(),
131-
)?;
132-
Ok(Datum::Vector(result.into()))
150+
Ok(Datum::Vector(matches.into()))
133151
}
134152

135153
fn stat_falsification(
@@ -190,7 +208,8 @@ pub fn list_contains(list: Expression, value: Expression) -> Expression {
190208
ListContains.new_expr(EmptyOptions, [list, value])
191209
}
192210

193-
/// Returns a [`BoolArray`] where each bit represents if a list contains the scalar.
211+
/// Returns a [`BoolVector`] where each bit represents if a list contains the scalar.
212+
// FIXME(ngates): test implementation and move to vortex-compute
194213
fn list_contains_scalar(list: ListViewVector, value: ListViewScalar) -> VortexResult<BoolVector> {
195214
// If the list array is constant, we perform a single comparison.
196215
// if list.len() > 1 && list.is_constant() {
@@ -269,6 +288,30 @@ fn list_contains_scalar(list: ListViewVector, value: ListViewScalar) -> VortexRe
269288
Ok(BoolVector::new(list_matches, list.validity().clone()))
270289
}
271290

291+
// Then there is a constant list scalar (haystack) being compared to an array of needles.
292+
// FIXME(ngates): test implementation and move to vortex-compute
293+
fn constant_list_scalar_contains(list: ListViewScalar, values: Vector) -> VortexResult<BoolVector> {
294+
let elements = list.value().elements();
295+
296+
// For each element in the list, we perform a full comparison over the values and OR
297+
// the results together.
298+
let mut result: BoolVector = BoolVector::new(
299+
BitBuffer::new_unset(values.len()),
300+
Mask::new(values.len(), false),
301+
);
302+
for i in 0..elements.len() {
303+
let element = Datum::Scalar(elements.scalar_at(i));
304+
let compared: BoolDatum = Compare::<Equal>::compare(Datum::Vector(values.clone()), element);
305+
let compared = Datum::from(compared)
306+
.ensure_vector(values.len())
307+
.into_bool();
308+
309+
result = LogicalOr::or(result, &compared);
310+
}
311+
312+
Ok(result)
313+
}
314+
272315
/// Returns a [`BitBuffer`] where each bit represents if a list contains the scalar, derived from a
273316
/// [`BoolArray`] of matches on the child elements array.
274317
///

vortex-array/src/expression.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,25 @@ use vortex_error::VortexResult;
77
use crate::Array;
88
use crate::ArrayRef;
99
use crate::IntoArray;
10+
use crate::arrays::ConstantArray;
1011
use crate::arrays::ScalarFnArray;
1112
use crate::expr::Expression;
13+
use crate::expr::Literal;
1214
use crate::expr::Root;
1315

1416
impl dyn Array + '_ {
1517
/// Apply the expression to this array, producing a new array in constant time.
1618
pub fn apply(&self, expr: &Expression) -> VortexResult<ArrayRef> {
19+
// If the expression is a root, return self.
1720
if expr.is::<Root>() {
18-
// If the expression is a root, return self.
1921
return Ok(self.to_array());
2022
}
2123

24+
// Manually convert literals to ConstantArray.
25+
if let Some(scalar) = expr.as_opt::<Literal>() {
26+
return Ok(ConstantArray::new(scalar.clone(), self.len()).into_array());
27+
}
28+
2229
// Otherwise, collect the child arrays.
2330
let children: Vec<_> = expr
2431
.children()

0 commit comments

Comments
 (0)