namespace TeamCity.Docker { using System; using System.Collections.Generic; using System.Linq; using Generic; using Model; // ReSharper disable once ClassNeverInstantiated.Global internal class BuildGraphsFactory : IFactory>, IGraph> { public Result>> Create(IGraph graph) { if (graph == null) throw new ArgumentNullException(nameof(graph)); return new Result>>(CreateInternal(graph)); } private IEnumerable> CreateInternal(IGraph graph) { if (graph == null) throw new ArgumentNullException(nameof(graph)); var buildGraph = graph.Copy(i => i.Value is Image || i.Value is Reference); var cutNodes = new HashSet>(); while (true) { var bestCut = new HashSet>(buildGraph.FindMinimumCutByStoerWagner(links => links.Select(i => i.From.Value.Weight.Value).Concat(Enumerable.Repeat(0, 1)).Sum(), out var bestCost)); if (bestCost > 0) { yield return buildGraph.Copy(node => node.Value is Image || node.Value is Reference); break; } if (bestCut.Count > buildGraph.NodesCount >> 1) { bestCut = new HashSet>(graph.Nodes.Except(bestCut)); } cutNodes.UnionWith(bestCut); yield return buildGraph.Copy(node => (node.Value is Image || node.Value is Reference) && bestCut.Contains(node)); buildGraph = buildGraph.Copy(node => !cutNodes.Contains(node)); } } } }