pub fn remove_undemanded(&mut self) {
        // Determine the demanded expressions to remove irrelevant ones.
        let mut demand = std::collections::HashSet::new();
        for (_index, pred) in self.predicates.iter() {
            demand.extend(pred.support());
        }
        // Start from the output columns as presumed demanded.
        // If this is not the case, the caller should project some away.
        demand.extend(self.projection.iter().cloned());
        // Proceed in *reverse* order, as expressions may depend on other
        // expressions that precede them.
        for index in (0..self.expressions.len()).rev() {
            if demand.contains(&(self.input_arity + index)) {
                demand.extend(self.expressions[index].support());
            }
        }

        // Maintain a map from initial column identifiers to locations
        // once we have removed undemanded expressions.
        let mut remap = HashMap::new();
        // This map only needs to map elements of `demand` to a new location,
        // but the logic is easier if we include all input columns (as the
        // new position is then determined by the size of the map).
        for index in 0..self.input_arity {
            remap.insert(index, index);
        }
        // Retain demanded expressions, and record their new locations.
        let mut new_expressions = Vec::new();
        for (index, expr) in self.expressions.drain(..).enumerate() {
            if demand.contains(&(index + self.input_arity)) {
                remap.insert(index + self.input_arity, remap.len());
                new_expressions.push(expr);
            }
        }
        self.expressions = new_expressions;

        // Update column identifiers; rebuild `Self` to re-establish any invariants.
        // We mirror `self.permute(&remap)` but we specifically want to remap columns
        // that are produced by `self.expressions` after the input columns.
        let (expressions, predicates, projection) = self.as_map_filter_project();
        *self = Self::new(self.input_arity)
            .map(expressions.into_iter().map(|mut e| {
                e.permute_map(&remap);
                e
            }))
            .filter(predicates.into_iter().map(|mut p| {
                p.permute_map(&remap);
                p
            }))
            .project(projection.into_iter().map(|c| remap[&c]));
    }
/// Removes unused expressions from `self.expressions`.
///
/// Expressions are "used" if they are relied upon by any output columns
/// or any predicates, even transitively. Any expressions that are not
/// relied upon in this way can be discarded.
///
/// # Example
///
/// ```rust
/// use expr::{func, MapFilterProject, MirScalarExpr, UnaryFunc, BinaryFunc};
/// // Use the output from `inline_expression` example.
/// let mut map_filter_project = MapFilterProject::new(5)
///     .map(vec![
///         MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
///         MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
///         MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(6), BinaryFunc::AddInt64),
///         MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(6), BinaryFunc::AddInt64),
///         MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
///         MirScalarExpr::column(6).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
///         MirScalarExpr::column(6).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
///     ])
///     .project(vec![3,4,8,11]);
///
/// let mut expected_optimized = MapFilterProject::new(5)
///     .map(vec![
///         MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
///         MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(5), BinaryFunc::AddInt64),
///         MirScalarExpr::column(5).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
///     ])
///     .project(vec![3,4,6,7]);
///
/// // Remove undemandedd expressions, streamlining the work done..
/// map_filter_project.remove_undemanded();
///
/// assert_eq!(
///     map_filter_project,
///     expected_optimized,
/// );
/// ```
Removes unused expressions from `self.expressions`.
Expressions are "used" if they are relied upon by any output columns
or any predicates, even transitively. Any expressions that are not
relied upon in this way can be discarded.
Removes unused expressions from ` self . expressions ` . Expressions are " used " if they are relied upon by any output columns or any predicates even transitively . Any expressions that are not relied upon in this way can be discarded .
pub fn remove_undemanded(&mut self) {
        // Determine the demanded expressions to remove irrelevant ones.
        let mut demand = std::collections::HashSet::new();
        for (_index, pred) in self.predicates.iter() {
            demand.extend(pred.support());
        }
        // Start from the output columns as presumed demanded.
        // If this is not the case, the caller should project some away.
        demand.extend(self.projection.iter().cloned());
        // Proceed in *reverse* order, as expressions may depend on other
        // expressions that precede them.
        for index in (0..self.expressions.len()).rev() {
            if demand.contains(&(self.input_arity + index)) {
                demand.extend(self.expressions[index].support());
            }
        }
        // Maintain a map from initial column identifiers to locations
        // once we have removed undemanded expressions.
        let mut remap = HashMap::new();
        // This map only needs to map elements of `demand` to a new location,
        // but the logic is easier if we include all input columns (as the
        // new position is then determined by the size of the map).
        for index in 0..self.input_arity {
            remap.insert(index, index);
        }
        // Retain demanded expressions, and record their new locations.
        let mut new_expressions = Vec::new();
        for (index, expr) in self.expressions.drain(..).enumerate() {
            if demand.contains(&(index + self.input_arity)) {
                remap.insert(index + self.input_arity, remap.len());
                new_expressions.push(expr);
            }
        }
        self.expressions = new_expressions;
        // Update column identifiers; rebuild `Self` to re-establish any invariants.
        // We mirror `self.permute(&remap)` but we specifically want to remap columns
        // that are produced by `self.expressions` after the input columns.
        let (expressions, predicates, projection) = self.as_map_filter_project();
        *self = Self::new(self.input_arity)
            .map(expressions.into_iter().map(|mut e| {
                e.permute_map(&remap);
                e
            }))
            .filter(predicates.into_iter().map(|mut p| {
                p.permute_map(&remap);
                p
            }))
            .project(projection.into_iter().map(|c| remap[&c]));
    }
