Avoids to clone query plan during evaluation

pull/10/head
Tpt 6 years ago
parent bd5c737334
commit a15e8548f3
  1. 52
      lib/src/sparql/eval.rs

@ -42,19 +42,19 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
pub fn evaluate_select_plan<'a>( pub fn evaluate_select_plan<'a>(
&'a self, &'a self,
plan: &PlanNode, plan: &'a PlanNode,
variables: &[Variable], variables: &[Variable],
) -> Result<QueryResult<'a>> { ) -> Result<QueryResult<'a>> {
let iter = self.eval_plan(plan.clone(), vec![None; variables.len()]); let iter = self.eval_plan(plan, vec![None; variables.len()]);
Ok(QueryResult::Bindings( Ok(QueryResult::Bindings(
self.decode_bindings(iter, variables.to_vec()), self.decode_bindings(iter, variables.to_vec()),
)) ))
} }
fn eval_plan<'a>(&self, node: PlanNode, from: EncodedTuple) -> EncodedTuplesIterator<'a> { fn eval_plan<'a>(&self, node: &'a PlanNode, from: EncodedTuple) -> EncodedTuplesIterator<'a> {
match node { match node {
PlanNode::Init => Box::new(once(Ok(from))), PlanNode::Init => Box::new(once(Ok(from))),
PlanNode::StaticBindings { tuples } => Box::new(tuples.into_iter().map(Ok)), PlanNode::StaticBindings { tuples } => Box::new(tuples.iter().cloned().map(Ok)),
PlanNode::QuadPatternJoin { PlanNode::QuadPatternJoin {
child, child,
subject, subject,
@ -64,7 +64,7 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
} => { } => {
let eval = self.clone(); let eval = self.clone();
Box::new( Box::new(
self.eval_plan(*child, from) self.eval_plan(&*child, from)
.flat_map(move |tuple| match tuple { .flat_map(move |tuple| match tuple {
Ok(tuple) => { Ok(tuple) => {
let iter: EncodedTuplesIterator = match eval let iter: EncodedTuplesIterator = match eval
@ -147,7 +147,7 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
} }
PlanNode::Join { left, right } => { PlanNode::Join { left, right } => {
//TODO: very dumb implementation //TODO: very dumb implementation
let left_iter = self.eval_plan(*left, from.clone()); let left_iter = self.eval_plan(&*left, from.clone());
let mut left_values = Vec::with_capacity(left_iter.size_hint().0); let mut left_values = Vec::with_capacity(left_iter.size_hint().0);
let mut errors = Vec::default(); let mut errors = Vec::default();
for result in left_iter { for result in left_iter {
@ -160,7 +160,7 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
} }
Box::new(JoinIterator { Box::new(JoinIterator {
left: left_values, left: left_values,
right_iter: self.eval_plan(*right, from), right_iter: self.eval_plan(&*right, from),
buffered_results: errors, buffered_results: errors,
}) })
} }
@ -174,8 +174,8 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
unbind_variables(&mut filtered_from, &problem_vars); unbind_variables(&mut filtered_from, &problem_vars);
let iter = LeftJoinIterator { let iter = LeftJoinIterator {
eval: self.clone(), eval: self.clone(),
right_plan: *right, right_plan: &*right,
left_iter: self.eval_plan(*left, filtered_from), left_iter: self.eval_plan(&*left, filtered_from),
current_right_iter: None, current_right_iter: None,
}; };
if problem_vars.is_empty() { if problem_vars.is_empty() {
@ -190,7 +190,7 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
} }
PlanNode::Filter { child, expression } => { PlanNode::Filter { child, expression } => {
let eval = self.clone(); let eval = self.clone();
Box::new(self.eval_plan(*child, from).filter(move |tuple| { Box::new(self.eval_plan(&*child, from).filter(move |tuple| {
match tuple { match tuple {
Ok(tuple) => eval Ok(tuple) => eval
.eval_expression(&expression, tuple) .eval_expression(&expression, tuple)
@ -202,8 +202,8 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
} }
PlanNode::Union { entry, children } => Box::new(UnionIterator { PlanNode::Union { entry, children } => Box::new(UnionIterator {
eval: self.clone(), eval: self.clone(),
children_plan: children, children_plan: &children,
input_iter: self.eval_plan(*entry, from), input_iter: self.eval_plan(&*entry, from),
current_iters: Vec::default(), current_iters: Vec::default(),
}), }),
PlanNode::Extend { PlanNode::Extend {
@ -213,11 +213,11 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
} => { } => {
let eval = self.clone(); let eval = self.clone();
Box::new( Box::new(
self.eval_plan(*child, from) self.eval_plan(&*child, from)
.filter_map(move |tuple| match tuple { .filter_map(move |tuple| match tuple {
Ok(mut tuple) => { Ok(mut tuple) => {
put_value( put_value(
position, *position,
eval.eval_expression(&expression, &tuple)?, eval.eval_expression(&expression, &tuple)?,
&mut tuple, &mut tuple,
); );
@ -228,7 +228,7 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
) )
} }
PlanNode::HashDeduplicate { child } => { PlanNode::HashDeduplicate { child } => {
let iter = self.eval_plan(*child, from); let iter = self.eval_plan(&*child, from);
let mut values = HashSet::with_capacity(iter.size_hint().0); let mut values = HashSet::with_capacity(iter.size_hint().0);
let mut errors = Vec::default(); let mut errors = Vec::default();
for result in iter { for result in iter {
@ -241,13 +241,15 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
} }
Box::new(errors.into_iter().chain(values.into_iter().map(Ok))) Box::new(errors.into_iter().chain(values.into_iter().map(Ok)))
} }
PlanNode::Skip { child, count } => Box::new(self.eval_plan(*child, from).skip(count)), PlanNode::Skip { child, count } => Box::new(self.eval_plan(&*child, from).skip(*count)),
PlanNode::Limit { child, count } => Box::new(self.eval_plan(*child, from).take(count)), PlanNode::Limit { child, count } => {
Box::new(self.eval_plan(&*child, from).take(*count))
}
PlanNode::Project { child, mapping } => { PlanNode::Project { child, mapping } => {
Box::new(self.eval_plan(*child, from).map(move |tuple| { Box::new(self.eval_plan(&*child, from).map(move |tuple| {
let tuple = tuple?; let tuple = tuple?;
let mut new_tuple = Vec::with_capacity(mapping.len()); let mut new_tuple = Vec::with_capacity(mapping.len());
for key in &mapping { for key in mapping {
new_tuple.push(tuple[*key]); new_tuple.push(tuple[*key]);
} }
Ok(new_tuple) Ok(new_tuple)
@ -835,7 +837,7 @@ impl<'a> Iterator for JoinIterator<'a> {
struct LeftJoinIterator<'a, S: EncodedQuadsStore> { struct LeftJoinIterator<'a, S: EncodedQuadsStore> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
right_plan: PlanNode, right_plan: &'a PlanNode,
left_iter: EncodedTuplesIterator<'a>, left_iter: EncodedTuplesIterator<'a>,
current_right_iter: Option<EncodedTuplesIterator<'a>>, current_right_iter: Option<EncodedTuplesIterator<'a>>,
} }
@ -851,9 +853,7 @@ impl<'a, S: EncodedQuadsStore> Iterator for LeftJoinIterator<'a, S> {
} }
match self.left_iter.next()? { match self.left_iter.next()? {
Ok(left_tuple) => { Ok(left_tuple) => {
let mut right_iter = self let mut right_iter = self.eval.eval_plan(self.right_plan, left_tuple.clone());
.eval
.eval_plan(self.right_plan.clone(), left_tuple.clone());
match right_iter.next() { match right_iter.next() {
Some(right_tuple) => { Some(right_tuple) => {
self.current_right_iter = Some(right_iter); self.current_right_iter = Some(right_iter);
@ -905,7 +905,7 @@ impl<'a, S: EncodedQuadsStore> Iterator for BadLeftJoinIterator<'a, S> {
struct UnionIterator<'a, S: EncodedQuadsStore> { struct UnionIterator<'a, S: EncodedQuadsStore> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
children_plan: Vec<PlanNode>, children_plan: &'a Vec<PlanNode>,
input_iter: EncodedTuplesIterator<'a>, input_iter: EncodedTuplesIterator<'a>,
current_iters: Vec<EncodedTuplesIterator<'a>>, current_iters: Vec<EncodedTuplesIterator<'a>>,
} }
@ -922,9 +922,9 @@ impl<'a, S: EncodedQuadsStore> Iterator for UnionIterator<'a, S> {
} }
match self.input_iter.next()? { match self.input_iter.next()? {
Ok(input_tuple) => { Ok(input_tuple) => {
for plan in &self.children_plan { for plan in self.children_plan {
self.current_iters self.current_iters
.push(self.eval.eval_plan(plan.clone(), input_tuple.clone())); .push(self.eval.eval_plan(plan, input_tuple.clone()));
} }
} }
Err(error) => return Some(Err(error)), Err(error) => return Some(Err(error)),

Loading…
Cancel
Save