Skip to content

Commit 4968607

Browse files
perf[vortex-expr]: replace can stop looking at subtree if it finds a match (#5405)
if there is a match with a needle there can be no more matches in that subtree --------- Signed-off-by: Joe Isaacs <[email protected]>
1 parent 1d5d34a commit 4968607

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed

vortex-array/src/expr/transform/replace.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,30 @@
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

44
use vortex_dtype::{Nullability, StructFields};
5-
use vortex_error::{VortexExpect, VortexResult};
5+
use vortex_error::VortexExpect;
66

77
use crate::expr::Expression;
88
use crate::expr::exprs::get_item::col;
99
use crate::expr::exprs::pack::pack;
1010
use crate::expr::exprs::root::root;
11-
use crate::expr::traversal::{NodeExt, Transformed};
11+
use crate::expr::traversal::{NodeExt, Transformed, TraversalOrder};
1212

1313
/// Replaces all occurrences of `needle` in the expression `expr` with `replacement`.
1414
pub fn replace(expr: Expression, needle: &Expression, replacement: Expression) -> Expression {
15-
expr.transform_up(|node| replace_transformer(node, needle, &replacement))
16-
.vortex_expect("ReplaceVisitor should not fail")
17-
.into_inner()
15+
expr.transform_down(|node| {
16+
if &node == needle {
17+
Ok(Transformed {
18+
value: replacement.clone(),
19+
// If there is a match with a needle there can be no more matches in that subtree.
20+
order: TraversalOrder::Skip,
21+
changed: true,
22+
})
23+
} else {
24+
Ok(Transformed::no(node))
25+
}
26+
})
27+
.vortex_expect("ReplaceVisitor should not fail")
28+
.into_inner()
1829
}
1930

2031
/// Expand the `root` expression with a pack of the given struct fields.
@@ -32,18 +43,6 @@ pub fn replace_root_fields(expr: Expression, fields: &StructFields) -> Expressio
3243
)
3344
}
3445

35-
fn replace_transformer(
36-
node: Expression,
37-
needle: &Expression,
38-
replacement: &Expression,
39-
) -> VortexResult<Transformed<Expression>> {
40-
if &node == needle {
41-
Ok(Transformed::yes(replacement.clone()))
42-
} else {
43-
Ok(Transformed::no(node))
44-
}
45-
}
46-
4746
#[cfg(test)]
4847
mod test {
4948
use vortex_dtype::Nullability::NonNullable;

0 commit comments

Comments
 (0)