Example #1
0
 /// <summary>
 /// Instantiates a new PatternEdge object
 /// </summary>
 /// <param name="fixedDirection">Whether this pattern edge should be matched with a fixed direction or not.</param>
 /// <param name="typeID">The type ID of the pattern edge.</param>
 /// <param name="type">The GrGen type of the pattern edge.</param>
 /// <param name="typeName">The name of the type interface of the pattern element.</param>
 /// <param name="name">The name of the pattern edge.</param>
 /// <param name="unprefixedName">Pure name of the pattern element as specified in the .grg without any prefixes</param>
 /// <param name="allowedTypes">An array of allowed types for this pattern element.
 ///     If it is null, all subtypes of the type specified by typeID (including itself)
 ///     are allowed for this pattern element.</param>
 /// <param name="isAllowedType">An array containing a bool for each edge type (order defined by the TypeIDs)
 ///     which is true iff the corresponding type is allowed for this pattern element.
 ///     It should be null if allowedTypes is null or empty or has only one element.</param>
 /// <param name="cost"> default cost/priority from frontend, user priority if given</param>
 /// <param name="parameterIndex">Specifies to which rule parameter this pattern element corresponds</param>
 /// <param name="maybeNull">Tells whether this pattern edge may be null (is a parameter if true).</param>
 /// <param name="storage">If not null this edge is to be bound by iterating the given storage.</param>
 /// <param name="storageIndex">If not null this edge is to be determined by a storage lookup,
 ///     with the accessor given here applied as index into the storage given in the storage parameter.</param>
 /// <param name="indexAccess">If not null this pattern element is to be determined by an index lookup, with details specified by the concrete index access type contained in this field.</param>
 /// <param name="nameLookup">If not null this pattern element is to be determined by a name map lookup.</param>
 /// <param name="uniqueLookup">If not null this pattern element is to be determined by a unique index lookup.</param>
 /// <param name="elementBeforeCasting">If not null this pattern node is to be bound by casting the given elementBeforeCasting to the pattern node type or causing matching to fail.</param>
 /// <param name="defToBeYieldedTo">Iff true the element is only defined in its PointOfDefinition pattern,
 ///     it gets matched in another, nested or called pattern which yields it to the containing pattern.</param>
 /// <param name="initialization">The initialization expression for the edge if some was defined, 
 ///     only possible for defToBeYieldedTo edges, otherwise null.</param>
 public PatternEdge(bool fixedDirection,
     int typeID, EdgeType type, String typeName, 
     String name, String unprefixedName,
     GrGenType[] allowedTypes, bool[] isAllowedType,
     float cost, int parameterIndex, bool maybeNull,
     StorageAccess storage, StorageAccessIndex storageIndex,
     IndexAccess indexAccess, NameLookup nameLookup, UniqueLookup uniqueLookup,
     PatternElement elementBeforeCasting,
     bool defToBeYieldedTo, Expression initialization)
     : base(typeID, typeName, name, unprefixedName, allowedTypes, isAllowedType,
         cost, parameterIndex, maybeNull, storage, storageIndex, indexAccess, nameLookup, uniqueLookup,
         elementBeforeCasting, defToBeYieldedTo, initialization)
 {
     this.fixedDirection = fixedDirection;
     this.type = type;
 }
