/// Generate the initial scans to implement the query.
///
/// For some statements, multiple index scans would be a valid way to
/// implement the statement. In that case, we always choose the first one.
/// Later calls to `next` can cycle through them to explore all possible
/// plans.
Generate the initial scans to implement the query.
For some statements, multiple index scans would be a valid way to
implement the statement. In that case, we always choose the first one.
Later calls to `next` can cycle through them to explore all possible
plans.
Generate the initial scans to implement the query . For some statements multiple index scans would be a valid way to implement the statement . In that case we always choose the first one . Later calls to ` next ` can cycle through them to explore all possible plans .
pub fn initialize_scans(&mut self) {
        // If there was a previous plan, clear its scans, because we are going
        // to initialize them with new scans.
        self.plan.scans.clear();
        // Track which slots are already defined (those we can read from), and
        // which slots still need to be initialized (those we need to plan).
        let mut slot_initialized = Vec::with_capacity(self.plan.slots.len());
        // Constants are initialized at the start, before any scans.
        for slot_def in &self.plan.slots {
            match slot_def {
                SlotDefinition::Variable { .. } => slot_initialized.push(false),
                SlotDefinition::Constant { .. } => slot_initialized.push(true),
            }
        }
        // Then we can plan a scan for every statement.
        for &(slot_entity, attribute, slot_value) in &self.statements {
            let is_entity_init = slot_initialized[slot_entity.0 as usize];
            let is_value_init = slot_initialized[slot_value.0 as usize];
            // Depending on what slots are initialized already, various index-
            // flow combinations can be used to fill the remaining slots. When
            // there are multiple indexes that could fill the slot, we pick the
            // first one, and later on, iterating plans will explore alternatives.
            let (index, flow) = match (is_entity_init, is_value_init) {
                (true, true) => (Index::Aevt, Flow::InIn),
                (false, true) => (Index::Avet, Flow::InOut),
                (true, false) => (Index::Aevt, Flow::InOut),
                (false, false) => (Index::Aevt, Flow::OutOut),
            };
            let scan = Scan {
                index: index,
                flow: flow,
                entity: slot_entity,
                attribute: attribute,
                value: slot_value,
            };
            self.plan.scans.push(scan);
            // The scan will initialize any uninitialized slots it references.
            slot_initialized[slot_entity.0 as usize] = true;
            slot_initialized[slot_value.0 as usize] = true;
        }
    }
pub fn initialize_scans ( & mut self ) { // If there was a previous plan, clear its scans, because we are going // to initialize them with new scans. self . plan . scans . clear ( ) ; // Track which slots are already defined (those we can read from), and // which slots still need to be initialized (those we need to plan). let mut slot_initialized = Vec :: with_capacity ( self . plan . slots . len ( ) ) ; // Constants are initialized at the start, before any scans. for slot_def in & self . plan . slots { match slot_def { SlotDefinition :: Variable { .. } => slot_initialized . push ( false ) , SlotDefinition :: Constant { .. } => slot_initialized . push ( true ) , } } // Then we can plan a scan for every statement. for & ( slot_entity , attribute , slot_value ) in & self . statements { let is_entity_init = slot_initialized [ slot_entity . 0 as usize ] ; let is_value_init = slot_initialized [ slot_value . 0 as usize ] ; // Depending on what slots are initialized already, various index- // flow combinations can be used to fill the remaining slots. When // there are multiple indexes that could fill the slot, we pick the // first one, and later on, iterating plans will explore alternatives. let ( index , flow ) = match ( is_entity_init , is_value_init ) { ( true , true ) => ( Index :: Aevt , Flow :: InIn ) , ( false , true ) => ( Index :: Avet , Flow :: InOut ) , ( true , false ) => ( Index :: Aevt , Flow :: InOut ) , ( false , false ) => ( Index :: Aevt , Flow :: OutOut ) , } ; let scan = Scan { index : index , flow : flow , entity : slot_entity , attribute : attribute , value : slot_value , } ; self . plan . scans . push ( scan ) ; // The scan will initialize any uninitialized slots it references. slot_initialized [ slot_entity . 0 as usize ] = true ; slot_initialized [ slot_value . 0 as usize ] = true ; } }
Generate the initial scans to implement the query.
Generate the initial scans to implement the query .
&mut self