|
1 | 1 | // SPDX-License-Identifier: Apache-2.0 |
2 | 2 | // SPDX-FileCopyrightText: Copyright the Vortex contributors |
3 | 3 |
|
4 | | -use vortex_error::VortexExpect; |
5 | 4 | use vortex_error::VortexResult; |
6 | 5 |
|
7 | 6 | use crate::ArrayRef; |
8 | 7 | use crate::ExecutionCtx; |
9 | 8 | use crate::array::ArrayView; |
10 | 9 | use crate::arrays::Narrow; |
11 | | -use crate::arrays::ScalarFn; |
12 | 10 | use crate::arrays::narrow::NarrowArraySlotsExt; |
13 | 11 | use crate::arrays::narrow::compute::cast_keeping_nullability; |
14 | 12 | use crate::arrays::narrow::compute::ptype_holding_both_values; |
15 | 13 | use crate::arrays::narrow::compute::ptype_holding_values_and_scalar; |
16 | 14 | use crate::arrays::narrow::compute::wrap_values; |
17 | | -use crate::arrays::scalar_fn::ExactScalarFn; |
18 | | -use crate::arrays::scalar_fn::ScalarFnArrayExt; |
19 | | -use crate::arrays::scalar_fn::ScalarFnArrayView; |
20 | 15 | use crate::builtins::ArrayBuiltins; |
21 | | -use crate::kernel::ExecuteParentKernel; |
22 | | -use crate::scalar_fn::fns::zip::Zip; |
23 | 16 | use crate::scalar_fn::fns::zip::ZipKernel; |
24 | 17 |
|
| 18 | +/// Zips the values of a [`Narrow`] in the `if_true` branch with the `if_false` branch, when that is |
| 19 | +/// another `Narrow` or a constant, at the type that holds both. Any other `if_false` declines. |
| 20 | +/// |
| 21 | +/// [`ZipExecuteAdaptor`](crate::scalar_fn::fns::zip::ZipExecuteAdaptor) runs this kernel only for |
| 22 | +/// the `if_true` branch, so a `Narrow` in the `if_false` branch takes the default path. |
25 | 23 | impl ZipKernel for Narrow { |
26 | 24 | fn zip( |
27 | 25 | array: ArrayView<'_, Self>, |
28 | 26 | if_false: &ArrayRef, |
29 | 27 | mask: &ArrayRef, |
30 | 28 | _ctx: &mut ExecutionCtx, |
31 | 29 | ) -> VortexResult<Option<ArrayRef>> { |
32 | | - zip_values(array, if_false, mask, Branch::IfTrue) |
33 | | - } |
34 | | -} |
35 | | - |
36 | | -/// Zips a [`Narrow`] in the `if_false` branch. |
37 | | -/// |
38 | | -/// [`ZipExecuteAdaptor`] runs [`ZipKernel`] only for the `if_true` branch. |
39 | | -/// |
40 | | -/// [`ZipExecuteAdaptor`]: crate::scalar_fn::fns::zip::ZipExecuteAdaptor |
41 | | -#[derive(Debug)] |
42 | | -pub(crate) struct NarrowZipIfFalseKernel; |
43 | | - |
44 | | -impl ExecuteParentKernel<Narrow> for NarrowZipIfFalseKernel { |
45 | | - type Parent = ExactScalarFn<Zip>; |
46 | | - |
47 | | - fn execute_parent( |
48 | | - &self, |
49 | | - array: ArrayView<'_, Narrow>, |
50 | | - parent: ScalarFnArrayView<'_, Zip>, |
51 | | - child_idx: usize, |
52 | | - _ctx: &mut ExecutionCtx, |
53 | | - ) -> VortexResult<Option<ArrayRef>> { |
54 | | - if child_idx != 1 { |
55 | | - return Ok(None); |
56 | | - } |
57 | | - |
58 | | - let zip = parent |
59 | | - .as_opt::<ScalarFn>() |
60 | | - .vortex_expect("ExactScalarFn matcher confirmed ScalarFnArray"); |
61 | | - |
62 | | - zip_values(array, zip.get_child(0), zip.get_child(2), Branch::IfFalse) |
63 | | - } |
64 | | -} |
65 | | - |
66 | | -/// The branch of a zip that holds the [`Narrow`]. |
67 | | -enum Branch { |
68 | | - IfTrue, |
69 | | - IfFalse, |
70 | | -} |
71 | | - |
72 | | -/// Zips the values of `array` with the values of `other`, a `Narrow` or a constant, at the type |
73 | | -/// that holds both. Any other `other` declines. |
74 | | -fn zip_values( |
75 | | - array: ArrayView<'_, Narrow>, |
76 | | - other: &ArrayRef, |
77 | | - mask: &ArrayRef, |
78 | | - branch: Branch, |
79 | | -) -> VortexResult<Option<ArrayRef>> { |
80 | | - let values = array.values(); |
81 | | - let (other_values, ptype) = if let Some(other) = other.as_opt::<Narrow>() { |
82 | | - let Some(ptype) = ptype_holding_both_values(array, other) else { |
| 30 | + let (if_false_values, ptype) = if let Some(other) = if_false.as_opt::<Narrow>() { |
| 31 | + let Some(ptype) = ptype_holding_both_values(array, other) else { |
| 32 | + return Ok(None); |
| 33 | + }; |
| 34 | + (other.values().clone(), ptype) |
| 35 | + } else if let Some(constant) = if_false.as_constant() { |
| 36 | + let Some(ptype) = ptype_holding_values_and_scalar(array, constant)? else { |
| 37 | + return Ok(None); |
| 38 | + }; |
| 39 | + (if_false.clone(), ptype) |
| 40 | + } else { |
83 | 41 | return Ok(None); |
84 | 42 | }; |
85 | | - (other.values().clone(), ptype) |
86 | | - } else if let Some(constant) = other.as_constant() { |
87 | | - let Some(ptype) = ptype_holding_values_and_scalar(array, constant)? else { |
88 | | - return Ok(None); |
89 | | - }; |
90 | | - (other.clone(), ptype) |
91 | | - } else { |
92 | | - return Ok(None); |
93 | | - }; |
94 | 43 |
|
95 | | - let values = cast_keeping_nullability(values, ptype)?; |
96 | | - let other_values = cast_keeping_nullability(&other_values, ptype)?; |
| 44 | + let if_true_values = cast_keeping_nullability(array.values(), ptype)?; |
| 45 | + let if_false_values = cast_keeping_nullability(&if_false_values, ptype)?; |
97 | 46 |
|
98 | | - let zipped = match branch { |
99 | | - Branch::IfTrue => mask.zip(values, other_values)?, |
100 | | - Branch::IfFalse => mask.zip(other_values, values)?, |
101 | | - }; |
102 | | - let dtype = array.dtype().with_nullability(zipped.dtype().nullability()); |
| 47 | + let zipped = mask.zip(if_true_values, if_false_values)?; |
| 48 | + let dtype = array.dtype().with_nullability(zipped.dtype().nullability()); |
103 | 49 |
|
104 | | - wrap_values(zipped, dtype).map(Some) |
| 50 | + wrap_values(zipped, dtype).map(Some) |
| 51 | + } |
105 | 52 | } |
0 commit comments