pub fn remove_undemanded ( & mut self ) { // Determine the demanded expressions to remove irrelevant ones. let mut demand = std :: collections :: HashSet :: new ( ) ; for ( _index , pred ) in self . predicates . iter ( ) { demand . extend ( pred . support ( ) ) ; } // Start from the output columns as presumed demanded. // If this is not the case, the caller should project some away. demand . extend ( self . projection . iter ( ) . cloned ( ) ) ; // Proceed in *reverse* order, as expressions may depend on other // expressions that precede them. for index in ( 0 .. self . expressions . len ( ) ) . rev ( ) { if demand . contains ( & ( self . input_arity + index ) ) { demand . extend ( self . expressions [ index ] . support ( ) ) ; } } // Maintain a map from initial column identifiers to locations // once we have removed undemanded expressions. let mut remap = HashMap :: new ( ) ; // This map only needs to map elements of `demand` to a new location, // but the logic is easier if we include all input columns (as the // new position is then determined by the size of the map). for index in 0 .. self . input_arity { remap . insert ( index , index ) ; } // Retain demanded expressions, and record their new locations. let mut new_expressions = Vec :: new ( ) ; for ( index , expr ) in self . expressions . drain ( .. ) . enumerate ( ) { if demand . contains ( & ( index + self . input_arity ) ) { remap . insert ( index + self . input_arity , remap . len ( ) ) ; new_expressions . push ( expr ) ; } } self . expressions = new_expressions ; // Update column identifiers; rebuild `Self` to re-establish any invariants. // We mirror `self.permute(&remap)` but we specifically want to remap columns // that are produced by `self.expressions` after the input columns. let ( expressions , predicates , projection ) = self . as_map_filter_project ( ) ; * self = Self :: new ( self . input_arity ) . map ( expressions . into_iter ( ) . map ( | mut e | { e . permute_map ( & remap ) ; e } ) ) . filter ( predicates . into_iter ( ) . map ( | mut p | { p . permute_map ( & remap ) ; p } ) ) . project ( projection . into_iter ( ) . map ( | c | remap [ & c ] ) ) ; }
Removes unused expressions from `self.expressions`.
Removes unused expressions from ` self . expressions ` .
&mut self
&mut self
example
```rust
use expr::{func, MapFilterProject, MirScalarExpr, UnaryFunc, BinaryFunc};
Use the output from `inline_expression` example.
let mut map_filter_project = MapFilterProject::new(5)
.map(vec![
MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(6), BinaryFunc::AddInt64),
MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(6), BinaryFunc::AddInt64),
MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
MirScalarExpr::column(6).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
MirScalarExpr::column(6).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
])
.project(vec![3,4,8,11]).

let mut expected_optimized = MapFilterProject::new(5)
.map(vec![
MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(5), BinaryFunc::AddInt64),
MirScalarExpr::column(5).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
])
.project(vec![3,4,6,7]).

Remove undemandedd expressions, streamlining the work done
map_filter_project.remove_undemanded().


` ` ` rust use expr :: { func MapFilterProject MirScalarExpr UnaryFunc BinaryFunc } ; Use the output from ` inline_expression ` example . let mut map_filter_project = MapFilterProject :: new ( 5 ) . map ( vec! [ MirScalarExpr :: column ( 0 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) MirScalarExpr :: column ( 1 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) MirScalarExpr :: column ( 0 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) . call_binary ( MirScalarExpr :: column ( 6 ) BinaryFunc :: AddInt64 ) MirScalarExpr :: column ( 0 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) . call_binary ( MirScalarExpr :: column ( 6 ) BinaryFunc :: AddInt64 ) MirScalarExpr :: column ( 2 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) MirScalarExpr :: column ( 6 ) . call_binary ( MirScalarExpr :: column ( 2 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) BinaryFunc :: AddInt64 ) MirScalarExpr :: column ( 6 ) . call_binary ( MirScalarExpr :: column ( 2 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) BinaryFunc :: AddInt64 ) ] ) . project ( vec! [ 3 4 8 11 ] ) . let mut expected_optimized = MapFilterProject :: new ( 5 ) . map ( vec! [ MirScalarExpr :: column ( 1 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) MirScalarExpr :: column ( 0 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) . call_binary ( MirScalarExpr :: column ( 5 ) BinaryFunc :: AddInt64 ) MirScalarExpr :: column ( 5 ) . call_binary ( MirScalarExpr :: column ( 2 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) BinaryFunc :: AddInt64 ) ] ) . project ( vec! [ 3 4 6 7 ] ) . Remove undemandedd expressions streamlining the work done map_filter_project . remove_undemanded () .