Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-plan/src/plans/visitor/lp.rs
6940 views
1
use polars_utils::unitvec;
2
3
use super::*;
4
use crate::prelude::*;
5
6
#[derive(Copy, Clone, Debug)]
7
pub struct IRNode {
8
node: Node,
9
// Whether it may mutate the arena on rewrite.
10
// If set the Rewriting Treewalker will mutate the arena.
11
mutate: bool,
12
}
13
14
impl IRNode {
15
pub fn new(node: Node) -> Self {
16
Self {
17
node,
18
mutate: false,
19
}
20
}
21
22
pub fn new_mutate(node: Node) -> Self {
23
Self { node, mutate: true }
24
}
25
26
pub fn node(&self) -> Node {
27
self.node
28
}
29
30
pub fn replace_node(&mut self, node: Node) {
31
self.node = node;
32
}
33
34
/// Replace the current `Node` with a new `IR`.
35
pub fn replace(&mut self, ae: IR, arena: &mut Arena<IR>) {
36
let node = self.node;
37
arena.replace(node, ae);
38
}
39
40
pub fn to_alp<'a>(&self, arena: &'a Arena<IR>) -> &'a IR {
41
arena.get(self.node)
42
}
43
44
pub fn to_alp_mut<'a>(&mut self, arena: &'a mut Arena<IR>) -> &'a mut IR {
45
arena.get_mut(self.node)
46
}
47
48
pub fn assign(&mut self, ir_node: IR, arena: &mut Arena<IR>) {
49
let node = arena.add(ir_node);
50
self.node = node;
51
}
52
}
53
54
pub type IRNodeArena = (Arena<IR>, Arena<AExpr>);
55
56
impl TreeWalker for IRNode {
57
type Arena = IRNodeArena;
58
59
fn apply_children<F: FnMut(&Self, &Self::Arena) -> PolarsResult<VisitRecursion>>(
60
&self,
61
op: &mut F,
62
arena: &Self::Arena,
63
) -> PolarsResult<VisitRecursion> {
64
let mut scratch = unitvec![];
65
66
self.to_alp(&arena.0).copy_inputs(&mut scratch);
67
for &node in scratch.as_slice() {
68
let mut lp_node = IRNode::new(node);
69
lp_node.mutate = self.mutate;
70
match op(&lp_node, arena)? {
71
// let the recursion continue
72
VisitRecursion::Continue | VisitRecursion::Skip => {},
73
// early stop
74
VisitRecursion::Stop => return Ok(VisitRecursion::Stop),
75
}
76
}
77
Ok(VisitRecursion::Continue)
78
}
79
80
fn map_children<F: FnMut(Self, &mut Self::Arena) -> PolarsResult<Self>>(
81
self,
82
op: &mut F,
83
arena: &mut Self::Arena,
84
) -> PolarsResult<Self> {
85
let mut inputs = vec![];
86
87
let lp = arena.0.get(self.node);
88
lp.copy_inputs(&mut inputs);
89
90
// rewrite the nodes
91
for node in &mut inputs {
92
let mut lp_node = IRNode::new(*node);
93
lp_node.mutate = self.mutate;
94
*node = op(lp_node, arena)?.node;
95
}
96
let lp = arena.0.get(self.node);
97
let lp = lp.clone().with_inputs(inputs);
98
if self.mutate {
99
arena.0.replace(self.node, lp);
100
Ok(self)
101
} else {
102
let node = arena.0.add(lp);
103
Ok(IRNode::new_mutate(node))
104
}
105
}
106
}
107
108
#[cfg(feature = "cse")]
109
pub(crate) fn with_ir_arena<F: FnOnce(&mut IRNodeArena) -> T, T>(
110
lp_arena: &mut Arena<IR>,
111
expr_arena: &mut Arena<AExpr>,
112
func: F,
113
) -> T {
114
try_with_ir_arena(lp_arena, expr_arena, |a| Ok(func(a))).unwrap()
115
}
116
117
#[cfg(feature = "cse")]
118
pub(crate) fn try_with_ir_arena<F: FnOnce(&mut IRNodeArena) -> PolarsResult<T>, T>(
119
lp_arena: &mut Arena<IR>,
120
expr_arena: &mut Arena<AExpr>,
121
func: F,
122
) -> PolarsResult<T> {
123
let owned_lp_arena = std::mem::take(lp_arena);
124
let owned_expr_arena = std::mem::take(expr_arena);
125
126
let mut arena = (owned_lp_arena, owned_expr_arena);
127
let out = func(&mut arena);
128
std::mem::swap(lp_arena, &mut arena.0);
129
std::mem::swap(expr_arena, &mut arena.1);
130
out
131
}
132
133