Adds dumb join reordering

pull/10/head
Tpt 5 years ago
parent 17abe2d1ab
commit 9339e1063e
  1. 16
      lib/src/sparql/algebra.rs
  2. 62
      lib/src/sparql/plan_builder.rs

@ -194,6 +194,22 @@ pub enum TripleOrPathPattern {
Path(PathPattern),
}
impl TripleOrPathPattern {
pub(crate) fn subject(&self) -> &TermOrVariable {
match self {
TripleOrPathPattern::Triple(t) => &t.subject,
TripleOrPathPattern::Path(t) => &t.subject,
}
}
pub(crate) fn object(&self) -> &TermOrVariable {
match self {
TripleOrPathPattern::Triple(t) => &t.object,
TripleOrPathPattern::Path(t) => &t.object,
}
}
}
impl<'a> fmt::Display for TripleOrPathPattern {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {

@ -7,6 +7,7 @@ use crate::store::numeric_encoder::ENCODED_DEFAULT_GRAPH;
use crate::store::StoreConnection;
use crate::Result;
use failure::format_err;
use std::collections::HashSet;
pub struct PlanBuilder<'a, S: StoreConnection> {
store: &'a S,
@ -180,7 +181,7 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
graph_name: PatternValue,
) -> Result<PlanNode> {
let mut plan = input;
for pattern in p {
for pattern in sort_bgp(p) {
plan = match pattern {
TripleOrPathPattern::Triple(pattern) => PlanNode::QuadPatternJoin {
child: Box::new(plan),
@ -581,3 +582,62 @@ fn slice_key<T: Eq>(slice: &[T], element: &T) -> Option<usize> {
}
None
}
fn sort_bgp(p: &[TripleOrPathPattern]) -> Vec<&TripleOrPathPattern> {
let mut assigned_variables = HashSet::default();
let mut new_p: Vec<_> = p.iter().collect();
for i in 0..new_p.len() {
(&mut new_p[i..]).sort_by(|p1, p2| {
count_pattern_binds(p2, &assigned_variables)
.cmp(&count_pattern_binds(p1, &assigned_variables))
});
add_pattern_variables(new_p[i], &mut assigned_variables);
}
new_p
}
fn count_pattern_binds(
pattern: &TripleOrPathPattern,
assigned_variables: &HashSet<&Variable>,
) -> u8 {
let mut count = 3;
if let TermOrVariable::Variable(v) = pattern.subject() {
if !assigned_variables.contains(v) {
count -= 1;
}
}
if let TripleOrPathPattern::Triple(t) = pattern {
if let NamedNodeOrVariable::Variable(v) = &t.predicate {
if !assigned_variables.contains(v) {
count -= 1;
}
}
} else {
count -= 1;
}
if let TermOrVariable::Variable(v) = pattern.object() {
if !assigned_variables.contains(v) {
count -= 1;
}
}
count
}
fn add_pattern_variables<'a>(
pattern: &'a TripleOrPathPattern,
variables: &mut HashSet<&'a Variable>,
) {
if let TermOrVariable::Variable(v) = pattern.subject() {
variables.insert(v);
}
if let TripleOrPathPattern::Triple(t) = pattern {
if let NamedNodeOrVariable::Variable(v) = &t.predicate {
variables.insert(v);
}
}
if let TermOrVariable::Variable(v) = pattern.object() {
variables.insert(v);
}
}

Loading…
Cancel
Save