private void AddDuplicatesToTree(List <IsIdentifiableRule> allRules) { var root = new TreeNodeWithCount("Identical Rules"); var children = GetDuplicates(allRules).ToArray(); root.Children = children; _treeView.AddObject(root); }
private void EvaluateRuleCoverage() { _treeView.ClearObjects(); var colliding = new TreeNodeWithCount("Colliding Rules"); var ignore = new TreeNodeWithCount("Ignore Rules Used"); var update = new TreeNodeWithCount("Update Rules Used"); var outstanding = new TreeNodeWithCount("Outstanding Failures"); var allRules = Ignorer.Rules.Union(Updater.Rules).ToList(); AddDuplicatesToTree(allRules); _treeView.AddObjects(new [] { colliding, ignore, update, outstanding }); var cts = new CancellationTokenSource(); var btn = new Button("Cancel"); Action cancelFunc = () => { cts.Cancel(); }; Action closeFunc = () => { Application.RequestStop(); }; btn.Clicked += cancelFunc; var dlg = new Dialog("Evaluating", MainWindow.DlgWidth, 6, btn); var stage = new Label("Evaluating Failures") { Width = Dim.Fill(), X = 0, Y = 0 }; var progress = new ProgressBar() { Height = 2, Width = Dim.Fill(), X = 0, Y = 1 }; var textProgress = new Label("0/0") { TextAlignment = TextAlignment.Right, Width = Dim.Fill(), X = 0, Y = 2 }; dlg.Add(stage); dlg.Add(progress); dlg.Add(textProgress); Task.Run(() => { EvaluateRuleCoverageAsync(stage, progress, textProgress, cts.Token, colliding, ignore, update, outstanding); }, cts.Token).ContinueWith((t) => { btn.Clicked -= cancelFunc; btn.Text = "Done"; btn.Clicked += closeFunc; dlg.SetNeedsDisplay(); cts.Dispose(); });; Application.Run(dlg); }
private void EvaluateRuleCoverageAsync(Label stage, ProgressBar progress, Label textProgress, CancellationToken token, TreeNodeWithCount colliding, TreeNodeWithCount ignore, TreeNodeWithCount update, TreeNodeWithCount outstanding) { Dictionary <IsIdentifiableRule, int> rulesUsed = new Dictionary <IsIdentifiableRule, int>(); Dictionary <string, OutstandingFailureNode> outstandingFailures = new Dictionary <string, OutstandingFailureNode>(); int done = 0; var max = CurrentReport.Failures.Count(); foreach (Failure f in CurrentReport.Failures) { done++; token.ThrowIfCancellationRequested(); if (done % 1000 == 0) { SetProgress(progress, textProgress, done, max); } var ignoreRule = Ignorer.Rules.FirstOrDefault(r => r.Apply(f.ProblemField, f.ProblemValue, out _) != RuleAction.None); var updateRule = Updater.Rules.FirstOrDefault(r => r.Apply(f.ProblemField, f.ProblemValue, out _) != RuleAction.None); // record how often each reviewer rule was used with a failure foreach (var r in new [] { ignoreRule, updateRule }) { if (r != null) { if (!rulesUsed.ContainsKey(r)) { rulesUsed.Add(r, 1); } else { rulesUsed[r]++; } } } // There are 2 conflicting rules for this input value (it should be updated and ignored!) if (ignoreRule != null && updateRule != null) { // find an existing collision audit node for this input value var existing = colliding.Children.OfType <CollidingRulesNode>().FirstOrDefault(c => c.CollideOn[0].ProblemValue.Equals(f.ProblemValue)); if (existing != null) { existing.Add(f); } else { colliding.Children.Add(new CollidingRulesNode(ignoreRule, updateRule, f)); } } // input value that doesn't match any system rules yet if (ignoreRule == null && updateRule == null) { if (!outstandingFailures.ContainsKey(f.ProblemValue)) { outstandingFailures.Add(f.ProblemValue, new OutstandingFailureNode(f, 1)); } else { outstandingFailures[f.ProblemValue].NumberOfTimesReported++; } } } SetProgress(progress, textProgress, done, max); var ignoreRulesUsed = rulesUsed.Where(r => r.Key.Action == RuleAction.Ignore).ToList(); stage.Text = "Evaluating Ignore Rules Used"; max = ignoreRulesUsed.Count(); done = 0; foreach (var used in ignoreRulesUsed.OrderByDescending(kvp => kvp.Value)) { done++; token.ThrowIfCancellationRequested(); if (done % 1000 == 0) { SetProgress(progress, textProgress, done, max); } ignore.Children.Add(new RuleUsageNode(Ignorer, used.Key, used.Value)); } SetProgress(progress, textProgress, done, max); stage.Text = "Evaluating Update Rules Used"; var updateRulesUsed = rulesUsed.Where(r => r.Key.Action == RuleAction.Report).ToList(); max = updateRulesUsed.Count(); done = 0; foreach (var used in updateRulesUsed.OrderByDescending(kvp => kvp.Value)) { done++; token.ThrowIfCancellationRequested(); if (done % 1000 == 0) { SetProgress(progress, textProgress, done, max); } update.Children.Add(new RuleUsageNode(Updater, used.Key, used.Value)); } SetProgress(progress, textProgress, done, max); stage.Text = "Evaluating Outstanding Failures"; outstanding.Children = outstandingFailures.Select(f => f.Value).GroupBy(f => f.Failure.ProblemField) .Select(g => new FailureGroupingNode(g.Key, g.ToArray())) .OrderByDescending(v => v.Failures.Sum(f => f.NumberOfTimesReported)) .Cast <ITreeNode>() .ToList(); }