Exemplo n.º 1
0
        /// <summary>
        /// Creates a Match object.
        /// </summary>
        /// <param name="graph"> A graph to conduct a query on. </param>
        /// <param name="variableMap"> An empty map of variables. </param>
        /// <param name="executionHelper"> A match execution helper. </param>
        /// <param name="matchNode"> A parse tree of match expression. </param>
        /// <param name="exprInfo"> A query expression information. </param>
        public MatchObject(Graph graph, VariableMap variableMap, IMatchExecutionHelper executionHelper, MatchNode matchNode, QueryExpressionInfo exprInfo)
        {
            if (executionHelper == null || matchNode == null || variableMap == null || graph == null)
            {
                throw new ArgumentNullException($"{this.GetType()}, passing null arguments to the constructor.");
            }

            this.helper = executionHelper;
            MatchVisitor matchVisitor = new MatchVisitor(graph.nodeTables, graph.edgeTables);

            matchNode.Accept(matchVisitor);

            // Create real pattern and variableMap.
            var result = matchVisitor.GetResult();

            this.CheckParsedPatternCorrectness(result);

            // Create  matcher and pattern based on the name of matcher and pattern.
            // Change if necessary .
            this.pattern = MatchFactory.CreatePattern(helper.ParallelPatternMatcherName, helper.PatternName, variableMap, result);

            // Now we have got enough information about results.
            // After creating pattern the variable map is filled and we know extend of the results.
            this.queryResults = new MatchFixedResults(this.helper.FixedArraySize, variableMap.GetCount(), executionHelper.ThreadCount);

            this.matcher = MatchFactory.CreateMatcher(helper.ParallelPatternMatcherName, pattern, graph, this.queryResults, executionHelper);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Builds a streamed version of a query from an input.
        /// Cannot contain order by and group by simultaneously.
        /// Called by static create method.
        /// </summary>
        /// <param name="tokens"> An input query.</param>
        /// <param name="graph"> A graph to compute the query on.</param>
        /// <param name="threadCount"> Maximum number of threads available to use.</param>
        /// <param name="printer"> A printer to use. </param>
        /// <param name="formater"> A formater to use by printer. </param>
        /// <param name="verticesPerThread"> A number of vertices distributed to threads during parallel computation of the query.</param>
        /// <param name="fileName">  A file to store results into if set, otherwise null. </param>
        /// <param name="isStreamed"> A flag to distinguish a normal construtor from streamed constructor.</param>
        /// <param name="allowPrint"> Whether to allow printing. Mainly for benchmarking purposes.</param>
        /// <param name="fixedArraySize"> The size of the arrays used for storing results of the matcher.</param>
        /// <param name="grouperAlias"> A grouper to use when specifying group by.</param>
        /// <param name="sorterAlias"> A sorter to use when specifying order by.</param>
        private Query(List <Token> tokens, Graph graph, bool allowPrint, int threadCount, PrinterType printer, FormaterType formater, int verticesPerThread, string fileName, GrouperAlias grouperAlias, SorterAlias sorterAlias, int fixedArraySize, bool isStreamed)
        {
            this.graph       = graph;
            this.variableMap = new VariableMap();
            this.qEhelper    = new QueryExecutionHelper(threadCount, printer, formater, verticesPerThread, fixedArraySize, fileName, "DFSParallelStreamed", "DFSSingleThreadStreamed", "SIMPLE", grouperAlias, sorterAlias);

            // Parse input query.
            var parsedClauses = Parser.Parse(tokens);

            if (parsedClauses.ContainsKey(Parser.Clause.OrderBy) && parsedClauses.ContainsKey(Parser.Clause.GroupBy))
            {
                throw new ArgumentException($"{this.GetType()}, the streamed version of the query cannot contain group by and order by at the same time.");
            }

            // MATCH is always leaf.
            MatchObjectStreamed match = (MatchObjectStreamed)QueryObject.Factory
                                            (typeof(MatchObjectStreamed), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.Match], null);

            // GROUP BY and obtain the aggregates and hashes -> the all necessary info is in the expressionInfo class.
            if (parsedClauses.ContainsKey(Parser.Clause.GroupBy))
            {
                this.exprInfo = new QueryExpressionInfo(true);
                GroupByResultProcessor.ParseGroupBy(graph, variableMap, qEhelper, (GroupByNode)parsedClauses[Parser.Clause.GroupBy], exprInfo);
            }
            else
            {
                this.exprInfo = new QueryExpressionInfo(false);
            }

            // SELECT is the last one to process the resuls.
            this.query = QueryObject.Factory
                             (typeof(SelectObject), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.Select], exprInfo);
            ((SelectObject)this.query).allowPrint = allowPrint;

            SetSingleGroupFlags();

            // ORDER BY
            if (parsedClauses.ContainsKey(Parser.Clause.OrderBy))
            {
                var comps       = OrderByResultProcessor.ParseOrderBy(graph, variableMap, qEhelper, (OrderByNode)parsedClauses[Parser.Clause.OrderBy], exprInfo, variableMap.GetCount());
                var orderByProc = OrderByResultProcessor.Factory(this.exprInfo, comps, qEhelper, variableMap.GetCount(), this.exprInfo.CollectUsedVariables());
                match.PassResultProcessor(orderByProc);
            }
            else
            {
                // Check if the query is aggregation and not a simple query.
                if ((this.exprInfo.Aggregates.Count == 0 && this.qEhelper.IsSetSingleGroupGroupBy) || (!this.qEhelper.IsSetSingleGroupGroupBy && !parsedClauses.ContainsKey(Parser.Clause.GroupBy)))
                {
                    throw new ArgumentException($"{this.GetType()}, no grouping or sorting was specified. The Streamed version allows to compute only aggregations. If you want to use only patter matching, please change to mode Normal.");
                }
                var groupByProc = GroupByResultProcessor.Factory(exprInfo, qEhelper, variableMap.GetCount(), this.exprInfo.CollectUsedVariables(), isStreamed);

                match.PassResultProcessor(groupByProc);
            }
            query.AddToEnd(match);
        }