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