Exemplo n.º 1
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
            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
            {
                // 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);
            }
#else
            // Use serial calculation which is likely to really suck for big products
            var productSet = new Multiset();
            foreach (var x in Sets)
            {
                foreach (var y in other.Sets)
                {
                    productSet.Add(x.Join(y));
                }
            }
            return(productSet);
#endif
        }
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 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.º 3
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.º 4
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.º 5
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.º 6
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.º 7
0
        private void EvalFilteredProduct(SparqlEvaluationContext context, ISet x, BaseMultiset other, PartitionedMultiset partitionedSet)
        {
            int id = partitionedSet.GetNextBaseID();

            foreach (ISet y in other.Sets)
            {
                id++;
                ISet z = x.Join(y);
                z.ID = id;
                partitionedSet.Add(z);
                try
                {
                    if (!this._expr.Evaluate(context, z.ID).AsSafeBoolean())
                    {
                        //Means the expression evaluates to false so we discard the solution
                        partitionedSet.Remove(z.ID);
                    }
                }
                catch
                {
                    //Means the solution does not meet the FILTER and can be discarded
                    partitionedSet.Remove(z.ID);
                }
            }
            //Remember to check for timeouts occassionally
            context.CheckTimeout();
        }
Exemplo n.º 8
0
        /// <summary>
        /// Evaluates the filtered product
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            BaseMultiset initialInput = context.InputMultiset;
            BaseMultiset lhsResults   = context.Evaluate(this._lhs);

            if (lhsResults is NullMultiset || lhsResults.IsEmpty)
            {
                //If LHS Results are Null/Empty then end result will always be null so short circuit
                context.OutputMultiset = new NullMultiset();
            }
            else
            {
                context.InputMultiset = initialInput;
                BaseMultiset rhsResults = context.Evaluate(this._rhs);
                if (rhsResults is NullMultiset || rhsResults.IsEmpty)
                {
                    //If RHS Results are Null/Empty then end results will always be null so short circuit
                    context.OutputMultiset = new NullMultiset();
                }
                else if (rhsResults is IdentityMultiset)
                {
                    //Apply Filter over LHS Results only - defer evaluation to filter implementation
                    context.InputMultiset = lhsResults;
                    UnaryExpressionFilter filter = new UnaryExpressionFilter(this._expr);
                    filter.Evaluate(context);
                    context.OutputMultiset = lhsResults;
                }
                else
                {
                    //Calculate the product applying the filter as we go
#if NET40 && !SILVERLIGHT
                    if (Options.UsePLinqEvaluation && this._expr.CanParallelise)
                    {
                        PartitionedMultiset partitionedSet;
                        SparqlResultBinder  binder = context.Binder;
                        if (lhsResults.Count >= rhsResults.Count)
                        {
                            partitionedSet = new PartitionedMultiset(lhsResults.Count, rhsResults.Count);
                            context.Binder = new LeviathanLeftJoinBinder(partitionedSet);
                            lhsResults.Sets.AsParallel().ForAll(x => this.EvalFilteredProduct(context, x, rhsResults, partitionedSet));
                        }
                        else
                        {
                            partitionedSet = new PartitionedMultiset(rhsResults.Count, lhsResults.Count);
                            context.Binder = new LeviathanLeftJoinBinder(partitionedSet);
                            rhsResults.Sets.AsParallel().ForAll(y => this.EvalFilteredProduct(context, y, lhsResults, partitionedSet));
                        }

                        context.Binder         = binder;
                        context.OutputMultiset = partitionedSet;
                    }
                    else
                    {
#endif
                    BaseMultiset productSet   = new Multiset();
                    SparqlResultBinder binder = context.Binder;
                    context.Binder = new LeviathanLeftJoinBinder(productSet);
                    foreach (ISet x in lhsResults.Sets)
                    {
                        foreach (ISet y in rhsResults.Sets)
                        {
                            ISet z = x.Join(y);
                            productSet.Add(z);
                            try
                            {
                                if (!this._expr.Evaluate(context, z.ID).AsSafeBoolean())
                                {
                                    //Means the expression evaluates to false so we discard the solution
                                    productSet.Remove(z.ID);
                                }
                            }
                            catch
                            {
                                //Means this solution does not meet the FILTER and can be discarded
                                productSet.Remove(z.ID);
                            }
                        }
                        //Remember to check for timeouts occassionaly
                        context.CheckTimeout();
                    }
                    context.Binder         = binder;
                    context.OutputMultiset = productSet;
#if NET40 && !SILVERLIGHT
                }
#endif
                }
            }
            return(context.OutputMultiset);
        }
