vortex_expr/operator/
reduce.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_array::pipeline::OperatorRef;
5use vortex_error::VortexResult;
6
7use crate::traversal::{FoldUp, Node, NodeExt, NodeFolder, NodeRewriter, Transformed};
8
9pub fn reduce_operator(operator: OperatorRef) -> VortexResult<OperatorRef> {
10    let operator = reduce_up(operator.clone())?;
11    reduce_down(operator)
12}
13
14pub fn reduce_up(operator: OperatorRef) -> VortexResult<OperatorRef> {
15    let mut folder = UpReducer;
16    operator.fold(&mut folder).map(|t| t.value())
17}
18
19pub fn reduce_down(operator: OperatorRef) -> VortexResult<OperatorRef> {
20    let mut rewriter = DownReducer;
21    operator.rewrite(&mut rewriter).map(|t| t.value)
22}
23
24struct UpReducer;
25
26impl NodeFolder for UpReducer {
27    type NodeTy = OperatorRef;
28    type Result = OperatorRef;
29
30    fn visit_up(
31        &mut self,
32        node: Self::NodeTy,
33        children: Vec<Self::Result>,
34    ) -> VortexResult<FoldUp<Self::Result>> {
35        Ok(FoldUp::Continue(
36            match node.reduce_children(children.as_slice()) {
37                None => node.with_children(children),
38                Some(r) => r,
39            },
40        ))
41    }
42}
43
44struct DownReducer;
45
46impl NodeRewriter for DownReducer {
47    type NodeTy = OperatorRef;
48
49    fn visit_down(&mut self, node: Self::NodeTy) -> VortexResult<Transformed<Self::NodeTy>> {
50        if node.children_count() != 1 {
51            return Ok(Transformed::no(node));
52        }
53        match node.children()[0].reduce_parent(node.clone()) {
54            None => Ok(Transformed::no(node)),
55            Some(r) => Ok(Transformed::yes(r)),
56        }
57    }
58}