vortex_expr/operator/
reduce.rs1use 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}