pub fn plan(
        join: &MirRelationExpr,
        input_mapper: &JoinInputMapper,
        available: &[Vec<Vec<MirScalarExpr>>],
        unique_keys: &[Vec<Vec<usize>>],
    ) -> Option<MirRelationExpr> {
        let mut new_join = join.clone();

        if let MirRelationExpr::Join {
            inputs,
            equivalences,
            implementation,
        } = &mut new_join
        {
            // We prefer a starting point based on the characteristics of the other input arrangements.
            // We could change this preference at any point, but the list of orders should still inform.
            // Important, we should choose something stable under re-ordering, to converge under fixed
            // point iteration; we choose to start with the first input optimizing our criteria, which
            // should remain stable even when promoted to the first position.
            let mut orders =
                super::optimize_orders(equivalences, available, unique_keys, input_mapper);

            // For differential join, it is not as important for the starting
            // input to have good characteristics because the other ones
            // determine whether intermediate results blow up. Thus, we do not
            // include the starting input when max-minning.
            let max_min_characteristics = orders
                .iter()
                .flat_map(|order| order.iter().skip(1).map(|(c, _, _)| c.clone()).min())
                .max();
            let mut order = if let Some(max_min_characteristics) = max_min_characteristics {
                orders
                    .into_iter()
                    .find(|o| {
                        o.iter().skip(1).map(|(c, _, _)| c).min().unwrap()
                            == &max_min_characteristics
                    })?
                    .into_iter()
                    .map(|(_c, k, r)| (r, k))
                    .collect::<Vec<_>>()
            } else {
                // if max_min_characteristics is None, then there must only be
                // one input and thus only one order in orders
                orders
                    .remove(0)
                    .into_iter()
                    .map(|(_c, k, r)| (r, k))
                    .collect::<Vec<_>>()
            };

            let (start, start_keys) = &order[0];
            let start = *start;
            let start_keys = if available[start].contains(&start_keys) {
                Some(start_keys.clone())
            } else {
                // if there is not already a pre-existing arrangement
                // for the start input, do not implement one
                order.remove(0);
                None
            };

            // Implement arrangements in each of the inputs.
            let lifted_mfp = super::implement_arrangements(inputs, available, order.iter());

            if start_keys.is_some() {
                // now that the starting arrangement has been implemented,
                // remove it from `order` so `order` only contains information
                // about the other inputs
                order.remove(0);
            }

            // Install the implementation.
            *implementation = JoinImplementation::Differential((start, start_keys), order);

            super::install_lifted_mfp(&mut new_join, lifted_mfp);

            // Hooray done!
            Some(new_join)
        } else {
            panic!("differential::plan call on non-join expression.")
        }
    }
/// Creates a linear differential plan, and any predicates that need to be lifted.
Creates a linear differential plan, and any predicates that need to be lifted.
Creates a linear differential plan and any predicates that need to be lifted .
pub fn plan(
        join: &MirRelationExpr,
        input_mapper: &JoinInputMapper,
        available: &[Vec<Vec<MirScalarExpr>>],
        unique_keys: &[Vec<Vec<usize>>],
    ) -> Option<MirRelationExpr> {
        let mut new_join = join.clone();
        if let MirRelationExpr::Join {
            inputs,
            equivalences,
            implementation,
        } = &mut new_join
        {
            // We prefer a starting point based on the characteristics of the other input arrangements.
            // We could change this preference at any point, but the list of orders should still inform.
            // Important, we should choose something stable under re-ordering, to converge under fixed
            // point iteration; we choose to start with the first input optimizing our criteria, which
            // should remain stable even when promoted to the first position.
            let mut orders =
                super::optimize_orders(equivalences, available, unique_keys, input_mapper);
            // For differential join, it is not as important for the starting
            // input to have good characteristics because the other ones
            // determine whether intermediate results blow up. Thus, we do not
            // include the starting input when max-minning.
            let max_min_characteristics = orders
                .iter()
                .flat_map(|order| order.iter().skip(1).map(|(c, _, _)| c.clone()).min())
                .max();
            let mut order = if let Some(max_min_characteristics) = max_min_characteristics {
                orders
                    .into_iter()
                    .find(|o| {
                        o.iter().skip(1).map(|(c, _, _)| c).min().unwrap()
                            == &max_min_characteristics
                    })?
                    .into_iter()
                    .map(|(_c, k, r)| (r, k))
                    .collect::<Vec<_>>()
            } else {
                // if max_min_characteristics is None, then there must only be
                // one input and thus only one order in orders
                orders
                    .remove(0)
                    .into_iter()
                    .map(|(_c, k, r)| (r, k))
                    .collect::<Vec<_>>()
            };
            let (start, start_keys) = &order[0];
            let start = *start;
            let start_keys = if available[start].contains(&start_keys) {
                Some(start_keys.clone())
            } else {
                // if there is not already a pre-existing arrangement
                // for the start input, do not implement one
                order.remove(0);
                None
            };
            // Implement arrangements in each of the inputs.
            let lifted_mfp = super::implement_arrangements(inputs, available, order.iter());
            if start_keys.is_some() {
                // now that the starting arrangement has been implemented,
                // remove it from `order` so `order` only contains information
                // about the other inputs
                order.remove(0);
            }
            // Install the implementation.
            *implementation = JoinImplementation::Differential((start, start_keys), order);
            super::install_lifted_mfp(&mut new_join, lifted_mfp);
            // Hooray done!
            Some(new_join)
        } else {
            panic!("differential::plan call on non-join expression.")
        }
    }
