public void SparqlGraphPatternToAlgebra8() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsType <Graph>(algebra); Graph g = (Graph)algebra; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); // Nest in another graph pattern with different specifier GraphPattern parent = new GraphPattern(); parent.IsGraph = true; parent.GraphSpecifier = new UriToken("<http://example.org>", 0, 0, 0); parent.AddGraphPattern(gp); // Resulting algebra must nest the graph clauses algebra = parent.ToAlgebra(); Assert.IsType <Graph>(algebra); g = (Graph)algebra; Assert.Equal(parent.GraphSpecifier.Value, g.GraphSpecifier.Value); Assert.IsType <Graph>(g.InnerAlgebra); g = (Graph)g.InnerAlgebra; Assert.Equal(gp.GraphSpecifier.Value, g.GraphSpecifier.Value); Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); }
public void SparqlGraphPatternToAlgebra4() { GraphPattern up = new GraphPattern(); up.IsUnion = true; GraphPattern gp = new GraphPattern(); gp.IsService = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); up.AddGraphPattern(gp); GraphPattern empty = new GraphPattern(); up.AddGraphPattern(empty); ISparqlAlgebra algebra = up.ToAlgebra(); Assert.IsType <Union>(algebra); Union u = (Union)algebra; Assert.IsType <Service>(u.Lhs); Assert.IsAssignableFrom <IBgp>(u.Rhs); }
public void SparqlGraphPatternToAlgebra4() { GraphPattern up = new GraphPattern(); up.IsUnion = true; GraphPattern gp = new GraphPattern(); gp.IsService = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); up.AddGraphPattern(gp); GraphPattern empty = new GraphPattern(); up.AddGraphPattern(empty); ISparqlAlgebra algebra = up.ToAlgebra(); Assert.IsInstanceOf(typeof(Union), algebra); Union u = (Union)algebra; Assert.IsInstanceOf(typeof(Service), u.Lhs); Assert.IsInstanceOf(typeof(IBgp), u.Rhs); }
public void SparqlGraphPatternToAlgebra7() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsType <Graph>(algebra); Graph g = (Graph)algebra; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); // Nest in another graph pattern with same specifier GraphPattern parent = new GraphPattern(); parent.IsGraph = true; parent.GraphSpecifier = gp.GraphSpecifier; parent.AddGraphPattern(gp); // Resulting algebra will collapse the two graph clauses into a single one algebra = parent.ToAlgebra(); Assert.IsType <Graph>(algebra); g = (Graph)algebra; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); }
public void SparqlGraphPatternToAlgebra2() { GraphPattern up = new GraphPattern(); up.IsUnion = true; GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); up.AddGraphPattern(gp); GraphPattern empty = new GraphPattern(); up.AddGraphPattern(empty); ISparqlAlgebra algebra = up.ToAlgebra(); Assert.IsType(typeof(Union), algebra); Union u = (Union)algebra; Assert.IsType(typeof(Graph), u.Lhs); Graph g = (Graph)u.Lhs; Assert.IsAssignableFrom(typeof(IBgp), g.InnerAlgebra); Assert.IsAssignableFrom(typeof(IBgp), u.Rhs); }
public void SparqlGraphPatternToAlgebra3() { GraphPattern gp = new GraphPattern(); gp.IsService = true; gp.GraphSpecifier = new UriToken("<http://example.org/sparql>", 0, 0, 0); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsType <Service>(algebra); }
public void SparqlGraphPatternToAlgebra1() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsType <Graph>(algebra); Graph g = (Graph)algebra; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); }
public void SparqlGraphPatternToAlgebra1() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsInstanceOf(typeof(Graph), algebra); Graph g = (Graph)algebra; Assert.IsInstanceOf(typeof(IBgp), g.InnerAlgebra); }
public void SparqlGraphPatternToAlgebra6() { GraphPattern gp = new GraphPattern(); gp.IsService = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); gp.AddInlineData(new BindingsPattern()); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsAssignableFrom <IJoin>(algebra); IJoin join = (IJoin)algebra; Assert.IsType <Service>(join.Lhs); Assert.IsType <Bindings>(join.Rhs); }
public void SparqlGraphPatternToAlgebra6() { GraphPattern gp = new GraphPattern(); gp.IsService = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); gp.AddInlineData(new BindingsPattern()); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsInstanceOf(typeof(IJoin), algebra); IJoin join = (IJoin)algebra; Assert.IsInstanceOf(typeof(Service), join.Lhs); Assert.IsInstanceOf(typeof(Bindings), join.Rhs); }
public void SparqlGraphPatternToAlgebra5() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); gp.AddInlineData(new BindingsPattern()); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsAssignableFrom <IJoin>(algebra); IJoin join = (IJoin)algebra; Assert.IsType <Graph>(join.Lhs); Graph g = (Graph)join.Lhs; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); Assert.IsAssignableFrom <Bindings>(join.Rhs); }
public void SparqlGraphPatternToAlgebra5() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); gp.AddInlineData(new BindingsPattern()); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsInstanceOf(typeof(IJoin), algebra); IJoin join = (IJoin)algebra; Assert.IsInstanceOf(typeof(Graph), join.Lhs); Graph g = (Graph)join.Lhs; Assert.IsInstanceOf(typeof(IBgp), g.InnerAlgebra); Assert.IsInstanceOf(typeof(Bindings), join.Rhs); }
public void SparqlGraphPatternToAlgebra9() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsType <Graph>(algebra); Graph g = (Graph)algebra; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); // Nest in another graph pattern with same specifier but also with another BGP GraphPattern parent = new GraphPattern(); parent.IsGraph = true; parent.GraphSpecifier = gp.GraphSpecifier; parent.AddGraphPattern(gp); ITriplePattern tp = new TriplePattern(new VariablePattern("s"), new VariablePattern("p"), new VariablePattern("o")); parent.AddTriplePattern(tp); // Resulting algebra will keep both graph clauses because of the join algebra = parent.ToAlgebra(); Assert.IsType <Graph>(algebra); g = (Graph)algebra; Assert.IsType <Join>(g.InnerAlgebra); Join join = (Join)g.InnerAlgebra; Assert.IsType <Graph>(join.Lhs); g = (Graph)join.Lhs; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); }
/// <summary> /// Internal method which evaluates the Graph Pattern. /// </summary> /// <param name="origContext">Evaluation Context.</param> /// <remarks> /// We only ever need to evaluate the Graph Pattern once to get the Results. /// </remarks> private void EvaluateInternal(SparqlEvaluationContext origContext) { _result = null; // We must take a copy of the original context as otherwise we can have strange results SparqlEvaluationContext context = new SparqlEvaluationContext(origContext.Query, origContext.Data); context.InputMultiset = origContext.InputMultiset; context.OutputMultiset = new Multiset(); _lastInput = context.InputMultiset.GetHashCode(); _lastCount = context.InputMultiset.Count; // REQ: Optimise the algebra here ISparqlAlgebra existsClause = _pattern.ToAlgebra(); _result = context.Evaluate(existsClause); // This is the new algorithm which is also correct but is O(3n) so much faster and scalable // Downside is that it does require more memory than the old algorithm _joinVars = origContext.InputMultiset.Variables.Where(v => _result.Variables.Contains(v)).ToList(); if (_joinVars.Count == 0) { return; } List <MultiDictionary <INode, List <int> > > values = new List <MultiDictionary <INode, List <int> > >(); List <List <int> > nulls = new List <List <int> >(); foreach (System.String var in _joinVars) { values.Add(new MultiDictionary <INode, List <int> >(new FastVirtualNodeComparer())); nulls.Add(new List <int>()); } // First do a pass over the LHS Result to find all possible values for joined variables foreach (ISet x in origContext.InputMultiset.Sets) { int i = 0; foreach (System.String var in _joinVars) { INode value = x[var]; if (value != null) { List <int> ids; if (values[i].TryGetValue(value, out ids)) { ids.Add(x.ID); } else { values[i].Add(value, new List <int> { x.ID }); } } else { nulls[i].Add(x.ID); } i++; } } // Then do a pass over the RHS and work out the intersections _exists = new HashSet <int>(); foreach (ISet y in _result.Sets) { IEnumerable <int> possMatches = null; int i = 0; foreach (System.String var in _joinVars) { INode value = y[var]; if (value != null) { if (values[i].ContainsKey(value)) { possMatches = (possMatches == null ? values[i][value].Concat(nulls[i]) : possMatches.Intersect(values[i][value].Concat(nulls[i]))); } else { possMatches = Enumerable.Empty <int>(); break; } } else { // Don't forget that a null will be potentially compatible with everything possMatches = (possMatches == null ? origContext.InputMultiset.SetIDs : possMatches.Intersect(origContext.InputMultiset.SetIDs)); } i++; } if (possMatches == null) { continue; } // Look at possible matches, if is a valid match then mark the set as having an existing match // Don't reconsider sets which have already been marked as having an existing match foreach (int poss in possMatches) { if (_exists.Contains(poss)) { continue; } if (origContext.InputMultiset[poss].IsCompatibleWith(y, _joinVars)) { _exists.Add(poss); } } } }