vortex_expr/operator/
reduce.rs

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