pub fn new_rule(&mut self, rule: &Rule) -> Result<()> {
        trace!("Registering rule: {:?}", rule);
        let signal = Signal::new();
        let trigger = signal.clone();
        let profile = Rc::new(RefCell::new(RuleProfile::new(rule.name.clone())));
        self.rule_profiles.push(profile.clone());
        self.signals.push(signal.clone());

        for pred in &rule.body {
            let dep_rules = self.get_dep_rules(&pred.pred_name);
            dep_rules.borrow_mut().push(signal.clone());
        }

        let rule_future = {
            let mut next_fact_id = None;
            let fdb = self.fact_db.clone();
            let funcs = self.funcs.clone();
            let buddies = self.get_dep_rules(&rule.head.pred_name);
            let rule = rule.clone();
            let out_signal = signal.clone();
            let start_time = self.start_time.clone();
            let limiter = self.limiter.clone();
            signal.for_each(move |_| {
                let rule_start = Instant::now();
                match (start_time.elapsed(), limiter) {
                    (run_time, Some(limit_time)) if run_time > limit_time => return out_signal.stop(),
                    _ => ()
                }
                trace!("Activating rule: {:?}", rule.name);
                let mut productive: usize = 0;
                    let pre_db = Instant::now();
                    let states_0 = fdb.search_facts(&rule.body, next_fact_id).chain_err(|| format!("Search from {}", rule.name)).unwrap();
                    let sql_time = pre_db.elapsed();
                    profile.borrow_mut().add_select_time(sql_time);
                    next_fact_id = states_0.iter().flat_map(|x| x.0.iter()).max().map(|x| x + 1).or(next_fact_id);
                let results = states_0.len();
                    trace!("Query submitted");
                    let mut states: Box<
                        Iterator<
                            Item = (Vec<FactId>,
                                    Vec<Value>),
                        >,
                    > = Box::new(states_0.into_iter());
                    let where_start = Instant::now();
                    for where_clause in rule.wheres.iter() {
                        let wc = where_clause.clone();
                        let bf = &funcs;
                        let next_states = states.flat_map(move |state| {
                            let resp = eval(&wc.rhs, &state.1, bf);
                            let out: Vec<_> = bind(&wc.lhs, resp, &state.1)
                                .into_iter()
                                .map(|x| (state.0.clone(), x))
                                .collect();
                            out
                        });
                        states = Box::new(next_states);
                    }
                    let facts: Vec<Fact> = states.map(|state| substitute(&rule.head, &state.1)).collect();
                    let compute_time = where_start.elapsed();
                    profile.borrow_mut().add_compute_time(compute_time);
                    trace!("Insertions beginning");
                    let insert_start = Instant::now();
                    for fact in facts {
                        if fdb.insert_fact(&fact)
                            .unwrap()
                            .is_some()
                        {
                            productive += 1;
                        }
                    }
                    let insert_time = insert_start.elapsed();
                    profile.borrow_mut().add_insert_time(insert_time);
                    trace!("Insertions done");
                trace!(
                    "Generated {} results, turned into {} facts.",
                    results,
                    productive
                );

                if productive > 0 {
                    for buddy in buddies.borrow().iter() {
                        buddy.signal();
                    }
                }

                let rule_elapsed = rule_start.elapsed();
                profile.borrow_mut().add_rule_time(rule_elapsed);
                out_signal.done()
            })
        };

        self.event_loop.spawn(rule_future);
        trigger.signal();
        Ok(())
    }
/// Register a new rule with the database
Register a new rule with the database
Register a new rule with the database
pub fn new_rule(&mut self, rule: &Rule) -> Result<()> {
        trace!("Registering rule: {:?}", rule);
        let signal = Signal::new();
        let trigger = signal.clone();
        let profile = Rc::new(RefCell::new(RuleProfile::new(rule.name.clone())));
        self.rule_profiles.push(profile.clone());
        self.signals.push(signal.clone());
        for pred in &rule.body {
            let dep_rules = self.get_dep_rules(&pred.pred_name);
            dep_rules.borrow_mut().push(signal.clone());
        }
        let rule_future = {
            let mut next_fact_id = None;
            let fdb = self.fact_db.clone();
            let funcs = self.funcs.clone();
            let buddies = self.get_dep_rules(&rule.head.pred_name);
            let rule = rule.clone();
            let out_signal = signal.clone();
            let start_time = self.start_time.clone();
            let limiter = self.limiter.clone();
            signal.for_each(move |_| {
                let rule_start = Instant::now();
                match (start_time.elapsed(), limiter) {
                    (run_time, Some(limit_time)) if run_time > limit_time => return out_signal.stop(),
                    _ => ()
                }
                trace!("Activating rule: {:?}", rule.name);
                let mut productive: usize = 0;
                    let pre_db = Instant::now();
                    let states_0 = fdb.search_facts(&rule.body, next_fact_id).chain_err(|| format!("Search from {}", rule.name)).unwrap();
                    let sql_time = pre_db.elapsed();
                    profile.borrow_mut().add_select_time(sql_time);
                    next_fact_id = states_0.iter().flat_map(|x| x.0.iter()).max().map(|x| x + 1).or(next_fact_id);
                let results = states_0.len();
                    trace!("Query submitted");
                    let mut states: Box<
                        Iterator<
                            Item = (Vec<FactId>,
                                    Vec<Value>),
                        >,
                    > = Box::new(states_0.into_iter());
                    let where_start = Instant::now();
                    for where_clause in rule.wheres.iter() {
                        let wc = where_clause.clone();
                        let bf = &funcs;
                        let next_states = states.flat_map(move |state| {
                            let resp = eval(&wc.rhs, &state.1, bf);
                            let out: Vec<_> = bind(&wc.lhs, resp, &state.1)
                                .into_iter()
                                .map(|x| (state.0.clone(), x))
                                .collect();
                            out
                        });
                        states = Box::new(next_states);
                    }
                    let facts: Vec<Fact> = states.map(|state| substitute(&rule.head, &state.1)).collect();
                    let compute_time = where_start.elapsed();
                    profile.borrow_mut().add_compute_time(compute_time);
                    trace!("Insertions beginning");
                    let insert_start = Instant::now();
                    for fact in facts {
                        if fdb.insert_fact(&fact)
                            .unwrap()
                            .is_some()
                        {
                            productive += 1;
                        }
                    }
                    let insert_time = insert_start.elapsed();
                    profile.borrow_mut().add_insert_time(insert_time);
                    trace!("Insertions done");
                trace!(
                    "Generated {} results, turned into {} facts.",
                    results,
                    productive
                );
                if productive > 0 {
                    for buddy in buddies.borrow().iter() {
                        buddy.signal();
                    }
                }
                let rule_elapsed = rule_start.elapsed();
                profile.borrow_mut().add_rule_time(rule_elapsed);
                out_signal.done()
            })
        };
        self.event_loop.spawn(rule_future);
        trigger.signal();
        Ok(())
    }
