protected override UpInfo BeforePopDependency(Stack <Dependency> currentPath, bool isEnd, bool isLoopBack, CountedEnum counted, PathInfo down, PathInfo here, UpInfo upSum, UpInfo childUp) { Dependency top = currentPath.Peek(); bool isEndOfCycle = _onPath.Get(top.UsedItem) > 0; if (childUp.FoundPathBelow || isEnd || isEndOfCycle) { _countedObjectsPerItem .GetOrAdd(top.UsedItem, () => new HashSet <IMatchableObject>()) .Add(down.CountedObject); } if (isEnd || isEndOfCycle) { if (_ignorePrefixPaths && childUp.FoundPathBelow) { // don't add this prefix path to list of found paths; however, the node will // be reached and have its correct end flag } else { _foundPaths.Add(here); } return(new UpInfo(true)); } else { return(new UpInfo(upSum.FoundPathBelow | childUp.FoundPathBelow)); } }
protected override DownAndHere AfterPushDependency(Stack <Dependency> currentPath, bool isEnd, bool isLoopBack, CountedEnum counted, PathInfo down) { Dependency top = currentPath.Peek(); PathNode pathNode = new PathNode(down.Tail, top, isEnd, isMatchedByCountSymbol: counted != CountedEnum.NotCounted, isEndOfCycle: isLoopBack); PathInfo downInfo = new PathInfo(down.Root, down.RootIsCounted, counted == CountedEnum.DependencyCounted ? top : counted == CountedEnum.UsedItemCounted ? top.UsedItem : down.CountedObject, pathNode); return(new DownAndHere(downInfo, downInfo)); }
protected override DownAndHere AfterPushDependency(Stack <Dependency> currentPath, bool isEnd, bool isLoopBack, CountedEnum counted, Ignore down) { if (isEnd) { _recordedPaths.Add(string.Join("/", currentPath.Reverse())); switch (counted) { case CountedEnum.DependencyCounted: _countedObjects.Add(currentPath.Peek()); break; case CountedEnum.UsedItemCounted: _countedObjects.Add(currentPath.Peek().UsedItem); break; } } return(new DownAndHere(Ignore.Om, Ignore.Om)); }
protected override Ignore BeforePopDependency(Stack <Dependency> currentPath, bool isEnd, bool isLoopBack, CountedEnum counted, Ignore down, Ignore here, Ignore upSum, Ignore childUp) { return(Ignore.Om); }
protected abstract TUpInfo BeforePopDependency(Stack <TDependency> currentPath, bool isEnd, bool isLoopBack, CountedEnum counted, TDownInfo down, THereInfo here, TUpInfo upSum, TUpInfo childUp);
protected abstract DownAndHere AfterPushDependency(Stack <TDependency> currentPath, bool isEnd, bool isLoopBack, CountedEnum counted, TDownInfo down);
private TUpInfo Traverse([NotNull] TItem tail, [NotNull] Dictionary <TItem, TDependency[]> incidentDependencies, IBeforeDependencyGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeDependencyState, TDownInfo rawDown, HashSet <TPathState> statesOnPath) { if (!beforeDependencyState.CanContinue) { throw new ArgumentException("Traverse must be called with continueable state", nameof(beforeDependencyState)); } _checkAbort(); TUpInfo upSum; bool visitSuccessors = ShouldVisitSuccessors(tail, _currentPath, out upSum); if (visitSuccessors) { // We are at this item for the first time - check whether we find a path to some defined end TDependency[] dependencies; if (!incidentDependencies.TryGetValue(tail, out dependencies)) { dependencies = NO_DEPENDENCIES; } foreach (var nextDep in dependencies) { bool dependencyIsCounted; IBeforeItemGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeItemState = beforeDependencyState.Advance(nextDep, (m, d) => m.IsMatch(d), out dependencyIsCounted); if (beforeItemState.CanContinue) { TItem nextTail = nextDep.UsedItem; bool atEnd; bool itemIsCounted; IBeforeDependencyGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeNextDependencyState = beforeItemState.Advance(nextTail, (m, i) => ItemMatch.IsMatch(m, i), out atEnd, out itemIsCounted); _currentPath.Push(nextDep); CountedEnum counted = dependencyIsCounted ? CountedEnum.DependencyCounted : itemIsCounted ? CountedEnum.UsedItemCounted : CountedEnum.NotCounted; var stateElement = CreateStateElement(beforeNextDependencyState, nextDep); bool newOnPath = statesOnPath.Add(stateElement); DownAndHere downAndHere = AfterPushDependency(_currentPath, atEnd, !newOnPath, counted, rawDown); TUpInfo childUp; if (_currentPath.Count < _maxRecursionDepth && beforeNextDependencyState.CanContinue && newOnPath) { childUp = Traverse(nextTail, incidentDependencies, beforeNextDependencyState, downAndHere.Down, statesOnPath); statesOnPath.Remove(stateElement); } else { childUp = default(TUpInfo); // ??? as above ____ } upSum = BeforePopDependency(_currentPath, atEnd, !newOnPath, counted, rawDown, downAndHere.Save, upSum, childUp); _currentPath.Pop(); } } } upSum = AfterVisitingSuccessors(visitSuccessors, tail, _currentPath, upSum); return(upSum); }