pub fn plan ( join : & MirRelationExpr , input_mapper : & JoinInputMapper , available : & [ Vec < Vec < MirScalarExpr > > ] , unique_keys : & [ Vec < Vec < usize > > ] , ) -> Option < MirRelationExpr > { let mut new_join = join . clone ( ) ; if let MirRelationExpr :: Join { inputs , equivalences , implementation , } = & mut new_join { // We prefer a starting point based on the characteristics of the other input arrangements. // We could change this preference at any point, but the list of orders should still inform. // Important, we should choose something stable under re-ordering, to converge under fixed // point iteration; we choose to start with the first input optimizing our criteria, which // should remain stable even when promoted to the first position. let mut orders = super :: optimize_orders ( equivalences , available , unique_keys , input_mapper ) ; // For differential join, it is not as important for the starting // input to have good characteristics because the other ones // determine whether intermediate results blow up. Thus, we do not // include the starting input when max-minning. let max_min_characteristics = orders . iter ( ) . flat_map ( | order | order . iter ( ) . skip ( 1 ) . map ( | ( c , _ , _ ) | c . clone ( ) ) . min ( ) ) . max ( ) ; let mut order = if let Some ( max_min_characteristics ) = max_min_characteristics { orders . into_iter ( ) . find ( | o | { o . iter ( ) . skip ( 1 ) . map ( | ( c , _ , _ ) | c ) . min ( ) . unwrap ( ) == & max_min_characteristics } ) ? . into_iter ( ) . map ( | ( _c , k , r ) | ( r , k ) ) . collect :: < Vec < _ > > ( ) } else { // if max_min_characteristics is None, then there must only be // one input and thus only one order in orders orders . remove ( 0 ) . into_iter ( ) . map ( | ( _c , k , r ) | ( r , k ) ) . collect :: < Vec < _ > > ( ) } ; let ( start , start_keys ) = & order [ 0 ] ; let start = * start ; let start_keys = if available [ start ] . contains ( & start_keys ) { Some ( start_keys . clone ( ) ) } else { // if there is not already a pre-existing arrangement // for the start input, do not implement one order . remove ( 0 ) ; None } ; // Implement arrangements in each of the inputs. let lifted_mfp = super :: implement_arrangements ( inputs , available , order . iter ( ) ) ; if start_keys . is_some ( ) { // now that the starting arrangement has been implemented, // remove it from `order` so `order` only contains information // about the other inputs order . remove ( 0 ) ; } // Install the implementation. * implementation = JoinImplementation :: Differential ( ( start , start_keys ) , order ) ; super :: install_lifted_mfp ( & mut new_join , lifted_mfp ) ; // Hooray done! Some ( new_join ) } else { panic ! ( " " ) } }
Creates a linear differential plan, and any predicates that need to be lifted.
Creates a linear differential plan and any predicates that need to be lifted .
join
&MirRelationExpr
input_mapper
&JoinInputMapper
available
&[Vec<Vec<MirScalarExpr>>]
unique_keys
&[Vec<Vec<usize>>]
join
&MirRelationExpr
input_mapper
&JoinInputMapper
available
&[Vec<Vec<MirScalarExpr>>]
unique_keys
&[Vec<Vec<usize>>]