Path: blob/main/crates/polars-plan/src/plans/visitor/lp.rs
6940 views
use polars_utils::unitvec;12use super::*;3use crate::prelude::*;45#[derive(Copy, Clone, Debug)]6pub struct IRNode {7node: Node,8// Whether it may mutate the arena on rewrite.9// If set the Rewriting Treewalker will mutate the arena.10mutate: bool,11}1213impl IRNode {14pub fn new(node: Node) -> Self {15Self {16node,17mutate: false,18}19}2021pub fn new_mutate(node: Node) -> Self {22Self { node, mutate: true }23}2425pub fn node(&self) -> Node {26self.node27}2829pub fn replace_node(&mut self, node: Node) {30self.node = node;31}3233/// Replace the current `Node` with a new `IR`.34pub fn replace(&mut self, ae: IR, arena: &mut Arena<IR>) {35let node = self.node;36arena.replace(node, ae);37}3839pub fn to_alp<'a>(&self, arena: &'a Arena<IR>) -> &'a IR {40arena.get(self.node)41}4243pub fn to_alp_mut<'a>(&mut self, arena: &'a mut Arena<IR>) -> &'a mut IR {44arena.get_mut(self.node)45}4647pub fn assign(&mut self, ir_node: IR, arena: &mut Arena<IR>) {48let node = arena.add(ir_node);49self.node = node;50}51}5253pub type IRNodeArena = (Arena<IR>, Arena<AExpr>);5455impl TreeWalker for IRNode {56type Arena = IRNodeArena;5758fn apply_children<F: FnMut(&Self, &Self::Arena) -> PolarsResult<VisitRecursion>>(59&self,60op: &mut F,61arena: &Self::Arena,62) -> PolarsResult<VisitRecursion> {63let mut scratch = unitvec![];6465self.to_alp(&arena.0).copy_inputs(&mut scratch);66for &node in scratch.as_slice() {67let mut lp_node = IRNode::new(node);68lp_node.mutate = self.mutate;69match op(&lp_node, arena)? {70// let the recursion continue71VisitRecursion::Continue | VisitRecursion::Skip => {},72// early stop73VisitRecursion::Stop => return Ok(VisitRecursion::Stop),74}75}76Ok(VisitRecursion::Continue)77}7879fn map_children<F: FnMut(Self, &mut Self::Arena) -> PolarsResult<Self>>(80self,81op: &mut F,82arena: &mut Self::Arena,83) -> PolarsResult<Self> {84let mut inputs = vec![];8586let lp = arena.0.get(self.node);87lp.copy_inputs(&mut inputs);8889// rewrite the nodes90for node in &mut inputs {91let mut lp_node = IRNode::new(*node);92lp_node.mutate = self.mutate;93*node = op(lp_node, arena)?.node;94}95let lp = arena.0.get(self.node);96let lp = lp.clone().with_inputs(inputs);97if self.mutate {98arena.0.replace(self.node, lp);99Ok(self)100} else {101let node = arena.0.add(lp);102Ok(IRNode::new_mutate(node))103}104}105}106107#[cfg(feature = "cse")]108pub(crate) fn with_ir_arena<F: FnOnce(&mut IRNodeArena) -> T, T>(109lp_arena: &mut Arena<IR>,110expr_arena: &mut Arena<AExpr>,111func: F,112) -> T {113try_with_ir_arena(lp_arena, expr_arena, |a| Ok(func(a))).unwrap()114}115116#[cfg(feature = "cse")]117pub(crate) fn try_with_ir_arena<F: FnOnce(&mut IRNodeArena) -> PolarsResult<T>, T>(118lp_arena: &mut Arena<IR>,119expr_arena: &mut Arena<AExpr>,120func: F,121) -> PolarsResult<T> {122let owned_lp_arena = std::mem::take(lp_arena);123let owned_expr_arena = std::mem::take(expr_arena);124125let mut arena = (owned_lp_arena, owned_expr_arena);126let out = func(&mut arena);127std::mem::swap(lp_arena, &mut arena.0);128std::mem::swap(expr_arena, &mut arena.1);129out130}131132133