protected void Render(IEnumerable <Dependency> edges, ItemMatch innerMatchOrNull, [NotNull] ITargetWriter output, int?labelWidthOrNull, bool withNotOkCt) { IDictionary <Item, IEnumerable <Dependency> > itemsAndDependencies = Dependency.Dependencies2ItemsAndDependencies(edges); var innerAndReachableOuterItems = new HashSet <Item>(itemsAndDependencies.Where(n => ItemMatch.IsMatch(innerMatchOrNull, n.Key)).SelectMany(kvp => new[] { kvp.Key }.Concat(kvp.Value.Select(e => e.UsedItem)))); IEnumerable <Item> sortedItems = MoreOrLessTopologicalSort(edges).Where(n => innerAndReachableOuterItems.Contains(n)); if (sortedItems.Any()) { int m = 0; Dictionary <Item, int> item2Index = sortedItems.ToDictionary(n => n, n => ++ m); IEnumerable <Item> topItems = sortedItems.Where(n => ItemMatch.IsMatch(innerMatchOrNull, n)); int labelWidth = labelWidthOrNull ?? Math.Max(Math.Min(sortedItems.Max(n => n.Name.Length), 30), 4); int colWidth = Math.Max(1 + ("" + edges.Max(e => e.Ct)).Length, // 1+ because of loop prefix 1 + ("" + sortedItems.Count()).Length); // 1+ because of ! or % marker string itemFormat = "{0," + (colWidth - 1) + ":" + Repeat('0', colWidth - 1) + "}"; string ctFormat = "{0}{1," + (colWidth - 1) + ":" + Repeat('#', colWidth) + "}"; Write(output, colWidth, labelWidth, topItems, itemFormat, item2Index, withNotOkCt, sortedItems, ctFormat, itemsAndDependencies); } else { Log.WriteError("No visible items and dependencies found for output"); } }
public bool Matches([CanBeNull] IEnumerable <Dependency> incoming, Item i, [CanBeNull] IEnumerable <Dependency> outgoing) { return((_atLeastOneIncomingDependencyPattern == null || incoming != null && incoming.Any(d => _atLeastOneIncomingDependencyPattern.IsMatch(d))) && ItemMatch.IsMatch(_itemMatch, i) && (_atLeastOneOutgoingDependencyPattern == null || outgoing != null && outgoing.Any(d => _atLeastOneOutgoingDependencyPattern.IsMatch(d)))); }
private IEnumerable <Item> LogOnlyItemCount(string pattern) { ItemMatch m = pattern == null ? null : new ItemMatch(pattern, IgnoreCase, anyWhereMatcherOk: true); IEnumerable <Item> allItems = new HashSet <Item>(CurrentGraph.VisibleDependencies.SelectMany(d => new[] { d.UsingItem, d.UsedItem })); IEnumerable <Item> matchingItems = allItems.Where(i => ItemMatch.IsMatch(m, i)); Log.WriteInfo(matchingItems.Count() + " items" + (m == null ? "" : " matching " + pattern)); return(matchingItems); }
public FindCycleDepsPathFinder([NotNull, ItemNotNull] IEnumerable <TDependency> dependencies, [CanBeNull] ItemMatch cycleAnchorsMatch, bool ignoreSelfCycles, int maxCycleLength, [NotNull] Action <int, Stack <TDependency>, string> recordNewCycleToRoot, [NotNull, ItemCanBeNull] AbstractPathMatch <TDependency, TItem>[] expectedPathMatches, Action checkAbort) : base(checkAbort) { Dictionary <TItem, TDependency[]> outgoing = AbstractItem <TItem> .CollectOutgoingDependenciesMap(dependencies); _maxCycleLength = maxCycleLength; _ignoreSelfCycles = ignoreSelfCycles; _recordNewCycleToRoot = recordNewCycleToRoot; IEnumerable <TItem> roots = outgoing.Keys.Where(i => ItemMatch.IsMatch(cycleAnchorsMatch, i)); _addIndexToMarkerFormat = "D" + ("" + roots.Count() / 2).Length; foreach (var root in roots.OrderBy(i => i.Name)) { _root = root; _visited2RestLength = new Dictionary <TItem, int>(); Traverse(root, outgoing, expectedPathMatches, endMatch: null, down: Ignore.Om); } }
private void Render([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, [NotNull] ITargetWriter output, ItemMatch innerMatch, int?maxExampleLength) { IDictionary <Item, IEnumerable <Dependency> > itemsAndDependencies = Dependency.Dependencies2ItemsAndDependencies(dependencies); output.WriteLine("digraph D {"); output.WriteLine("ranksep = 1.5;"); foreach (var n in itemsAndDependencies.Keys.OrderBy(n => n.Name)) { output.WriteLine("\"" + n.Name + "\" [shape=" + (ItemMatch.IsMatch(innerMatch, n) ? "box,style=bold" : "oval") + "];"); } output.WriteLine(); foreach (var n in itemsAndDependencies.Keys.OrderBy(n => n.Name)) { foreach (var e in itemsAndDependencies[n].Where(e => ItemMatch.IsMatch(innerMatch, e.UsingItem) || ItemMatch.IsMatch(innerMatch, e.UsedItem))) { output.WriteLine(e.GetDotRepresentation(maxExampleLength)); } } output.WriteLine("}"); }
public override int Transform([NotNull] GlobalContext globalContext, Ignore configureOptions, [NotNull] TransformOptions transformOptions, [NotNull][ItemNotNull] IEnumerable <Dependency> dependencies, [NotNull] List <Dependency> transformedDependencies) { Dependency[] matchingDependencies = dependencies .Where(d => !transformOptions.Matches.Any() || transformOptions.Matches.Any(m => ItemMatch.IsMatch(m, d.UsingItem)) && transformOptions.Matches.Any(m => ItemMatch.IsMatch(m, d.UsedItem))) .ToArray(); MatrixDictionary <Item, int> aggregatedCounts = MatrixDictionary.CreateCounts(matchingDependencies, d => d.Ct, globalContext.CurrentGraph); // Force each item to exist on both matrix axes foreach (var from in aggregatedCounts.RowKeys) { aggregatedCounts.GetColumnSum(from); } foreach (var to in aggregatedCounts.ColumnKeys) { aggregatedCounts.GetRowSum(to); } // aggregatedCounts is used destructively in both following Mark runs; this is no problem, // because no sink can also be a source in NDepCheck: Nodes without any edges do not // appear; and nodes with only self cycles are either not a source and sink (if ignoreSelfCycles=false), // or they are both a source and a sink and hence are found in the first Mark run. if (transformOptions.MarkSinks) { Mark(aggregatedCounts, ac => ac.RowKeys, i => aggregatedCounts.GetRowSum(i), !transformOptions.ConsiderSelfCyclesInSourcesAndSinks, transformOptions.Recursive, transformOptions.MarkerToAdd); } if (transformOptions.MarkSources) { Mark(aggregatedCounts, ac => ac.ColumnKeys, i => aggregatedCounts.GetColumnSum(i), !transformOptions.ConsiderSelfCyclesInSourcesAndSinks, transformOptions.Recursive, transformOptions.MarkerToAdd); } var remainingNodes = new HashSet <Item>(aggregatedCounts.RowKeys); remainingNodes.UnionWith(aggregatedCounts.ColumnKeys); if (transformOptions.MarkSingleCycleNodes) { foreach (var d in matchingDependencies) { if (Equals(d.UsingItem, d.UsedItem)) { d.UsingItem.IncrementMarker(transformOptions.MarkerToAdd); } } } transformedDependencies.AddRange(dependencies); return(Program.OK_RESULT); }
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); }
protected TUpInfo Traverse([NotNull] TItem root, [NotNull] Dictionary <TItem, TDependency[]> incidentDependencies, Func <TItem, bool, TDownInfo> down) { IBeforeItemGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> initState = _regex.CreateState(); bool atEnd, atCount; IBeforeDependencyGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeDependencyState = initState.Advance(root, (m, i) => ItemMatch.IsMatch(m, i), out atEnd, out atCount); if (beforeDependencyState.CanContinue) { return(Traverse(root, incidentDependencies, beforeDependencyState, down(root, atCount), new HashSet <TPathState> { CreateFirstStateElement(beforeDependencyState, root) })); } else { return(default(TUpInfo)); // ?????????? } }
protected override bool IsItemMatch(ItemMatch itemMatch, Item item) => ItemMatch.IsMatch(itemMatch, item);
protected override bool IsItemMatch(ItemMatch itemMatch, Item item) { return(ItemMatch.IsMatch(itemMatch, item)); }