예제 #1
0
        /// <summary>
        /// If some node has no dependency, we will take it into consideration
        /// </summary>
        /// <param name="aggregationBlock"></param>
        /// <param name="predicateLinksAccessedTableAliases"></param>
        /// <returns></returns>
        public List <ExecutionOrder> GenerateNextOrders(
            AggregationBlock aggregationBlock,
            List <Tuple <PredicateLink, HashSet <string> > > predicateLinksAccessedTableAliases)
        {
            // Find all possible next tuples
            List <Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > > nextTuples =
                new List <Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > >();

            foreach (KeyValuePair <string, HashSet <string> > pair in aggregationBlock.TableInputDependency)
            {
                if (!this.ExistingNodesAndEdges.Contains(pair.Key) && this.ExistingNodesAndEdges.IsSupersetOf(pair.Value))
                {
                    CompileNode node;
                    aggregationBlock.TryGetNode(pair.Key, out node);
                    nextTuples.AddRange(this.GenerateTuples(predicateLinksAccessedTableAliases, node));
                }
            }

            // Generate all possible next orders
            List <ExecutionOrder> nextOrders = new List <ExecutionOrder>();

            foreach (Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > tuple in nextTuples)
            {
                ExecutionOrder nextOrder = this.Duplicate();
                nextOrder.AddTuple(tuple);
                nextOrders.Add(nextOrder);
            }
            return(nextOrders);
        }
예제 #2
0
        public virtual ExecutionOrder GetLocalExecutionOrder(ExecutionOrder parentExecutionOrder)
        {
            ExecutionOrder executionOrder = new ExecutionOrder();

            executionOrder.Order.Add(new Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> >(
                                         null, null, null, null, new List <ExecutionOrder>()));
            return(executionOrder);
        }
예제 #3
0
 /// <summary>
 /// This constructor is used to transfer information to subquery
 /// </summary>
 /// <param name="executionOrder"></param>
 public ExecutionOrder(ExecutionOrder executionOrder)
 {
     this.Order = new List <Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > >();
     this.ExistingNodesAndEdges  = new HashSet <string>(executionOrder.ExistingNodesAndEdges);
     this.ExistingPredicateLinks = new HashSet <string>(executionOrder.ExistingPredicateLinks);
     // It is important that the readyEdges should be empty.
     // If the parentOrder has some readyEdges and this order records, the subquery cannot remove edges from readyEdges
     // because it could see the information from parent's aggregationBlock
     this.ReadyEdges = new HashSet <string>();
     this.Cost       = 0.0;
 }
예제 #4
0
 public QueryCompilationContext()
 {
     TemporaryTableCollection = new Dictionary <string, Tuple <TemporaryTableHeader, GraphViewExecutionOperator> >();
     RawRecordLayout          = new Dictionary <WColumnReferenceExpression, int>(new WColumnReferenceExpressionComparer());
     TableReferences          = new HashSet <string>();
     SideEffectStates         = new Dictionary <string, AggregateState>();
     SideEffectFunctions      = new Dictionary <string, IAggregateFunction>();
     CarryOn               = false;
     Containers            = new List <Container>();
     CurrentExecutionOrder = new ExecutionOrder();
     LocalExecutionOrders  = new List <ExecutionOrder>();
 }
예제 #5
0
 public override ExecutionOrder GetLocalExecutionOrder(ExecutionOrder parentExecutionOrder)
 {
     if (this.TableReference != null)
     {
         return(this.TableReference.GetLocalExecutionOrder(parentExecutionOrder));
     }
     else
     {
         ExecutionOrder executionOrder = new ExecutionOrder();
         executionOrder.Order.Add(new Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> >(
                                      null, null, null, null, new List <ExecutionOrder>()));
         return(executionOrder);
     }
 }
