예제 #1
0
        /// <summary>
        /// Optimises an Algebra to a form that uses <see cref="LazyBgp">LazyBgp</see> where possible
        /// </summary>
        /// <param name="algebra">Algebra</param>
        /// <param name="depth">Depth</param>
        /// <returns></returns>
        /// <remarks>
        /// <para>
        /// By transforming a query to use <see cref="LazyBgp">LazyBgp</see> we can achieve much more efficient processing of some forms of queries
        /// </para>
        /// </remarks>
        protected override ISparqlAlgebra OptimiseInternal(ISparqlAlgebra algebra, int depth)
        {
            try
            {
                ISparqlAlgebra temp;

                //Note this first test is specifically for the default BGP implementation since other optimisers
                //may run before us and replace with other BGP implementations which we don't want to replace hence
                //why we don't check for IBgp here
                if (algebra is Bgp)
                {
                    temp = new LazyBgp(((Bgp)algebra).TriplePatterns);
                }
                //else if (algebra is ILeftJoin)
                //{
                //    ILeftJoin join = (ILeftJoin)algebra;
                //    temp = new LeftJoin(this.OptimiseInternal(join.Lhs, depth + 1), join.Rhs, ((LeftJoin)algebra).Filter);
                //}
                else if (algebra is IUnion)
                {
                    IUnion join = (IUnion)algebra;
                    temp = new LazyUnion(this.OptimiseInternal(join.Lhs, depth + 1), this.OptimiseInternal(join.Rhs, depth + 1));
                }
                else if (algebra is IJoin)
                {
                    IJoin join = (IJoin)algebra;
                    if (join.Lhs.Variables.IsDisjoint(join.Rhs.Variables))
                    {
                        //If the sides of the Join are disjoint then can fully transform the join since we only need to find the requisite number of
                        //solutions on either side to guarantee a product which meets/exceeds the required results
                        //temp = new Join(this.OptimiseInternal(join.Lhs, depth + 1), this.OptimiseInternal(join.Rhs, depth + 1));
                        temp = join.Transform(this);
                    }
                    else
                    {
                        //If the sides are not disjoint then the LHS must be fully evaluated but the RHS need only produce enough
                        //solutions that match
                        //temp = new Join(join.Lhs, this.OptimiseInternal(join.Rhs, depth + 1));
                        temp = join.TransformRhs(this);
                    }
                }
                else if (algebra is Algebra.Graph)
                {
                    //Algebra.Graph g = (Algebra.Graph)algebra;
                    //temp = new Algebra.Graph(this.OptimiseInternal(g.InnerAlgebra, depth + 1), g.GraphSpecifier);
                    IUnaryOperator op = (IUnaryOperator)algebra;
                    temp = op.Transform(this);
                }
                else
                {
                    temp = algebra;
                }
                return(temp);
            }
            catch
            {
                //If the Optimise fails return the current algebra
                return(algebra);
            }
        }
예제 #2
0
 /// <summary>
 /// Optimises an Algebra to a form that uses <see cref="AskBgp">AskBgp</see> where possible
 /// </summary>
 /// <param name="algebra">Algebra</param>
 /// <param name="depth">Depth</param>
 /// <returns></returns>
 /// <remarks>
 /// <para>
 /// By transforming a query to use <see cref="AskBgp">AskBgp</see> we can achieve much more efficient processing of some forms of queries
 /// </para>
 /// </remarks>
 protected override ISparqlAlgebra OptimiseInternal(ISparqlAlgebra algebra, int depth)
 {
     try
     {
         ISparqlAlgebra temp;
         if (algebra is Bgp)
         {
             //Bgp is transformed into AskBgp
             //This tries to find 1 possible solution
             temp = new AskBgp(((Bgp)algebra).TriplePatterns);
         }
         else if (algebra is ILeftJoin)
         {
             //LeftJoin is transformed to just be the LHS as the RHS is irrelevant for ASK queries
             //UNLESS the LeftJoin occurs inside a Filter/Minus BUT we should never get called to transform a
             //LeftJoin() for those branches of the algebra as the Optimiseer does not transform
             //Filter()/Minus() operators
             temp = this.OptimiseInternal(((ILeftJoin)algebra).Lhs, depth + 1);
         }
         else if (algebra is IUnion)
         {
             IUnion join = (IUnion)algebra;
             temp = new AskUnion(this.OptimiseInternal(join.Lhs, depth + 1), this.OptimiseInternal(join.Rhs, depth + 1));
         }
         else if (algebra is IJoin)
         {
             IJoin join = (IJoin)algebra;
             if (join.Lhs.Variables.IsDisjoint(join.Rhs.Variables))
             {
                 //If the sides of the Join are disjoint then can fully transform the join since we only need to find at least
                 //one solution on either side in order for the query to match
                 //temp = new Join(this.OptimiseInternal(join.Lhs, depth + 1), this.OptimiseInternal(join.Rhs, depth + 1));
                 temp = join.Transform(this);
             }
             else
             {
                 //If the sides are not disjoint then the LHS must be fully evaluated but the RHS need only produce at least
                 //one solution based on the full input from the LHS for the query to match
                 //temp = new Join(join.Lhs, this.OptimiseInternal(join.Rhs, depth + 1));
                 temp = join.TransformRhs(this);
             }
         }
         else if (algebra is Algebra.Graph)
         {
             //Algebra.Graph g = (Algebra.Graph)algebra;
             //temp = new Algebra.Graph(this.OptimiseInternal(g.InnerAlgebra, depth + 1), g.GraphSpecifier);
             IUnaryOperator op = (IUnaryOperator)algebra;
             temp = op.Transform(this);
         }
         else
         {
             temp = algebra;
         }
         return(temp);
     }
     catch
     {
         //If the Optimise fails return the current algebra
         return(algebra);
     }
 }