Exemplo n.º 1
0
 /// <summary>
 /// Left Joins the Multiset to another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <param name="expr">Expression which the Join is predicated on</param>
 /// <returns>The other Multiset</returns>
 public override BaseMultiset LeftJoin(BaseMultiset other, ISparqlExpression expr)
 {
     //If Other is Null/Empty then the Join still results in Identity
     if (other is NullMultiset) return this;
     if (other.IsEmpty) return this;
     return other;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Calculates the product of two mutlisets asynchronously with a timeout to restrict long running computations
        /// </summary>
        /// <param name="multiset">Multiset</param>
        /// <param name="other">Other Multiset</param>
        /// <param name="timeout">Timeout, if &lt;=0 no timeout is used and product will be computed sychronously</param>
        /// <returns></returns>
        public static BaseMultiset ProductWithTimeout(this BaseMultiset multiset, BaseMultiset other, long timeout)
        {
            if (other is IdentityMultiset) return multiset;
            if (other is NullMultiset) return other;
            if (other.IsEmpty) return new NullMultiset();

            if (timeout <= 0)
            {
                return multiset.Product(other);
            }

            //Invoke using an Async call
            Multiset productSet = new Multiset();
            StopToken stop = new StopToken();
            GenerateProductDelegate d = new GenerateProductDelegate(GenerateProduct);
            IAsyncResult r = d.BeginInvoke(multiset, other, productSet, stop, null, null);

            //Wait
            int t = (int)Math.Min(timeout, Int32.MaxValue);
            r.AsyncWaitHandle.WaitOne(t);
            if (!r.IsCompleted)
            {
                stop.ShouldStop = true;
                r.AsyncWaitHandle.WaitOne();
            }
            return productSet;
        }
Exemplo n.º 3
0
 public void Fill(BaseMultiset multiset)
 {
     foreach (ISet s in multiset.Sets)
     {
         this.ProcessResult(new SparqlResult(s));
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Calculates the product of two mutlisets asynchronously with a timeout to restrict long running computations
        /// </summary>
        /// <param name="multiset">Multiset</param>
        /// <param name="other">Other Multiset</param>
        /// <param name="timeout">Timeout, if &lt;=0 no timeout is used and product will be computed sychronously</param>
        /// <returns></returns>
        public static BaseMultiset ProductWithTimeout(this BaseMultiset multiset, BaseMultiset other, long timeout)
        {
            if (other is IdentityMultiset)
            {
                return(multiset);
            }
            if (other is NullMultiset)
            {
                return(other);
            }
            if (other.IsEmpty)
            {
                return(new NullMultiset());
            }

            //If no timeout use default implementation
            if (timeout <= 0)
            {
                return(multiset.Product(other));
            }

            //Otherwise Invoke using an Async call
            BaseMultiset productSet;

#if NET40 && !SILVERLIGHT
            if (Options.UsePLinqEvaluation)
            {
                if (multiset.Count >= other.Count)
                {
                    productSet = new PartitionedMultiset(multiset.Count, other.Count);
                }
                else
                {
                    productSet = new PartitionedMultiset(other.Count, multiset.Count);
                }
            }
            else
            {
#endif
            productSet = new Multiset();
#if NET40 && !SILVERLIGHT
        }
#endif
            StopToken stop            = new StopToken();
            GenerateProductDelegate d = new GenerateProductDelegate(GenerateProduct);
            IAsyncResult r            = d.BeginInvoke(multiset, other, productSet, stop, null, null);

            //Wait
            int t = (int)Math.Min(timeout, Int32.MaxValue);
            r.AsyncWaitHandle.WaitOne(t);
            if (!r.IsCompleted)
            {
                stop.ShouldStop = true;
                r.AsyncWaitHandle.WaitOne();
            }
            return(productSet);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Determines whether this Multiset is disjoint with another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override bool IsDisjointWith(BaseMultiset other)
        {
            if (other is IdentityMultiset || other is NullMultiset)
            {
                return(false);
            }

            return(this.Variables.All(v => !other.ContainsVariable(v)));
        }
        /// <summary>
        /// Creates a new Evaluation Context for the given Query over the given Dataset
        /// </summary>
        /// <param name="q">Query</param>
        /// <param name="data">Dataset</param>
        public SparqlEvaluationContext(SparqlQuery q, ISparqlDataset data)
        {
            this._query = q;
            this._data = data;
            this._inputSet = new IdentityMultiset();
            this._binder = new LeviathanResultBinder(this);

            this.CalculateTimeout();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Evaluates the Union
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //Create a copy of the evaluation context for the RHS
            SparqlEvaluationContext context2 = new SparqlEvaluationContext(context.Query, context.Data, context.Processor);

            if (!(context.InputMultiset is IdentityMultiset))
            {
                context2.InputMultiset = new Multiset();
                foreach (ISet s in context.InputMultiset.Sets)
                {
                    context2.InputMultiset.Add(s.Copy());
                }
            }

            List <Uri> activeGraphs  = context.Data.ActiveGraphUris.ToList();
            List <Uri> defaultGraphs = context.Data.DefaultGraphUris.ToList();

            ParallelEvaluateDelegate d   = new ParallelEvaluateDelegate(this.ParallelEvaluate);
            IAsyncResult             lhs = d.BeginInvoke(this._lhs, context, activeGraphs, defaultGraphs, null, null);
            IAsyncResult             rhs = d.BeginInvoke(this._rhs, context2, activeGraphs, defaultGraphs, null, null);

            WaitHandle.WaitAll(new WaitHandle[] { lhs.AsyncWaitHandle, rhs.AsyncWaitHandle });

            bool rhsOk = false;

            try
            {
                BaseMultiset lhsResult = d.EndInvoke(lhs);
                rhsOk = true;
                BaseMultiset rhsResult = d.EndInvoke(rhs);
                context.CheckTimeout();

                context.OutputMultiset = lhsResult.Union(rhsResult);
                context.CheckTimeout();

                context.InputMultiset = context.OutputMultiset;
                return(context.OutputMultiset);
            }
            catch
            {
                if (!rhsOk)
                {
                    //Clean up the RHS evaluation call if the LHS has errored
                    try
                    {
                        d.EndInvoke(rhs);
                    }
                    catch
                    {
                        //Ignore this error as we're already going to throw the other error
                    }
                }
                throw;
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Evaluates the Algebra in the given context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //First evaluate the inner algebra
            BaseMultiset results = context.Evaluate(this._inner);

            context.OutputMultiset = new Multiset();

            if (results is NullMultiset)
            {
                context.OutputMultiset = results;
            }
            else if (results is IdentityMultiset)
            {
                context.OutputMultiset.AddVariable(this._var);
                Set s = new Set();
                try
                {
                    INode temp = this._expr.Evaluate(context, 0);
                    s.Add(this._var, temp);
                }
                catch
                {
                    //No assignment if there's an error
                    s.Add(this._var, null);
                }
                context.OutputMultiset.Add(s.Copy());
            }
            else
            {
                if (results.ContainsVariable(this._var))
                {
                    throw new RdfQueryException("Cannot assign to the variable ?" + this._var + "since it has previously been used in the Query");
                }

                context.InputMultiset = results;
                context.OutputMultiset.AddVariable(this._var);
#if NET40 && !SILVERLIGHT
                if (Options.UsePLinqEvaluation && this._expr.CanParallelise)
                {
                    results.SetIDs.AsParallel().ForAll(id => EvalExtend(context, results, id));
                }
                else
                {
#endif
                foreach (int id in results.SetIDs)
                {
                    EvalExtend(context, results, id);
                }
#if NET40 && !SILVERLIGHT
            }
#endif
            }

            return(context.OutputMultiset);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Evaluates the Algebra in the given context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //First evaluate the inner algebra
            BaseMultiset results = context.Evaluate(this._inner);

            context.OutputMultiset = new Multiset();

            if (results is NullMultiset)
            {
                context.OutputMultiset = results;
            }
            else if (results is IdentityMultiset)
            {
                context.OutputMultiset.AddVariable(this._var);
                Set s = new Set();
                try
                {
                    INode temp = this._expr.Evaluate(context, 0);
                    s.Add(this._var, temp);
                }
                catch
                {
                    //No assignment if there's an error
                    s.Add(this._var, null);
                }
                context.OutputMultiset.Add(s.Copy());
            }
            else
            {
                if (results.ContainsVariable(this._var))
                {
                    throw new RdfQueryException("Cannot use a BIND assigment to BIND to a variable that has previously been used in the Query");
                }

                context.OutputMultiset.AddVariable(this._var);
                foreach (int id in results.SetIDs.ToList())
                {
                    ISet s = results[id].Copy();
                    try
                    {
                        //Make a new assignment
                        INode temp = this._expr.Evaluate(context, id);
                        s.Add(this._var, temp);
                    }
                    catch
                    {
                        //No assignment if there's an error but the solution is preserved
                    }
                    context.OutputMultiset.Add(s);
                }
            }

            return(context.OutputMultiset);
        }
Exemplo n.º 10
0
        private void EvalProduct(ISet x, BaseMultiset other, PartitionedMultiset productSet)
        {
            int id = productSet.GetNextBaseID();

            foreach (ISet y in other.Sets)
            {
                id++;
                ISet z = x.Join(y);
                z.ID = id;
                productSet.Add(z);
            }
        }
Exemplo n.º 11
0
 private void RhsCallback(IAsyncResult result)
 {
     try
     {
         this._rhsResult = this._d.EndInvoke(result);
     }
     catch (Exception ex)
     {
         this._rhsError  = ex;
         this._rhsResult = null;
     }
 }
Exemplo n.º 12
0
        /// <summary>
        /// Calculates the product of two multi-sets asynchronously with a timeout to restrict long running computations.
        /// </summary>
        /// <param name="multiset">Multiset.</param>
        /// <param name="other">Other Multiset.</param>
        /// <param name="timeout">Timeout, if &lt;=0 no timeout is used and product will be computed synchronously.</param>
        /// <returns></returns>
        public static BaseMultiset ProductWithTimeout(this BaseMultiset multiset, BaseMultiset other, long timeout)
        {
            if (other is IdentityMultiset)
            {
                return(multiset);
            }
            if (other is NullMultiset)
            {
                return(other);
            }
            if (other.IsEmpty)
            {
                return(new NullMultiset());
            }

            // If no timeout use default implementation
            if (timeout <= 0)
            {
                return(multiset.Product(other));
            }

            // Otherwise Invoke using an Async call
            BaseMultiset productSet;

            if (Options.UsePLinqEvaluation)
            {
                if (multiset.Count >= other.Count)
                {
                    productSet = new PartitionedMultiset(multiset.Count, other.Count);
                }
                else
                {
                    productSet = new PartitionedMultiset(other.Count, multiset.Count);
                }
            }
            else
            {
                productSet = new Multiset();
            }

            var stop        = new StopToken();
            var t           = (int)Math.Min(timeout, int.MaxValue);
            var productTask = Task.Factory.StartNew(() => GenerateProduct(multiset, other, productSet, stop));

            if (!productTask.Wait(t))
            {
                stop.ShouldStop = true;
                productTask.Wait();
            }

            return(productSet);
        }
Exemplo n.º 13
0
 /// <summary>
 /// Left Joins the Multiset to another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <param name="expr">Expression which the Join is predicated on</param>
 /// <returns>The other Multiset</returns>
 public override BaseMultiset LeftJoin(BaseMultiset other, ISparqlExpression expr)
 {
     //If Other is Null/Empty then the Join still results in Identity
     if (other is NullMultiset)
     {
         return(this);
     }
     if (other.IsEmpty)
     {
         return(this);
     }
     return(other);
 }
Exemplo n.º 14
0
 /// <summary>
 /// Generates the Union of this Set and another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <returns>The other Multiset</returns>
 public override BaseMultiset Union(BaseMultiset other)
 {
     //If Other is Null/Empty then the Join still results in Identity
     if (other is NullMultiset)
     {
         return(this);
     }
     if (other.IsEmpty)
     {
         return(this);
     }
     return(other);
 }
Exemplo n.º 15
0
        /// <summary>
        /// Determines the starting points for Path evaluation
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="paths">Paths</param>
        /// <param name="reverse">Whether to evaluate Paths in reverse</param>
        protected void GetPathStarts(SparqlEvaluationContext context, List <List <INode> > paths, bool reverse)
        {
            HashSet <KeyValuePair <INode, INode> > nodes = new HashSet <KeyValuePair <INode, INode> >();

            if (this.Path is Property)
            {
                INode predicate = ((Property)this.Path).Predicate;
                foreach (Triple t in context.Data.GetTriplesWithPredicate(predicate))
                {
                    if (reverse)
                    {
                        nodes.Add(new KeyValuePair <INode, INode>(t.Object, t.Subject));
                    }
                    else
                    {
                        nodes.Add(new KeyValuePair <INode, INode>(t.Subject, t.Object));
                    }
                }
            }
            else
            {
                BaseMultiset initialInput = context.InputMultiset;
                context.InputMultiset = new IdentityMultiset();
                VariablePattern x   = new VariablePattern("?x");
                VariablePattern y   = new VariablePattern("?y");
                Bgp             bgp = new Bgp(new PropertyPathPattern(x, this.Path, y));

                BaseMultiset results = context.Evaluate(bgp); //bgp.Evaluate(context);
                context.InputMultiset = initialInput;

                if (!results.IsEmpty)
                {
                    foreach (ISet s in results.Sets)
                    {
                        if (s["x"] != null && s["y"] != null)
                        {
                            if (reverse)
                            {
                                nodes.Add(new KeyValuePair <INode, INode>(s["y"], s["x"]));
                            }
                            else
                            {
                                nodes.Add(new KeyValuePair <INode, INode>(s["x"], s["y"]));
                            }
                        }
                    }
                }
            }

            paths.AddRange(nodes.Select(kvp => new List <INode>(new INode[] { kvp.Key, kvp.Value })));
        }
Exemplo n.º 16
0
        /// <summary>
        /// Does a Product of this Multiset and another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public virtual BaseMultiset Product(BaseMultiset other)
        {
            if (other is IdentityMultiset)
            {
                return(this);
            }
            if (other is NullMultiset)
            {
                return(other);
            }
            if (other.IsEmpty)
            {
                return(new NullMultiset());
            }

#if NET40 && !SILVERLIGHT
            if (Options.UsePLinqEvaluation)
            {
                //Determine partition sizes so we can do a parallel product
                //Want to parallelize over whichever side is larger
                PartitionedMultiset partitionedSet;
                if (this.Count >= other.Count)
                {
                    partitionedSet = new PartitionedMultiset(this.Count, other.Count);
                    this.Sets.AsParallel().ForAll(x => this.EvalProduct(x, other, partitionedSet));
                }
                else
                {
                    partitionedSet = new PartitionedMultiset(other.Count, this.Count);
                    other.Sets.AsParallel().ForAll(y => this.EvalProduct(y, this, partitionedSet));
                }
                return(partitionedSet);
            }
            else
            {
#endif
            //Use serial calculation which is likely to really suck for big products
            Multiset productSet = new Multiset();
            foreach (ISet x in this.Sets)
            {
                foreach (ISet y in other.Sets)
                {
                    productSet.Add(x.Join(y));
                }
            }
            return(productSet);

#if NET40 && !SILVERLIGHT
        }
#endif
        }
Exemplo n.º 17
0
        /// <summary>
        /// Joins this Multiset to another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override BaseMultiset Join(BaseMultiset other)
        {
            //If the Other is the Identity Multiset the result is this Multiset
            if (other is IdentityMultiset)
            {
                return(this);
            }
            //If the Other is the Null Multiset the result is the Null Multiset
            if (other is NullMultiset)
            {
                return(other);
            }
            //If the Other is Empty then the result is the Null Multiset
            if (other.IsEmpty)
            {
                return(new NullMultiset());
            }

            //Find the First Variable from this Multiset which is in both Multisets
            //If there is no Variable from this Multiset in the other Multiset then this
            //should be a Join operation instead of a LeftJoin
            List <String> joinVars = this._variables.Where(v => other.Variables.Contains(v)).ToList();

            if (joinVars.Count == 0)
            {
                return(this.Product(other));
            }

            //Start building the Joined Set
            Multiset joinedSet = new Multiset();

            foreach (ISet x in this.Sets)
            {
                //For sets to be compatible for every joinable variable they must either have a null for the
                //variable in one of the sets or if they have values the values must be equal

                ////This first check is to try speed things up, it looks whether there are solutions that may match
                ////without needing to do a full table scan of the RHS results as the subsequent LINQ call will do
                ////if (!joinVars.All(v => x[v] == null || other.ContainsValue(v, x[v]) || other.ContainsValue(v, null))) continue;

                IEnumerable <ISet> ys = other.Sets.Where(s => joinVars.All(v => x[v] == null || s[v] == null || x[v].Equals(s[v])));
                //IEnumerable<ISet> ys = other.Sets.Where(s => s.IsCompatibleWith(x, joinVars));

                foreach (ISet y in ys)
                {
                    joinedSet.Add(x.Join(y));
                }
            }
            return(joinedSet);
        }
Exemplo n.º 18
0
 /// <summary>
 /// Exists Joins the Multiset to another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <param name="mustExist">Whether solutions must exist in the Other Multiset for the Join to suceed</param>
 /// <returns></returns>
 public override BaseMultiset ExistsJoin(BaseMultiset other, bool mustExist)
 {
     if (mustExist)
     {
         if (other is NullMultiset) return other;
         return this;
     }
     else
     {
         if (other is NullMultiset) return this;
         if (other is IdentityMultiset) return new NullMultiset();
         return this;
     }
 }
Exemplo n.º 19
0
        /// <summary>
        /// Evaluates the BGP against the Evaluation Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            bool         halt;
            BaseMultiset results = this.StreamingEvaluate(context, 0, out halt);

            if (results is Multiset && results.IsEmpty)
            {
                results = new NullMultiset();
            }

            context.OutputMultiset = results;
            context.OutputMultiset.Trim();
            return(context.OutputMultiset);
        }
Exemplo n.º 20
0
 /// <summary>
 /// Method for generating product of two multisets asynchronously
 /// </summary>
 /// <param name="multiset">Multiset</param>
 /// <param name="other">Other Multiset</param>
 /// <param name="target">Mutliset to generate the product in</param>
 /// <param name="stop">Stop Token</param>
 private static void GenerateProduct(BaseMultiset multiset, BaseMultiset other, BaseMultiset target, StopToken stop)
 {
     foreach (ISet x in multiset.Sets)
     {
         foreach (ISet y in other.Sets)
         {
             target.Add(x.Join(y));
             //if (stop.ShouldStop) break;
         }
         if (stop.ShouldStop)
         {
             break;
         }
     }
 }
Exemplo n.º 21
0
        private void EvalExtend(SparqlEvaluationContext context, BaseMultiset results, int id)
        {
            ISet s = results[id].Copy();

            try
            {
                // Make a new assignment
                INode temp = _expr.Evaluate(context, id);
                s.Add(_var, temp);
            }
            catch
            {
                // No assignment if there's an error but the solution is preserved
            }
            context.OutputMultiset.Add(s);
        }
Exemplo n.º 22
0
        public void SparqlAlgebraJoinSingleVariable1()
        {
            ISet x = new Set();

            x.Add("a", this._factory.CreateUriNode(UriFactory.Create("http://x")));

            BaseMultiset lhs = new Multiset();

            lhs.Add(x);
            BaseMultiset rhs = new Multiset();

            rhs.Add(x);

            BaseMultiset joined = lhs.Join(rhs);

            Assert.AreEqual(1, joined.Count);
        }
Exemplo n.º 23
0
        /// <summary>
        /// Does a Union of this Multiset and another Multiset.
        /// </summary>
        /// <param name="other">Other Multiset.</param>
        /// <returns></returns>
        public override BaseMultiset Union(BaseMultiset other)
        {
            if (other is IdentityMultiset) return this;
            if (other is NullMultiset) return this;
            if (other.IsEmpty) return this;

            Multiset m = new Multiset();
            foreach (ISet s in this.Sets)
            {
                m.Add(s.Copy());
            }
            foreach (ISet s in other.Sets)
            {
                m.Add(s.Copy());
            }
            return m;
        }
Exemplo n.º 24
0
        /// <summary>
        /// Evaluates the Path in the given context.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <returns></returns>
        public override BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            // Try and generate an Algebra expression
            // Make sure we don't generate clashing temporary variable IDs over the life of the
            // Evaluation
            PathTransformContext transformContext = new PathTransformContext(PathStart, PathEnd);

            if (context["PathTransformID"] != null)
            {
                transformContext.NextID = (int)context["PathTransformID"];
            }
            ISparqlAlgebra algebra = Path.ToAlgebra(transformContext);

            context["PathTransformID"] = transformContext.NextID;

            // Now we can evaluate the resulting algebra
            BaseMultiset initialInput = context.InputMultiset;
            bool         trimMode     = context.TrimTemporaryVariables;
            bool         rigMode      = Options.RigorousEvaluation;

            try
            {
                // Must enable rigorous evaluation or we get incorrect interactions between property and non-property path patterns
                Options.RigorousEvaluation = true;

                // Note: We may need to preserve Blank Node variables across evaluations
                // which we usually don't do BUT because of the way we translate only part of the path
                // into an algebra at a time and may need to do further nested translate calls we do
                // need to do this here
                context.TrimTemporaryVariables = false;
                BaseMultiset result = context.Evaluate(algebra);

                // Also note that we don't trim temporary variables here even if we've set the setting back
                // to enabled since a Trim will be done at the end of whatever BGP we are being evaluated in

                // Once we have our results can join then into our input
                context.OutputMultiset = initialInput.Join(result);
            }
            finally
            {
                context.TrimTemporaryVariables = trimMode;
                Options.RigorousEvaluation     = rigMode;
            }

            return(context.OutputMultiset);
        }
Exemplo n.º 25
0
        /// <summary>
        /// Evaluates the BINDINGS modifier
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //Evalute the Pattern
            BaseMultiset results = context.Evaluate(this._pattern);//this._pattern.Evaluate(context);

            //If the result is Null/Identity/Empty
            if (results is NullMultiset || results is IdentityMultiset || results.IsEmpty)
            {
                context.OutputMultiset = results;
                return(results);
            }
            else
            {
                //Result is an Join from the results to the Input Bindings
                context.OutputMultiset = results.Join(this._bindings.ToMultiset());
                return(context.OutputMultiset);
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// Creates a new Group Multiset
        /// </summary>
        /// <param name="contents">Multiset which contains the Member Sets of the Groups</param>
        /// <param name="groups">Groups</param>
        public GroupMultiset(BaseMultiset contents, List<BindingGroup> groups)
        {
            this._contents = contents;
            this._groups = groups;

            bool first = true;
            foreach (BindingGroup group in groups)
            {
                Set s = new Set();
                foreach (KeyValuePair<String, INode> assignment in group.Assignments)
                {
                    if (first) this.AddVariable(assignment.Key);
                    s.Add(assignment.Key, assignment.Value);
                }
                first = false;
                base.Add(s);
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Evaluates the Union
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            BaseMultiset initialInput = context.InputMultiset;
            BaseMultiset lhsResult    = context.Evaluate(this._lhs);//this._lhs.Evaluate(context);

            context.CheckTimeout();

            context.InputMultiset = initialInput;
            BaseMultiset rhsResult = context.Evaluate(this._rhs);//this._rhs.Evaluate(context);

            context.CheckTimeout();

            context.OutputMultiset = lhsResult.Union(rhsResult);
            context.CheckTimeout();

            context.InputMultiset = context.OutputMultiset;
            return(context.OutputMultiset);
        }
Exemplo n.º 28
0
        private static void EvalProduct(ISet x, BaseMultiset other, PartitionedMultiset productSet, StopToken stop)
        {
            if (stop.ShouldStop)
            {
                return;
            }
            var id = productSet.GetNextBaseID();

            foreach (var y in other.Sets)
            {
                id++;
                var z = x.Join(y);
                z.ID = id;
                productSet.Add(z);
                if (stop.ShouldStop)
                {
                    return;
                }
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// Does a Minus Join of this Multiset to another Multiset where any joinable results are subtracted from this Multiset to give the resulting Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override BaseMultiset MinusJoin(BaseMultiset other)
        {
            //If the other Multiset is the Identity/Null Multiset then minus-ing it doesn't alter this set
            if (other is IdentityMultiset)
            {
                return(this);
            }
            if (other is NullMultiset)
            {
                return(this);
            }
            //If the other Multiset is disjoint then minus-ing it also doesn't alter this set
            if (this.IsDisjointWith(other))
            {
                return(this);
            }

            //Find the Variables that are to be used for Joining
            List <String> joinVars = this._variables.Where(v => other.Variables.Contains(v)).ToList();

            if (joinVars.Count == 0)
            {
                return(this.Product(other));
            }

            //Start building the Joined Set
            Multiset joinedSet = new Multiset();

            foreach (ISet x in this.Sets)
            {
                //New Minus logic based on the improved Join() logic
                bool minus = other.Sets.Any(s => joinVars.All(v => x[v] == null || s[v] == null || x[v].Equals(s[v])));

                //If no compatible sets then this set is preserved
                if (!minus)
                {
                    joinedSet.Add(x);
                }
            }
            return(joinedSet);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Does a Union of this Multiset and another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override BaseMultiset Union(BaseMultiset other)
        {
            if (other is IdentityMultiset)
            {
                return(this);
            }
            if (other is NullMultiset)
            {
                return(this);
            }
            if (other.IsEmpty)
            {
                return(this);
            }

            foreach (ISet s in other.Sets)
            {
                this.Add(s);
            }
            return(this);
        }
Exemplo n.º 31
0
        /// <summary>
        /// Does a Union of this Multiset and another Multiset.
        /// </summary>
        /// <param name="other">Other Multiset.</param>
        /// <returns></returns>
        public virtual BaseMultiset Union(BaseMultiset other)
        {
            if (other is IdentityMultiset)
            {
                return(this);
            }
            if (other is NullMultiset)
            {
                return(this);
            }
            if (other.IsEmpty)
            {
                return(this);
            }

            foreach (ISet s in other.Sets)
            {
                Add(s.Copy());
            }
            return(this);
        }
Exemplo n.º 32
0
        private void EvalLeftJoinProduct(ISet x, BaseMultiset other, PartitionedMultiset partitionedSet, ISparqlExpression expr)
        {
            LeviathanLeftJoinBinder binder = new LeviathanLeftJoinBinder(partitionedSet);
            SparqlEvaluationContext subcontext = new SparqlEvaluationContext(binder);
            bool standalone = false, matched = false;

            int id = partitionedSet.GetNextBaseID();

            foreach (ISet y in other.Sets)
            {
                id++;
                ISet z = x.Join(y);
                z.ID = id;
                try
                {
                    partitionedSet.Add(z);
                    if (!expr.Evaluate(subcontext, z.ID).AsSafeBoolean())
                    {
                        partitionedSet.Remove(z.ID);
                        standalone = true;
                    }
                    else
                    {
                        matched = true;
                    }
                }
                catch
                {
                    partitionedSet.Remove(z.ID);
                    standalone = true;
                }
            }
            if (standalone && !matched)
            {
                id++;
                ISet z = x.Copy();
                z.ID = id;
                partitionedSet.Add(z);
            }
        }
Exemplo n.º 33
0
        /// <summary>
        /// Creates a new Group Multiset
        /// </summary>
        /// <param name="contents">Multiset which contains the Member Sets of the Groups</param>
        /// <param name="groups">Groups</param>
        public GroupMultiset(BaseMultiset contents, List <BindingGroup> groups)
        {
            this._contents = contents;

            bool first = true;

            foreach (BindingGroup group in groups)
            {
                Set s = new Set();
                foreach (KeyValuePair <String, INode> assignment in group.Assignments)
                {
                    if (first)
                    {
                        this.AddVariable(assignment.Key);
                    }
                    s.Add(assignment.Key, assignment.Value);
                }
                first = false;
                base.Add(s);
                this._groups.Add(s.ID, group);
            }
        }
Exemplo n.º 34
0
 /// <summary>
 /// Exists Joins the Multiset to another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <param name="mustExist">Whether solutions must exist in the Other Multiset for the Join to suceed</param>
 /// <returns></returns>
 public override BaseMultiset ExistsJoin(BaseMultiset other, bool mustExist)
 {
     if (mustExist)
     {
         if (other is NullMultiset)
         {
             return(other);
         }
         return(this);
     }
     else
     {
         if (other is NullMultiset)
         {
             return(this);
         }
         if (other is IdentityMultiset)
         {
             return(new NullMultiset());
         }
         return(this);
     }
 }
Exemplo n.º 35
0
        /// <summary>
        /// Evaluates the Minus join by evaluating the LHS and RHS and substracting the RHS results from the LHS.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            BaseMultiset initialInput = context.InputMultiset;
            BaseMultiset lhsResult    = context.Evaluate(_lhs);//this._lhs.Evaluate(context);

            context.CheckTimeout();

            if (lhsResult is NullMultiset)
            {
                context.OutputMultiset = lhsResult;
            }
            else if (lhsResult.IsEmpty)
            {
                context.OutputMultiset = new NullMultiset();
            }
            else if (_lhs.Variables.IsDisjoint(_rhs.Variables))
            {
                // If the RHS is disjoint then there is no need to evaluate the RHS
                context.OutputMultiset = lhsResult;
            }
            else
            {
                // If we get here then the RHS is not disjoint so it does affect the ouput

                // Only execute the RHS if the LHS had results
                // context.InputMultiset = lhsResult;
                context.InputMultiset = initialInput;
                BaseMultiset rhsResult = context.Evaluate(_rhs);//this._rhs.Evaluate(context);
                context.CheckTimeout();

                context.OutputMultiset = lhsResult.MinusJoin(rhsResult);
                context.CheckTimeout();
            }

            context.InputMultiset = context.OutputMultiset;
            return(context.OutputMultiset);
        }
Exemplo n.º 36
0
        /// <summary>
        /// Calculates the product of two mutlisets asynchronously with a timeout to restrict long running computations
        /// </summary>
        /// <param name="multiset">Multiset</param>
        /// <param name="other">Other Multiset</param>
        /// <param name="timeout">Timeout, if &lt;=0 no timeout is used and product will be computed sychronously</param>
        /// <returns></returns>
        public static BaseMultiset ProductWithTimeout(this BaseMultiset multiset, BaseMultiset other, long timeout)
        {
            if (other is IdentityMultiset)
            {
                return(multiset);
            }
            if (other is NullMultiset)
            {
                return(other);
            }
            if (other.IsEmpty)
            {
                return(new NullMultiset());
            }

            if (timeout <= 0)
            {
                return(multiset.Product(other));
            }

            //Invoke using an Async call
            Multiset  productSet      = new Multiset();
            StopToken stop            = new StopToken();
            GenerateProductDelegate d = new GenerateProductDelegate(GenerateProduct);
            IAsyncResult            r = d.BeginInvoke(multiset, other, productSet, stop, null, null);

            //Wait
            int t = (int)Math.Min(timeout, Int32.MaxValue);

            r.AsyncWaitHandle.WaitOne(t);
            if (!r.IsCompleted)
            {
                stop.ShouldStop = true;
                r.AsyncWaitHandle.WaitOne();
            }
            return(productSet);
        }
Exemplo n.º 37
0
        /// <summary>
        /// Does a Minus Join of this Multiset to another Multiset where any joinable results are subtracted from this Multiset to give the resulting Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override BaseMultiset MinusJoin(BaseMultiset other)
        {
            //If the other Multiset is the Identity/Null Multiset then minus-ing it doesn't alter this set
            if (other is IdentityMultiset) return this;
            if (other is NullMultiset) return this;
            //If the other Multiset is disjoint then minus-ing it also doesn't alter this set
            if (this.IsDisjointWith(other)) return this;

            //Find the Variables that are to be used for Joining
            List<String> joinVars = this._variables.Where(v => other.Variables.Contains(v)).ToList();
            if (joinVars.Count == 0) return this.Product(other);

            //Start building the Joined Set
            Multiset joinedSet = new Multiset();

            //This is the old algorithm which is correct but naive and has O(n^2) complexity
            //foreach (ISet x in this.Sets)
            //{
            //    //New Minus logic based on the improved Join() logic
            //    bool minus = other.Sets.Any(s => joinVars.All(v => x[v] == null || s[v] == null || x[v].Equals(s[v])));

            //    //If no compatible sets then this set is preserved
            //    if (!minus)
            //    {
            //        joinedSet.Add(x);
            //    }
            //}

            //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
            List<HashTable<INode, int>> values = new List<HashTable<INode, int>>();
            List<List<int>> nulls = new List<List<int>>();
            foreach (String var in joinVars)
            {
                values.Add(new HashTable<INode, int>(HashTableBias.Enumeration));
                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 this.Sets)
            {
                int i = 0;
                foreach (String var in joinVars)
                {
                    INode value = x[var];
                    if (value != null)
                    {
                        values[i].Add(value, x.ID);
                    }
                    else
                    {
                        nulls[i].Add(x.ID);
                    }
                    i++;
                }
            }

            //Then do a pass over the RHS and work out the intersections
            HashSet<int> toMinus = new HashSet<int>();
            foreach (ISet y in other.Sets)
            {
                IEnumerable<int> possMatches = null;
                int i = 0;
                foreach (String var in joinVars)
                {
                    INode value = y[var];
                    if (value != null)
                    {
                        if (values[i].ContainsKey(value))
                        {
                            possMatches = (possMatches == null ? values[i].GetValues(value).Concat(nulls[i]) : possMatches.Intersect(values[i].GetValues(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 ? this.SetIDs : possMatches.Intersect(this.SetIDs));
                    }
                    i++;
                }
                if (possMatches == null) continue;

                //Look at possible matches, if is a valid match then mark the matched set for minus'ing
                //Don't reconsider sets which have already been marked for minusing
                foreach (int poss in possMatches)
                {
                    if (toMinus.Contains(poss)) continue;
                    if (this._sets[poss].IsCompatibleWith(y, joinVars))
                    {
                        toMinus.Add(poss);
                    }
                }
            }

            //Apply the actual minus
            if (toMinus.Count == this.Count)
            {
                //If number of sets to minus is equal to number of sets then we're minusing everything
                return new NullMultiset();
            }
            else
            {
                //Otherwise iterate
                foreach (ISet x in this.Sets)
                {
                    if (!toMinus.Contains(x.ID))
                    {
                        joinedSet.Add(x.Copy());
                    }
                }
            }

            return joinedSet;
        }
Exemplo n.º 38
0
 private void RhsCallback(IAsyncResult result)
 {
     try
     {
         this._rhsResult = this._d.EndInvoke(result);
     }
     catch (Exception ex)
     {
         this._rhsError = ex;
         this._rhsResult = null;
     }
 }
Exemplo n.º 39
0
 /// <summary>
 /// Unions this Multiset with another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <returns>
 /// Results in the Other Multiset as this is an empty Multiset
 /// </returns>
 public override BaseMultiset Union(BaseMultiset other)
 {
     //Union results in Other Multiset
     return other;
 }
Exemplo n.º 40
0
        /// <summary>
        /// Does a Union of this Multiset and another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override BaseMultiset Union(BaseMultiset other)
        {
            if (other is IdentityMultiset) return this;
            if (other is NullMultiset) return this;
            if (other.IsEmpty) return this;

            foreach (ISet s in other.Sets)
            {
                this.Add(s.Copy());
            }
            return this;
        }
Exemplo n.º 41
0
 /// <summary>
 /// Exists Joins another Multiset to this Null Mutliset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <param name="mustExist">Whether joinable solutions must exist in the other Multiset for joins to be made</param>
 /// <returns>
 /// Results in this Null Multiset since Null joined to anything is Null
 /// </returns>
 public override BaseMultiset ExistsJoin(BaseMultiset other, bool mustExist)
 {
     return this;
 }
Exemplo n.º 42
0
 /// <summary>
 /// Minus Join is a special type of Join which only preserves sets from this Multiset which cannot be joined to the other Multiset
 /// </summary>
 /// <param name="other">Multiset to join with</param>
 /// <returns></returns>
 public abstract BaseMultiset MinusJoin(BaseMultiset other);
Exemplo n.º 43
0
 /// <summary>
 /// Union combines two concatenates two mutlisets
 /// </summary>
 /// <param name="other">Multiset to concatenate with</param>
 /// <returns></returns>
 public abstract BaseMultiset Union(BaseMultiset other);
Exemplo n.º 44
0
 /// <summary>
 /// Left Join combines two multisets where the join is predicated on an arbitrary expression
 /// </summary>
 /// <param name="other">Multiset to join with</param>
 /// <param name="expr">Expression on which the Join is predicated</param>
 /// <returns></returns>
 /// <remarks>
 /// Used for doing OPTIONALs
 /// </remarks>
 public abstract BaseMultiset LeftJoin(BaseMultiset other, ISparqlExpression expr);
Exemplo n.º 45
0
        /// <summary>
        /// Does an Exists Join of this Multiset to another Multiset where the Join is predicated on the existence/non-existence of a joinable solution on the RHS
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <param name="mustExist">Whether a solution must exist in the Other Multiset for the join to be made</param>
        /// <returns></returns>
        public override BaseMultiset ExistsJoin(BaseMultiset other, bool mustExist)
        {
            //For EXISTS and NOT EXISTS if the other is the Identity then it has no effect
            if (other is IdentityMultiset) return this;
            if (mustExist)
            {
                //If an EXISTS then Null/Empty Other results in Null
                if (other is NullMultiset) return other;
                if (other.IsEmpty) return new NullMultiset();
            }
            else
            {
                //If a NOT EXISTS then Null/Empty results in this
                if (other is NullMultiset) return this;
                if (other.IsEmpty) return this;
            }

            //Find the Variables that are to be used for Joining
            List<String> joinVars = this._variables.Where(v => other.Variables.Contains(v)).ToList();
            if (joinVars.Count == 0)
            {
                //All Disjoint Solutions are compatible
                if (mustExist)
                {
                    //If an EXISTS and disjoint then result is this
                    return this;
                }
                else
                {
                    //If a NOT EXISTS and disjoint then result is null
                    return new NullMultiset();
                }
            }

            //Start building the Joined Set
            Multiset joinedSet = new Multiset();

            //This is the old algorithm which is correct but naive with worse case O(n^2)
            //foreach (ISet x in this.Sets)
            //{
            //    //New ExistsJoin() logic based on the improved Join() logic
            //    bool exists = other.Sets.Any(s => joinVars.All(v => x[v] == null || s[v] == null || x[v].Equals(s[v])));
            //    //bool exists = other.Sets.Any(s => s.IsCompatibleWith(x, joinVars));

            //    if (exists)
            //    {
            //        //If there are compatible sets and this is an EXIST then preserve the solution
            //        if (mustExist) joinedSet.Add(x);
            //    }
            //    else
            //    {
            //        //If there are no compatible sets and this is a NOT EXISTS then preserve the solution
            //        if (!mustExist) joinedSet.Add(x);
            //    }
            //}

            //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
            List<HashTable<INode, int>> values = new List<HashTable<INode, int>>();
            List<List<int>> nulls = new List<List<int>>();
            foreach (String var in joinVars)
            {
                values.Add(new HashTable<INode, int>(HashTableBias.Enumeration));
                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 this.Sets)
            {
                int i = 0;
                foreach (String var in joinVars)
                {
                    INode value = x[var];
                    if (value != null)
                    {
                        values[i].Add(value, x.ID);
                    }
                    else
                    {
                        nulls[i].Add(x.ID);
                    }
                    i++;
                }
            }

            //Then do a pass over the RHS and work out the intersections
            HashSet<int> exists = new HashSet<int>();
            foreach (ISet y in other.Sets)
            {
                IEnumerable<int> possMatches = null;
                int i = 0;
                foreach (String var in joinVars)
                {
                    INode value = y[var];
                    if (value != null)
                    {
                        if (values[i].ContainsKey(value))
                        {
                            possMatches = (possMatches == null ? values[i].GetValues(value).Concat(nulls[i]) : possMatches.Intersect(values[i].GetValues(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 ? this.SetIDs : possMatches.Intersect(this.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 (this._sets[poss].IsCompatibleWith(y, joinVars))
                    {
                        exists.Add(poss);
                    }
                }
            }

            //Apply the actual exists
            if (exists.Count == this.Count)
            {
                //If number of sets that have a match is equal to number of sets then we're either returning everything or nothing
                if (mustExist)
                {
                    return this;
                }
                else
                {
                    return new NullMultiset();
                }
            }
            else
            {
                //Otherwise iterate
                foreach (ISet x in this.Sets)
                {
                    if (mustExist)
                    {
                        if (exists.Contains(x.ID))
                        {
                            joinedSet.Add(x.Copy());
                        }
                    }
                    else
                    {
                        if (!exists.Contains(x.ID))
                        {
                            joinedSet.Add(x.Copy());
                        }
                    }
                }
            }

            return joinedSet;
        }
Exemplo n.º 46
0
        /// <summary>
        /// Does a Left Join of this Multiset to another Multiset where the Join is predicated on the given Expression
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <param name="expr">Expression</param>
        /// <returns></returns>
        public override BaseMultiset LeftJoin(BaseMultiset other, ISparqlExpression expr)
        {
            //If the Other is the Identity/Null Multiset the result is this Multiset
            if (other is IdentityMultiset) return this;
            if (other is NullMultiset) return this;
            if (other.IsEmpty) return this;

            Multiset joinedSet = new Multiset();
            LeviathanLeftJoinBinder binder = new LeviathanLeftJoinBinder(joinedSet);
            SparqlEvaluationContext subcontext = new SparqlEvaluationContext(binder);

            //Find the First Variable from this Multiset which is in both Multisets
            //If there is no Variable from this Multiset in the other Multiset then this
            //should be a Join operation instead of a LeftJoin
            List<String> joinVars = this._variables.Where(v => other.Variables.Contains(v)).ToList();
            if (joinVars.Count == 0)
            {
                //Calculate a Product filtering as we go
                foreach (ISet x in this.Sets)
                {
                    bool standalone = false;
                    foreach (ISet y in other.Sets)
                    {
                        ISet z = x.Join(y);
                        try
                        {
                            joinedSet.Add(z);
                            if (!expr.Evaluate(subcontext, z.ID).AsSafeBoolean())
                            {
                                joinedSet.Remove(z.ID);
                                standalone = true;
                            }
                        }
                        catch
                        {
                            joinedSet.Remove(z.ID);
                            standalone = true;
                        }
                    }
                    if (standalone) joinedSet.Add(x.Copy());
                }
            }
            else
            {
                //This is the old algorithm which is correct but has complexity O(n^2) so it scales terribly
                //foreach (ISet x in this.Sets)
                //{
                //    IEnumerable<ISet> ys = other.Sets.Where(s => joinVars.All(v => x[v] == null || s[v] == null || x[v].Equals(s[v])));
                //    //IEnumerable<ISet> ys = other.Sets.Where(s => s.IsCompatibleWith(x, joinVars));
                //    bool standalone = false;
                //    int i = 0;
                //    foreach (ISet y in ys)
                //    {
                //        i++;
                //        ISet z = x.Join(y);
                //        try
                //        {
                //            joinedSet.Add(z);
                //            if (!expr.Evaluate(subcontext, z.ID).AsSafeBoolean())
                //            {
                //                joinedSet.Remove(z.ID);
                //                standalone = true;
                //            }
                //        }
                //        catch
                //        {
                //            joinedSet.Remove(z.ID);
                //            standalone = true;
                //        }
                //    }
                //    if (standalone || i == 0) joinedSet.Add(x);
                //}

                //This is the new Join algorithm which is also correct but is O(2n) so much faster and scalable
                //Downside is that it does require more memory than the old algorithm
                List<HashTable<INode, int>> values = new List<HashTable<INode, int>>();
                List<List<int>> nulls = new List<List<int>>();
                foreach (String var in joinVars)
                {
                    values.Add(new HashTable<INode, int>(HashTableBias.Enumeration));
                    nulls.Add(new List<int>());
                }

                //First do a pass over the LHS Result to find all possible values for joined variables
                HashSet<int> matched = new HashSet<int>();
                HashSet<int> standalone = new HashSet<int>();
                foreach (ISet x in this.Sets)
                {
                    int i = 0;
                    foreach (String var in joinVars)
                    {
                        INode value = x[var];
                        if (value != null)
                        {
                            values[i].Add(value, x.ID);
                        }
                        else
                        {
                            nulls[i].Add(x.ID);
                        }
                        i++;
                    }
                }

                //Then do a pass over the RHS and work out the intersections
                foreach (ISet y in other.Sets)
                {
                    IEnumerable<int> possMatches = null;
                    int i = 0;
                    foreach (String var in joinVars)
                    {
                        INode value = y[var];
                        if (value != null)
                        {
                            if (values[i].ContainsKey(value))
                            {
                                possMatches = (possMatches == null ? values[i].GetValues(value).Concat(nulls[i]) : possMatches.Intersect(values[i].GetValues(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 ? this.SetIDs : possMatches.Intersect(this.SetIDs));
                        }
                        i++;
                    }
                    if (possMatches == null) continue;

                    //Now do the actual joins for the current set
                    //Note - We access the dictionary directly here because going through the this[int id] method
                    //incurs a Contains() call each time and we know the IDs must exist because they came from
                    //our dictionary originally!
                    foreach (int poss in possMatches)
                    {
                        if (this._sets[poss].IsCompatibleWith(y, joinVars))
                        {
                            ISet z = this._sets[poss].Join(y);
                            joinedSet.Add(z);
                            try
                            {
                                if (!expr.Evaluate(subcontext, z.ID).AsSafeBoolean())
                                {
                                    joinedSet.Remove(z.ID);
                                    standalone.Add(poss);
                                }
                                else
                                {
                                    matched.Add(poss);
                                }
                            }
                            catch
                            {
                                joinedSet.Remove(z.ID);
                                standalone.Add(poss);
                            }
                        }
                    }
                }

                //Finally add in unmatched sets from LHS
                foreach (int id in this.SetIDs)
                {
                    if (!matched.Contains(id) || standalone.Contains(id)) joinedSet.Add(this._sets[id].Copy());
                }
            }
            return joinedSet;
        }
Exemplo n.º 47
0
        /// <summary>
        /// Joins this Multiset to another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override BaseMultiset Join(BaseMultiset other)
        {
            //If the Other is the Identity Multiset the result is this Multiset
            if (other is IdentityMultiset) return this;
            //If the Other is the Null Multiset the result is the Null Multiset
            if (other is NullMultiset) return other;
            //If the Other is Empty then the result is the Null Multiset
            if (other.IsEmpty) return new NullMultiset();

            //Find the First Variable from this Multiset which is in both Multisets
            //If there is no Variable from this Multiset in the other Multiset then this
            //should be a Join operation instead of a LeftJoin
            List<String> joinVars = this._variables.Where(v => other.Variables.Contains(v)).ToList();
            if (joinVars.Count == 0) return this.Product(other);

            //Start building the Joined Set
            Multiset joinedSet = new Multiset();

            //This is the old Join algorithm which while correct is O(n^2) so scales terribly
            //foreach (ISet x in this.Sets)
            //{
            //    //For sets to be compatible for every joinable variable they must either have a null for the
            //    //variable in one of the sets or if they have values the values must be equal

            //    ////This first check is to try speed things up, it looks whether there are solutions that may match
            //    ////without needing to do a full table scan of the RHS results as the subsequent LINQ call will do
            //    ////if (!joinVars.All(v => x[v] == null || other.ContainsValue(v, x[v]) || other.ContainsValue(v, null))) continue;

            //    IEnumerable<ISet> ys = other.Sets.Where(s => joinVars.All(v => x[v] == null || s[v] == null || x[v].Equals(s[v])));
            //    //IEnumerable<ISet> ys = other.Sets.Where(s => s.IsCompatibleWith(x, joinVars));

            //    foreach (ISet y in ys)
            //    {
            //        joinedSet.Add(x.Join(y));
            //    }
            //}

            //This is the new Join algorithm which is also correct but is O(2n) so much faster and scalable
            //Downside is that it does require more memory than the old algorithm
            List<HashTable<INode, int>> values = new List<HashTable<INode, int>>();
            List<List<int>> nulls = new List<List<int>>();
            foreach (String var in joinVars)
            {
                values.Add(new HashTable<INode, int>(HashTableBias.Enumeration));
                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 this.Sets)
            {
                int i = 0;
                foreach (String var in joinVars)
                {
                    INode value = x[var];
                    if (value != null)
                    {
                        values[i].Add(value, x.ID);
                    }
                    else
                    {
                        nulls[i].Add(x.ID);
                    }
                    i++;
                }
            }

            #if NET40 && !SILVERLIGHT
            if (Options.UsePLinqEvaluation)
            {
                //Use a paralllel join
                other.Sets.AsParallel().ForAll(y => EvalJoin(y, joinVars, values, nulls, joinedSet));
            }
            else
            {
            #endif
                //Use a serial join
                //Then do a pass over the RHS and work out the intersections
                foreach (ISet y in other.Sets)
                {
                    this.EvalJoin(y, joinVars, values, nulls, joinedSet);
                }
            #if NET40 && !SILVERLIGHT
            }
            #endif

            return joinedSet;
        }
Exemplo n.º 48
0
        /// <summary>
        /// Determines whether this Multiset is disjoint with another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override bool IsDisjointWith(BaseMultiset other)
        {
            if (other is IdentityMultiset || other is NullMultiset) return false;

            return this._variables.All(v => !other.ContainsVariable(v));
        }
Exemplo n.º 49
0
 /// <summary>
 /// Determines whether the Mutliset is disjoint with the given Multiset
 /// </summary>
 /// <param name="other">Multiset</param>
 /// <returns></returns>
 public abstract bool IsDisjointWith(BaseMultiset other);
Exemplo n.º 50
0
        /// <summary>
        /// Does a Product of this Multiset and another Multiset
        /// </summary>
        /// <param name="other">Other Multiset</param>
        /// <returns></returns>
        public override BaseMultiset Product(BaseMultiset other)
        {
            if (other is IdentityMultiset) return this;
            if (other is NullMultiset) return other;
            if (other.IsEmpty) return new NullMultiset();

            Multiset productSet = new Multiset();
            foreach (ISet x in this.Sets)
            {
                foreach (ISet y in other.Sets)
                {
                    productSet.Add(x.Join(y));
                }
            }
            return productSet;
        }
Exemplo n.º 51
0
 /// <summary>
 /// Exists Join is the equivalent of Left Join where the Join is predicated on the existence/non-existince of an appropriate join candidate in the other multiset
 /// </summary>
 /// <param name="other">Multiset to join with</param>
 /// <param name="mustExist">Whether a valid join candidate must exist in the other multiset for sets from this multiset to be kept</param>
 /// <returns></returns>
 public abstract BaseMultiset ExistsJoin(BaseMultiset other, bool mustExist);
Exemplo n.º 52
0
 /// <summary>
 /// Minus Joins this Multiset to another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <returns></returns>
 public override BaseMultiset MinusJoin(BaseMultiset other)
 {
     //Identity is always disjoint with Minus so return Identity
     return this;
 }
Exemplo n.º 53
0
 /// <summary>
 /// Product combines two multisets that are disjoint
 /// </summary>
 /// <param name="other">Multiset to join with</param>
 /// <returns></returns>
 public abstract BaseMultiset Product(BaseMultiset other);
Exemplo n.º 54
0
 /// <summary>
 /// Generates the Union of this Set and another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <returns>The other Multiset</returns>
 public override BaseMultiset Union(BaseMultiset other)
 {
     //If Other is Null/Empty then the Join still results in Identity
     if (other is NullMultiset) return this;
     if (other.IsEmpty) return this;
     return other;
 }
Exemplo n.º 55
0
 private void ShowMultiset(BaseMultiset multiset) 
 {
     Console.WriteLine(multiset.GetType().ToString());
     foreach (Set s in multiset.Sets)
     {
         Console.WriteLine(s.ToString());
     }
     Console.WriteLine();
 }
Exemplo n.º 56
0
 /// <summary>
 /// Returns False since the Identity Multiset is not disjoint with anything
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <returns></returns>
 public override bool IsDisjointWith(BaseMultiset other)
 {
     return false;
 }
Exemplo n.º 57
0
 /// <summary>
 /// Left Joins another Multiset to this Null Mutliset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <param name="expr">Expression the join is predicate upon</param>
 /// <returns>
 /// Results in this Null Multiset since Null joined to anything is Null
 /// </returns>
 public override BaseMultiset LeftJoin(BaseMultiset other, ISparqlExpression expr)
 {
     //Left Outer Join results in Null Multiset
     return this;
 }
Exemplo n.º 58
0
 /// <summary>
 /// Joins another Multiset to this Null Mutliset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <returns>
 /// Results in this Null Multiset since Null joined to anything is Null
 /// </returns>
 public override BaseMultiset Join(BaseMultiset other)
 {
     //Left Join results in Null Multiset
     return this;
 }
Exemplo n.º 59
0
        private void EvalJoin(ISet y, List<String> joinVars, List<HashTable<INode, int>> values, List<List<int>> nulls, BaseMultiset joinedSet)
        {
            IEnumerable<int> possMatches = null;
            int i = 0;
            foreach (String var in joinVars)
            {
                INode value = y[var];
                if (value != null)
                {
                    if (values[i].ContainsKey(value))
                    {
                        possMatches = (possMatches == null ? values[i].GetValues(value).Concat(nulls[i]) : possMatches.Intersect(values[i].GetValues(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 ? this.SetIDs : possMatches.Intersect(this.SetIDs));
                }
                i++;
            }
            if (possMatches == null) return;

            //Now do the actual joins for the current set
            //Note - We access the dictionary directly here because going through the this[int id] method
            //incurs a Contains() call each time and we know the IDs must exist because they came from
            //our dictionary originally!
            foreach (int poss in possMatches)
            {
                if (this._sets[poss].IsCompatibleWith(y, joinVars))
                {
                    joinedSet.Add(this._sets[poss].Join(y));
                }
            }
        }
Exemplo n.º 60
0
 /// <summary>
 /// Minus Joins this Multiset to another Multiset
 /// </summary>
 /// <param name="other">Other Multiset</param>
 /// <returns></returns>
 public override BaseMultiset MinusJoin(BaseMultiset other)
 {
     return this;
 }