Example #2
0
 /// <summary>
 /// Instantiates a new PatternElement object as a copy from an original element, used for independent inlining.
 /// </summary>
 /// <param name="original">The original pattern element to be copy constructed.</param>
 /// <param name="nameSuffix">The suffix to be added to the name of the pattern element (to avoid name collisions).</param>
 public PatternElement(PatternElement original, String nameSuffix)
 {
     TypeID = original.TypeID;
     typeName = original.typeName;
     name = original.name + nameSuffix;
     unprefixedName = original.unprefixedName + nameSuffix;
     pointOfDefinition = original.pointOfDefinition;
     defToBeYieldedTo = original.defToBeYieldedTo;
     initialization = original.initialization != null ? original.initialization.Copy(nameSuffix) : null;
     annotations = original.annotations;
     AllowedTypes = original.AllowedTypes;
     IsAllowedType = original.IsAllowedType;
     Cost = original.Cost;
     ParameterIndex = original.ParameterIndex;
     MaybeNull = original.MaybeNull;
     Storage = original.Storage != null ? new StorageAccess(original.Storage) : null;
     StorageIndex = original.StorageIndex != null ? new StorageAccessIndex(original.StorageIndex) : null;
     IndexAccess = original.IndexAccess != null ? original.IndexAccess.Copy(nameSuffix) : null;
     NameLookup = original.NameLookup != null ? original.NameLookup.Copy(nameSuffix) : null;
     UniqueLookup = original.UniqueLookup != null ? original.UniqueLookup.Copy(nameSuffix) : null;
     ElementBeforeCasting = original.ElementBeforeCasting;
     AssignmentSource = original.AssignmentSource;
     OriginalIndependentElement = original;
 }
        /// <summary>
        /// Search program operations implementing the
        /// parallelized PickFromIndex search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelPickFromIndex(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            IndexAccess index,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = "";
            string iterationType = TypesHelper.TypeName(index.Index is AttributeIndexDescription ?
                ((AttributeIndexDescription)index.Index).GraphElementType :
                ((IncidenceCountIndexDescription)index.Index).StartNodeType);
            string indexSetType = NamesOfEntities.IndexSetType(model.ModelName);

            // iterate available index elements
            GetCandidateByIterationParallel elementsIteration;
            if(index is IndexAccessEquality)
            {
                IndexAccessEquality indexEquality = (IndexAccessEquality)index;
                SourceBuilder equalityExpression = new SourceBuilder();
                indexEquality.Expr.Emit(equalityExpression);
                elementsIteration =
                    new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Equality,
                        equalityExpression.ToString(),
                        isNode,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            else if(index is IndexAccessAscending)
            {
                IndexAccessAscending indexAscending = (IndexAccessAscending)index;
                SourceBuilder fromExpression = new SourceBuilder();
                if(indexAscending.From != null)
                    indexAscending.From.Emit(fromExpression);
                SourceBuilder toExpression = new SourceBuilder();
                if(indexAscending.To != null)
                    indexAscending.To.Emit(toExpression);
                elementsIteration =
                    new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Ascending,
                        indexAscending.From != null ? fromExpression.ToString() : null,
                        indexAscending.IncludingFrom,
                        indexAscending.To != null ? toExpression.ToString() : null,
                        indexAscending.IncludingTo,
                        isNode,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            else //if(index is IndexAccessDescending)
            {
                IndexAccessDescending indexDescending = (IndexAccessDescending)index;
                SourceBuilder fromExpression = new SourceBuilder();
                if(indexDescending.From != null)
                    indexDescending.From.Emit(fromExpression);
                SourceBuilder toExpression = new SourceBuilder();
                if(indexDescending.To != null)
                    indexDescending.To.Emit(toExpression);
                elementsIteration =
                    new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Descending,
                        indexDescending.From != null ? fromExpression.ToString() : null,
                        indexDescending.IncludingFrom,
                        indexDescending.To != null ? toExpression.ToString() : null,
                        indexDescending.IncludingTo,
                        isNode,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            firstLoopPassed = true;

            SearchProgramOperation continuationPoint =
                insertionPoint.Append(elementsIteration);
            elementsIteration.NestedOperationsList =
                new SearchProgramList(elementsIteration);
            insertionPoint = elementsIteration.NestedOperationsList;

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

            //---------------------------------------------------------------------------
            // build next operation
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                currentOperationIndex + 1,
                insertionPoint);
            //---------------------------------------------------------------------------

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within candidate iteration built by now -
            // continue at the end of the list after storage iteration
            insertionPoint = continuationPoint;

            return insertionPoint;
        }
Example #4
0
        ////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Instantiates a new PatternElement object.
        /// </summary>
        /// <param name="typeID">The type ID of the pattern element.</param>
        /// <param name="typeName">The name of the type interface of the pattern element.</param>
        /// <param name="name">The name of the pattern element.</param>
        /// <param name="unprefixedName">Pure name of the pattern element as specified in the .grg without any prefixes</param>
        /// <param name="allowedTypes">An array of allowed types for this pattern element.
        ///     If it is null, all subtypes of the type specified by typeID (including itself)
        ///     are allowed for this pattern element.</param>
        /// <param name="isAllowedType">An array containing a bool for each node/edge type (order defined by the TypeIDs)
        ///     which is true iff the corresponding type is allowed for this pattern element.
        ///     It should be null if allowedTypes is null or empty or has only one element.</param>
        /// <param name="cost">Default cost/priority from frontend, user priority if given.</param>
        /// <param name="parameterIndex">Specifies to which rule parameter this pattern element corresponds.</param>
        /// <param name="maybeNull">Tells whether this pattern element may be null (is a parameter if true).</param>
        /// <param name="storage">If not null this pattern element is to be bound by iterating the given storage.</param>
        /// <param name="storageIndex">If not null this pattern element is to be determined by a storage lookup,
        ///     with the accessor given here applied as index into the storage given in the storage parameter.</param>
        /// <param name="indexAccess">If not null this pattern element is to be determined by an index lookup, with details specified by the concrete index access type contained in this field.</param>
        /// <param name="nameLookup">If not null this pattern element is to be determined by a name map lookup.</param>
        /// <param name="uniqueLookup">If not null this pattern element is to be determined by a unique index lookup.</param>
        /// <param name="elementBeforeCasting">If not null this pattern node is to be bound by casting the given elementBeforeCasting to the pattern node type or causing matching to fail.</param>
        /// <param name="defToBeYieldedTo">Iff true the element is only defined in its PointOfDefinition pattern,
        ///     it gets matched in another, nested or called pattern which yields it to the containing pattern.</param>
        /// <param name="initialization">The initialization expression for the element if some was defined, 
        ///     only possible for defToBeYieldedTo elements, otherwise null.</param>
        public PatternElement(int typeID, String typeName, 
            String name, String unprefixedName, 
            GrGenType[] allowedTypes, bool[] isAllowedType, 
            float cost, int parameterIndex, bool maybeNull,
            StorageAccess storage, StorageAccessIndex storageIndex,
            IndexAccess indexAccess, NameLookup nameLookup, UniqueLookup uniqueLookup,
            PatternElement elementBeforeCasting,
            bool defToBeYieldedTo, Expression initialization)
        {
            this.TypeID = typeID;
            this.typeName = typeName;
            this.name = name;
            this.unprefixedName = unprefixedName;
            this.AllowedTypes = allowedTypes;
            this.IsAllowedType = isAllowedType;
            this.Cost = cost;
            this.ParameterIndex = parameterIndex;
            this.MaybeNull = maybeNull;
            this.Storage = storage;
            this.StorageIndex = storageIndex;
            this.IndexAccess = indexAccess;
            this.NameLookup = nameLookup;
            this.UniqueLookup = uniqueLookup;
            this.ElementBeforeCasting = elementBeforeCasting;
            this.defToBeYieldedTo = defToBeYieldedTo;
            this.initialization = initialization;
            // TODO: the last parameters are (mostly) mutually exclusive, 
            // introduce some abstract details class with specialized classed for the different cases,
            // only one instance needed instead of the large amount of mostly null valued variables now
            // better now with the introduction of helper classes for StorageAccess and StorageAccessIndex, but could be improved further
        }
        /// <summary>
        /// Search program operations implementing the
        /// setup parallelized PickFromIndex search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelPickFromIndexSetup(
            SearchProgramOperation insertionPoint,
            SearchPlanNode target,
            IndexAccess index)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = "";
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();
            string iterationType = TypesHelper.TypeName(index.Index is AttributeIndexDescription ?
                ((AttributeIndexDescription)index.Index).GraphElementType :
                ((IncidenceCountIndexDescription)index.Index).StartNodeType);
            string indexSetType = NamesOfEntities.IndexSetType(model.ModelName);

            // iterate available index elements
            GetCandidateByIterationParallelSetup elementsIteration;
            if(index is IndexAccessEquality)
            {
                IndexAccessEquality indexEquality = (IndexAccessEquality)index;
                SourceBuilder equalityExpression = new SourceBuilder();
                indexEquality.Expr.Emit(equalityExpression);
                elementsIteration =
                    new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Equality,
                        equalityExpression.ToString(),
                        isNode,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            else if(index is IndexAccessAscending)
            {
                IndexAccessAscending indexAscending = (IndexAccessAscending)index;
                SourceBuilder fromExpression = new SourceBuilder();
                if(indexAscending.From != null)
                    indexAscending.From.Emit(fromExpression);
                SourceBuilder toExpression = new SourceBuilder();
                if(indexAscending.To != null)
                    indexAscending.To.Emit(toExpression);
                elementsIteration =
                    new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Ascending,
                        indexAscending.From != null ? fromExpression.ToString() : null,
                        indexAscending.IncludingFrom,
                        indexAscending.To != null ? toExpression.ToString() : null,
                        indexAscending.IncludingTo,
                        isNode,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            else //if(index is IndexAccessDescending)
            {
                IndexAccessDescending indexDescending = (IndexAccessDescending)index;
                SourceBuilder fromExpression = new SourceBuilder();
                if(indexDescending.From != null)
                    indexDescending.From.Emit(fromExpression);
                SourceBuilder toExpression = new SourceBuilder();
                if(indexDescending.To != null)
                    indexDescending.To.Emit(toExpression);
                elementsIteration =
                    new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Descending,
                        indexDescending.From != null ? fromExpression.ToString() : null,
                        indexDescending.IncludingFrom,
                        indexDescending.To != null ? toExpression.ToString() : null,
                        indexDescending.IncludingTo,
                        isNode,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            return insertionPoint.Append(elementsIteration);
        }