pub fn new_rule ( & mut self , rule : & Rule ) -> Result < ( ) > { trace ! ( " " rule ) ; let signal = Signal :: new ( ) ; let trigger = signal . clone ( ) ; let profile = Rc :: new ( RefCell :: new ( RuleProfile :: new ( rule . name . clone ( ) ) ) ) ; self . rule_profiles . push ( profile . clone ( ) ) ; self . signals . push ( signal . clone ( ) ) ; for pred in & rule . body { let dep_rules = self . get_dep_rules ( & pred . pred_name ) ; dep_rules . borrow_mut ( ) . push ( signal . clone ( ) ) ; } let rule_future = { let mut next_fact_id = None ; let fdb = self . fact_db . clone ( ) ; let funcs = self . funcs . clone ( ) ; let buddies = self . get_dep_rules ( & rule . head . pred_name ) ; let rule = rule . clone ( ) ; let out_signal = signal . clone ( ) ; let start_time = self . start_time . clone ( ) ; let limiter = self . limiter . clone ( ) ; signal . for_each ( move | _ | { let rule_start = Instant :: now ( ) ; match ( start_time . elapsed ( ) , limiter ) { ( run_time , Some ( limit_time ) ) if run_time > limit_time => return out_signal . stop ( ) , _ => ( ) } trace ! ( " " rule name ) ; let mut productive : usize = 0 ; let pre_db = Instant :: now ( ) ; let states_0 = fdb . search_facts ( & rule . body , next_fact_id ) . chain_err ( | | format ! ( " " rule name ) ) . unwrap ( ) ; let sql_time = pre_db . elapsed ( ) ; profile . borrow_mut ( ) . add_select_time ( sql_time ) ; next_fact_id = states_0 . iter ( ) . flat_map ( | x | x . 0 . iter ( ) ) . max ( ) . map ( | x | x + 1 ) . or ( next_fact_id ) ; let results = states_0 . len ( ) ; trace ! ( " " ) ; let mut states : Box < Iterator < Item = ( Vec < FactId > , Vec < Value > ) , > , > = Box :: new ( states_0 . into_iter ( ) ) ; let where_start = Instant :: now ( ) ; for where_clause in rule . wheres . iter ( ) { let wc = where_clause . clone ( ) ; let bf = & funcs ; let next_states = states . flat_map ( move | state | { let resp = eval ( & wc . rhs , & state . 1 , bf ) ; let out : Vec < _ > = bind ( & wc . lhs , resp , & state . 1 ) . into_iter ( ) . map ( | x | ( state . 0 . clone ( ) , x ) ) . collect ( ) ; out } ) ; states = Box :: new ( next_states ) ; } let facts : Vec < Fact > = states . map ( | state | substitute ( & rule . head , & state . 1 ) ) . collect ( ) ; let compute_time = where_start . elapsed ( ) ; profile . borrow_mut ( ) . add_compute_time ( compute_time ) ; trace ! ( " " ) ; let insert_start = Instant :: now ( ) ; for fact in facts { if fdb . insert_fact ( & fact ) . unwrap ( ) . is_some ( ) { productive += 1 ; } } let insert_time = insert_start . elapsed ( ) ; profile . borrow_mut ( ) . add_insert_time ( insert_time ) ; trace ! ( " " ) ; trace ! ( " " results productive ) ; if productive > 0 { for buddy in buddies . borrow ( ) . iter ( ) { buddy . signal ( ) ; } } let rule_elapsed = rule_start . elapsed ( ) ; profile . borrow_mut ( ) . add_rule_time ( rule_elapsed ) ; out_signal . done ( ) } ) } ; self . event_loop . spawn ( rule_future ) ; trigger . signal ( ) ; Ok ( ( ) ) }
Register a new rule with the database
Register a new rule with the database
&mut self
rule
&Rule
&mut self
rule
&Rule