solverforge-scoring 0.19.12

Incremental constraint scoring for SolverForge
Documentation
use super::{CompileCondition, ExecutablePlan, IndexedPlan, PlannedCondition, Strategy};
use crate::stream::joiner::AndJoiner;
use crate::stream::relational::RowHandle;
use std::borrow::Cow;

impl<A, B> CompileCondition for AndJoiner<A, B>
where
    A: CompileCondition,
    B: CompileCondition,
    A::Plan: IndexedPlan,
    B::Plan: IndexedPlan,
    (
        <A::Plan as IndexedPlan>::Kind,
        <B::Plan as IndexedPlan>::Kind,
    ): super::ComposePlans<A::Plan, B::Plan>,
{
    type Plan = <(
        <A::Plan as IndexedPlan>::Kind,
        <B::Plan as IndexedPlan>::Kind,
    ) as super::ComposePlans<A::Plan, B::Plan>>::Plan;
    fn compile(self) -> Self::Plan {
        <(
            <A::Plan as IndexedPlan>::Kind,
            <B::Plan as IndexedPlan>::Kind,
        ) as super::ComposePlans<A::Plan, B::Plan>>::compose(
            self.first.compile(),
            self.second.compile(),
        )
    }
}
impl<A: IndexedPlan, B: IndexedPlan> IndexedPlan for AndJoiner<A, B> {
    type Kind = super::ResidualKind;
    type Indexes = (A::Indexes, B::Indexes);
    fn new_indexes(&self) -> Self::Indexes {
        (self.first.new_indexes(), self.second.new_indexes())
    }
    fn remove_left(&self, i: &mut Self::Indexes, h: RowHandle) {
        self.first.remove_left(&mut i.0, h);
        self.second.remove_left(&mut i.1, h);
    }
    fn remove_right(&self, i: &mut Self::Indexes, h: RowHandle) {
        self.first.remove_right(&mut i.0, h);
        self.second.remove_right(&mut i.1, h);
    }
}
impl<L, R, A, B> ExecutablePlan<L, R> for AndJoiner<A, B>
where
    A: ExecutablePlan<L, R> + PlannedCondition<L, R>,
    B: ExecutablePlan<L, R> + PlannedCondition<L, R>,
{
    fn insert_left(&self, i: &mut Self::Indexes, h: RowHandle, row: &L) {
        self.first.insert_left(&mut i.0, h, row);
        self.second.insert_left(&mut i.1, h, row);
    }
    fn insert_right(&self, i: &mut Self::Indexes, h: RowHandle, row: &R) {
        self.first.insert_right(&mut i.0, h, row);
        self.second.insert_right(&mut i.1, h, row);
    }
    fn insert_right_transient(&self, i: &mut Self::Indexes, h: RowHandle, row: &R) {
        self.first.insert_right_transient(&mut i.0, h, row);
        self.second.insert_right_transient(&mut i.1, h, row);
    }
    fn right_candidates<'i>(&self, i: &'i Self::Indexes, row: &L) -> Cow<'i, [RowHandle]> {
        if A::STRATEGY == Strategy::Scan && B::STRATEGY != Strategy::Scan {
            return self.second.right_candidates(&i.1, row);
        }
        let first = self.first.right_candidates(&i.0, row);
        if B::STRATEGY == Strategy::Scan {
            return first;
        }
        Cow::Owned(intersect(
            first.into_owned(),
            self.second.right_candidates(&i.1, row).into_owned(),
        ))
    }
    fn left_candidates<'i>(&self, i: &'i Self::Indexes, row: &R) -> Cow<'i, [RowHandle]> {
        if A::STRATEGY == Strategy::Scan && B::STRATEGY != Strategy::Scan {
            return self.second.left_candidates(&i.1, row);
        }
        let first = self.first.left_candidates(&i.0, row);
        if B::STRATEGY == Strategy::Scan {
            return first;
        }
        Cow::Owned(intersect(
            first.into_owned(),
            self.second.left_candidates(&i.1, row).into_owned(),
        ))
    }
}
fn intersect(mut left: Vec<RowHandle>, mut right: Vec<RowHandle>) -> Vec<RowHandle> {
    right.sort_unstable();
    left.retain(|h| right.binary_search(h).is_ok());
    left
}