Exemplo n.º 9
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
#if NET40
            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();
            }
#else
            var productSet = new Multiset();
#endif

            var stop = new StopToken();
            var t    = (int)Math.Min(timeout, int.MaxValue);
#if NET40 || NETSTANDARD1_4 || NETSTANDARD2_0
            var productTask = Task.Factory.StartNew(() => GenerateProduct(multiset, other, productSet, stop));
            if (!productTask.Wait(t))
            {
                stop.ShouldStop = true;
                productTask.Wait();
            }

            return(productSet);
#else
            GenerateProductDelegate d = new GenerateProductDelegate(GenerateProduct);
            IAsyncResult            r = d.BeginInvoke(multiset, other, productSet, stop, null, null);
            // Wait
            r.AsyncWaitHandle.WaitOne(t);
            if (!r.IsCompleted)
            {
                stop.ShouldStop = true;
                r.AsyncWaitHandle.WaitOne();
            }
            return(productSet);
#endif
        }
Exemplo n.º 10
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 virtual 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 = Variables.Where(v => other.Variables.Contains(v)).ToList();

            if (joinVars.Count == 0)
            {
#if NET40
                if (Options.UsePLinqEvaluation && expr.CanParallelise)
                {
                    PartitionedMultiset partitionedSet = new PartitionedMultiset(this.Count, other.Count + 1);
                    this.Sets.AsParallel().ForAll(x => EvalLeftJoinProduct(x, other, partitionedSet, expr));
                    return(partitionedSet);
                }
#endif
                // Do a serial Left Join Product

                // Calculate a Product filtering as we go
                foreach (ISet x in Sets)
                {
                    bool standalone = false;
                    bool matched    = 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;
                            }
                            else
                            {
                                matched = true;
                            }
                        }
                        catch
                        {
                            joinedSet.Remove(z.ID);
                            standalone = true;
                        }
                    }
                    if (standalone && !matched)
                    {
                        joinedSet.Add(x.Copy());
                    }
                }
#if NET40
#endif
            }
            else
            {
                // 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 <MultiDictionary <INode, List <int> > > values = new List <MultiDictionary <INode, List <int> > >();
                List <List <int> > nulls = new List <List <int> >();
                foreach (String var in joinVars)
                {
                    joinedSet.AddVariable(var);
                    values.Add(new MultiDictionary <INode, List <int> >(new FastVirtualNodeComparer()));
                    nulls.Add(new List <int>());
                }

                // First do a pass over the RHS Result to find all possible values for joined variables
                foreach (ISet y in other.Sets)
                {
                    int i = 0;
                    foreach (String var in joinVars)
                    {
                        INode value = y[var];
                        if (value != null)
                        {
                            if (values[i].TryGetValue(value, out List <int> ids))
                            {
                                ids.Add(y.ID);
                            }
                            else
                            {
                                values[i].Add(value, new List <int> {
                                    y.ID
                                });
                            }
                        }
                        else
                        {
                            nulls[i].Add(y.ID);
                        }
                        i++;
                    }
                }

                // Then do a pass over the LHS and work out the intersections
#if NET40
                if (Options.UsePLinqEvaluation && expr.CanParallelise)
                {
                    this.Sets.AsParallel().ForAll(x => EvalLeftJoin(x, other, joinVars, values, nulls, joinedSet, subcontext, expr));
                }
                else
                {
                    // Use a Serial Left Join
                    foreach (ISet x in this.Sets)
                    {
                        this.EvalLeftJoin(x, other, joinVars, values, nulls, joinedSet, subcontext, expr);
                    }
                }
#else
                // Use a Serial Left Join
                foreach (var x in Sets)
                {
                    EvalLeftJoin(x, other, joinVars, values, nulls, joinedSet, subcontext, expr);
                }
#endif
            }
            return(joinedSet);
        }