/// <summary> /// move outwards from check operation until operation to continue at is found /// appending restore isomorphy for isomorphy written on the way /// and final jump to operation to continue at /// </summary> private static void MoveOutwardsAppendingRemoveIsomorphyAndJump( CheckOperation checkOperation, string[] neededElementsForCheckOperation, SearchProgramOperation outermostOperation, SearchProgram topLevelSearchProgram) { // insertion point for candidate failed operations SearchProgramOperation insertionPoint = checkOperation.CheckFailedOperations; while (insertionPoint.Next != null) { insertionPoint = insertionPoint.Next; } // set outermost to iterated matching dummy loop if iterated if (outermostOperation is SearchProgramOfIterated) { SearchProgramOperation cur = checkOperation; while (!(cur is IteratedMatchingDummyLoop)) { cur = cur.Previous; } outermostOperation = cur; } SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy( checkOperation, ref insertionPoint, neededElementsForCheckOperation, outermostOperation, topLevelSearchProgram); // decide on type of continuing operation, then insert it // continue at top nesting level -> return SearchProgramOperation op = continuationPoint; while (!(op is SearchProgram)) { op = op.Previous; } SearchProgram searchProgramRoot = op as SearchProgram; if (continuationPoint == searchProgramRoot) { ContinueOperation continueByReturn = new ContinueOperation( ContinueOperationType.ByReturn, searchProgramRoot is SearchProgramOfAction || searchProgramRoot is SearchProgramOfActionParallelizationHead, searchProgramRoot is SearchProgramOfActionParallelizationBody ); insertionPoint.Append(continueByReturn); return; } // continue at directly enclosing nesting level -> continue op = checkOperation; do { op = op.Previous; }while(!op.IsSearchNestingOperation()); SearchProgramOperation directlyEnclosingOperation = op; if (continuationPoint == directlyEnclosingOperation // (check negative/independent is enclosing, but not a loop, thus continue wouldn't work) && !(directlyEnclosingOperation is CheckPartialMatchByNegative) && !(directlyEnclosingOperation is CheckPartialMatchByIndependent) // (check partial match for duplicate contains an internal loop in checking, thus continue wouldn't work) && !(checkOperation is CheckPartialMatchForDuplicate)) { ContinueOperation continueByContinue = new ContinueOperation(ContinueOperationType.ByContinue, directlyEnclosingOperation is GetCandidateByIterationParallel); insertionPoint.Append(continueByContinue); return; } // otherwise -> goto label string gotoLabelName; // if our continuation point is a candidate iteration // -> append label at the end of the loop body of the candidate iteration loop if (continuationPoint is GetCandidateByIteration) { GetCandidateByIteration candidateIteration = continuationPoint as GetCandidateByIteration; op = candidateIteration.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is a candidate iteration parallel // -> append label at the end of the loop body of the candidate iteration loop else if (continuationPoint is GetCandidateByIterationParallel) { GetCandidateByIterationParallel candidateIteration = continuationPoint as GetCandidateByIterationParallel; op = candidateIteration.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is a both directions iteration // -> append label at the end of the loop body of the both directions iteration loop else if (continuationPoint is BothDirectionsIteration) { BothDirectionsIteration bothDirections = continuationPoint as BothDirectionsIteration; op = bothDirections.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is an alternative case // -> append label at the end of the alternative case operations else if (continuationPoint is AlternativeCaseMatching) { AlternativeCaseMatching alternativeCase = continuationPoint as AlternativeCaseMatching; op = alternativeCase.OperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is the dummy loop of an iterated operation // -> we just jump to the label maxMatchesIterReached directly after the loop else if (continuationPoint is IteratedMatchingDummyLoop) { gotoLabelName = "maxMatchesIterReached"; } // otherwise our continuation point is a check negative/independent operation // -> insert label directly after the check negative/independent operation else { CheckPartialMatchByNegativeOrIndependent checkNegativeIndependent = continuationPoint as CheckPartialMatchByNegativeOrIndependent; GotoLabel gotoLabel = new GotoLabel(); checkNegativeIndependent.Insert(gotoLabel); gotoLabelName = gotoLabel.LabelName; } ContinueOperation continueByGoto = new ContinueOperation( ContinueOperationType.ByGoto, gotoLabelName); // ByGoto due to parameters insertionPoint.Append(continueByGoto); }
/// <summary> /// "listentrick": append search program operations to adjust list heads /// i.e. set list entry point to element after last found, /// so that next searching starts there - performance optimization /// (leave graph in the state of our last visit (searching it)) /// </summary> private static void MoveOutwardsAppendingListHeadAdjustment( CheckContinueMatchingMaximumMatchesReached checkMaximumMatches, bool inParallelizedBody) { // todo: avoid adjusting list heads twice for lookups of same type // insertion point for candidate failed operations SearchProgramOperation insertionPoint = checkMaximumMatches.CheckFailedOperations; SearchProgramOperation op = checkMaximumMatches; do { if (op is GetCandidateByIteration) { GetCandidateByIteration candidateByIteration = op as GetCandidateByIteration; if (candidateByIteration.Type == GetCandidateByIterationType.GraphElements) { AdjustListHeads adjustElements = new AdjustListHeads( AdjustListHeadsTypes.GraphElements, candidateByIteration.PatternElementName, candidateByIteration.IsNode, inParallelizedBody); insertionPoint = insertionPoint.Append(adjustElements); } else if (candidateByIteration.Type == GetCandidateByIterationType.IncidentEdges) { AdjustListHeads adjustIncident = new AdjustListHeads( AdjustListHeadsTypes.IncidentEdges, candidateByIteration.PatternElementName, candidateByIteration.StartingPointNodeName, candidateByIteration.EdgeType, inParallelizedBody); insertionPoint = insertionPoint.Append(adjustIncident); } } else if (op is GetCandidateByIterationParallel) { GetCandidateByIterationParallel candidateByIteration = op as GetCandidateByIterationParallel; if (candidateByIteration.Type == GetCandidateByIterationType.GraphElements) { AdjustListHeads adjustElements = new AdjustListHeads( AdjustListHeadsTypes.GraphElements, candidateByIteration.PatternElementName, candidateByIteration.IsNode, inParallelizedBody); insertionPoint = insertionPoint.Append(adjustElements); } else if (candidateByIteration.Type == GetCandidateByIterationType.IncidentEdges) { AdjustListHeads adjustIncident = new AdjustListHeads( AdjustListHeadsTypes.IncidentEdges, candidateByIteration.PatternElementName, candidateByIteration.StartingPointNodeName, candidateByIteration.EdgeType, inParallelizedBody); insertionPoint = insertionPoint.Append(adjustIncident); } } op = op.Previous; }while(op != null); }