예제 #6
0
 public QueryCompilationContext(QueryCompilationContext parentContext)
 {
     CurrentExecutionOperator = parentContext.CurrentExecutionOperator;
     TemporaryTableCollection = parentContext.TemporaryTableCollection;
     RawRecordLayout          = new Dictionary <WColumnReferenceExpression, int>(parentContext.RawRecordLayout,
                                                                                 new WColumnReferenceExpressionComparer());
     TableReferences = new HashSet <string>(parentContext.TableReferences);
     OuterContextOp  = new EnumeratorOperator();
     CarryOn         = false;
     ParentContextRawRecordLayout = new Dictionary <WColumnReferenceExpression, int>(
         parentContext.RawRecordLayout, new WColumnReferenceExpressionComparer());
     SideEffectStates      = parentContext.SideEffectStates;
     SideEffectFunctions   = parentContext.SideEffectFunctions;
     Containers            = parentContext.Containers;
     CurrentExecutionOrder = new ExecutionOrder(parentContext.CurrentExecutionOrder);
     LocalExecutionOrders  = new List <ExecutionOrder>();
 }
        /// <summary>
        /// Every time, we will generate multiple next orders from queue[index]. If some of them are finished, we put these into queue[1 - index].
        /// If the size of candidate orders equals or exceeds the upper bound, we will leave a predetermined number of best partial solutions.
        /// </summary>
        /// <param name="tableReferences"></param>
        /// <returns></returns>
        internal ExecutionOrder GenerateOptimalExecutionOrder(ExecutionOrder parentExecutionOrder)
        {
            // Two queues, queue[index] keeps forthcoming orders and queue[1 - index] keeps results from queue[index]
            int queueIndex = 0, blockIndex = 0;
            int blocksCount = this.blocks.Count;
            List <List <ExecutionOrder> > queue = new List <List <ExecutionOrder> >
            {
                new List <ExecutionOrder>(),
                new List <ExecutionOrder>()
            };

            queue[queueIndex].Add(new ExecutionOrder(parentExecutionOrder));

            while (blockIndex < blocksCount)
            {
                // Firstly, we need to add the root table
                foreach (ExecutionOrder currentOrder in queue[queueIndex])
                {
                    currentOrder.AddRootTable(this.blocks[blockIndex], this.predicateLinksAccessedTableAliases);
                }

                int numberOfIterations = this.blocks[blockIndex].TableInputDependency.Count - 1;

                while (numberOfIterations-- > 0)
                {
                    foreach (ExecutionOrder currentOrder in queue[queueIndex])
                    {
                        List <ExecutionOrder> nextOrders = currentOrder.GenerateNextOrders(this.blocks[blockIndex],
                                                                                           this.predicateLinksAccessedTableAliases);
                        if (nextOrders.Count > MaxNumberOfOrders)
                        {
                            nextOrders.Sort(new ExecutionOrderComparer());
                            queue[1 - queueIndex].AddRange(nextOrders.GetRange(0, MaxNumberOfOrders));
                        }
                        else
                        {
                            queue[1 - queueIndex].AddRange(nextOrders);
                        }
                    }
                    queue[queueIndex].Clear();
                    if (queue[1 - queueIndex].Count > MaxNumberOfOrders)
                    {
                        queue[1 - queueIndex].Sort(new ExecutionOrderComparer());
                        queue[1 - queueIndex] = queue[1 - queueIndex].GetRange(0, MaxNumberOfOrders);
                    }
                    queueIndex = 1 - queueIndex;
                }

                // Finally, check whether there is any ready edge. If there is, we discard this order
                for (int index = queue[queueIndex].Count - 1; index >= 0; --index)
                {
                    if (queue[queueIndex][index].ReadyEdges.Any())
                    {
                        queue[queueIndex].RemoveAt(index);
                    }
                }
                ++blockIndex;
            }

            queue[queueIndex].Sort(new ExecutionOrderComparer());
            return(queue[queueIndex].First());
        }
예제 #8
0
 public ParentLink(ExecutionOrder parentExecutionOrder)
 {
     this.LinkAlias            = parentExecutionOrder.Order.Last().Item1.NodeAlias + "->";
     this.ParentExecutionOrder = parentExecutionOrder.Duplicate();
 }