public void DisconnectedNodes() { var graph = new MutableDirectedGraph(); NodeId a = graph.CreateNode(); NodeId b = graph.CreateNode(); XAssert.IsFalse(graph.IsReachableFrom(a, b)); XAssert.IsFalse(graph.IsReachableFrom(b, a)); }
public void TriviallyConnectedNodes() { var graph = new MutableDirectedGraph(); NodeId a = graph.CreateNode(); NodeId b = graph.CreateNode(); graph.AddEdge(a, b); XAssert.IsTrue(graph.IsReachableFrom(a, b)); XAssert.IsFalse(graph.IsReachableFrom(b, a)); }
public void TopologicalOrderViolationsIgnoredIfRequested() { var graph = new MutableDirectedGraph(); NodeId a = graph.CreateNode(); NodeId b = graph.CreateNode(); NodeId c = graph.CreateNode(); NodeId d = graph.CreateNode(); graph.AddEdge(a, b); graph.AddEdge(d, c); // This edge breaks the topological labelling. XAssert.IsFalse(graph.IsReachableFrom(a, c, skipOutOfOrderNodes: true)); }
/// <summary> /// Creates a test graph. /// There are light edges between nodes 0 - 1, 1 - 2, and 2 - 0. /// There are heavy edges between 0 - 1 and 1 - 3 /// </summary> private static void CreateGraphWithLightEdges(out MutableDirectedGraph graph, out NodeId[] nodes) { graph = new MutableDirectedGraph(); XAssert.AreEqual(graph.NodeCount, 0); XAssert.AreEqual(graph.EdgeCount, 0); // Test creation. nodes = new NodeId[4]; for (int i = 0; i < nodes.Length; ++i) { nodes[i] = graph.CreateNode(); } XAssert.AreEqual(graph.NodeCount, nodes.Length); XAssert.AreEqual(graph.EdgeCount, 0); foreach (NodeId t in nodes) { XAssert.IsTrue(graph.ContainsNode(t)); XAssert.IsTrue(graph.IsSourceNode(t)); XAssert.IsTrue(graph.IsSinkNode(t)); } graph.AddEdge(nodes[0], nodes[1], isLight: true); graph.AddEdge(nodes[1], nodes[2], isLight: true); graph.AddEdge(nodes[2], nodes[0], isLight: true); graph.AddEdge(nodes[0], nodes[1], isLight: false); graph.AddEdge(nodes[1], nodes[3], isLight: false); }
public override void Prepare() { Directory.CreateDirectory(OutputFilePath); m_writer = new StreamWriter(Path.Combine(OutputFilePath, "results.txt")); Console.WriteLine("Creating nodes"); foreach (var node in DataflowGraph.Nodes) { m_mutableGraph.CreateNode(); } Console.WriteLine("Created nodes"); foreach (var entry in PipGraph.AllOutputDirectoriesAndProducers) { var sealId = PipGraph.GetSealedDirectoryNode(entry.Key).ToPipId(); m_dynamicDirectoryProducers[sealId] = entry.Value; } foreach (CopyFile copyFile in PipGraph.RetrievePipsOfType(PipType.CopyFile)) { m_copiedFilesByTarget[copyFile.Destination] = copyFile.Source; } foreach (var directory in PipGraph.AllSealDirectories) { var sealId = PipGraph.GetSealedDirectoryNode(directory).ToPipId(); var sealKind = PipTable.GetSealDirectoryKind(sealId); // Populate map of whether this is a source only seal IsSourceOnlySeal(sealId); if (sealKind == SealDirectoryKind.Full || sealKind == SealDirectoryKind.Partial) { PipId?singleProducer = null; foreach (var file in PipGraph.ListSealedDirectoryContents(directory)) { if (file.IsOutputFile) { var producer = PipGraph.TryGetProducer(file); if (singleProducer == null) { singleProducer = producer; } else if (singleProducer != producer) { singleProducer = PipId.Invalid; } } } if (singleProducer.HasValue && singleProducer.Value.IsValid) { m_dynamicDirectoryProducers[sealId] = singleProducer.Value; } } } }
public void SimpleCycle() { var graph = new MutableDirectedGraph(); NodeId a = graph.CreateNode(); NodeId b = graph.CreateNode(); NodeId c = graph.CreateNode(); NodeId d = graph.CreateNode(); NodeId e = graph.CreateNode(); NodeId f = graph.CreateNode(); graph.AddEdge(a, b); graph.AddEdge(b, c); graph.AddEdge(c, b); // Cycle-forming backedge (violates topo order). graph.AddEdge(d, e); graph.AddEdge(e, f); XAssert.IsTrue(graph.IsReachableFrom(a, b), "Shouldn't visit the backedge"); XAssert.IsTrue(graph.IsReachableFrom(a, c), "Shouldn't visit the backedge"); try { // Note that to fail, we need a > e here due to a fast-path for 'unreachable' // that doesn't look at any edges. graph.IsReachableFrom(a, f); // Fails since it should find the backedge c -> b } catch (BuildXLException) { return; } XAssert.Fail("Expected a failure due to a topological order violation"); }
public void TrivialViolationOfTopologicalOrder() { var graph = new MutableDirectedGraph(); NodeId a = graph.CreateNode(); NodeId b = graph.CreateNode(); NodeId c = graph.CreateNode(); NodeId d = graph.CreateNode(); graph.AddEdge(a, b); graph.AddEdge(d, c); // This edge breaks the topological labelling. try { // Note that to fail, we need c > a here due to a fast-path for 'unreachable' // that doesn't look at any edges. graph.IsReachableFrom(a, c); } catch (BuildXLException) { return; } XAssert.Fail("Expected a failure due to a topological order violation"); }
private static IReadonlyDirectedGraph CreateRandomAcyclicGraph(Random rng, int nodeCount) { var graph = new MutableDirectedGraph(); var nodes = new NodeId[nodeCount]; for (int i = 0; i < nodeCount; i++) { nodes[i] = graph.CreateNode(); } for (int i = 0; i < nodeCount; i++) { int toIndex = i; while ((toIndex = rng.Next(toIndex + 1, nodeCount)) < nodeCount) { graph.AddEdge(nodes[i], nodes[toIndex]); } } return(graph); }
public void MultipleLevels() { var graph = new MutableDirectedGraph(); NodeId l0 = graph.CreateNode(); NodeId l1_n1 = graph.CreateNode(); NodeId l1_n2 = graph.CreateNode(); graph.AddEdge(l0, l1_n1); graph.AddEdge(l0, l1_n2); graph.AddEdge(l1_n1, l1_n2); NodeId l2_n1 = graph.CreateNode(); NodeId l2_n2 = graph.CreateNode(); graph.AddEdge(l1_n1, l2_n1); graph.AddEdge(l1_n2, l2_n2); NodeId l3_n1 = graph.CreateNode(); NodeId l3_n2 = graph.CreateNode(); graph.AddEdge(l2_n1, l3_n1); graph.AddEdge(l2_n2, l3_n2); NodeId l4 = graph.CreateNode(); graph.AddEdge(l3_n1, l4); graph.AddEdge(l3_n2, l4); XAssert.IsTrue(graph.IsReachableFrom(l1_n1, l3_n2)); XAssert.IsTrue(graph.IsReachableFrom(l0, l4)); XAssert.IsFalse(graph.IsReachableFrom(l3_n2, l1_n1)); XAssert.IsFalse(graph.IsReachableFrom(l4, l0)); }
/// <summary> /// Creates a test graph. /// </summary> private static void CreateGraph(out MutableDirectedGraph graph, out NodeId[] nodes) { graph = new MutableDirectedGraph(); XAssert.AreEqual(graph.NodeCount, 0); XAssert.AreEqual(graph.EdgeCount, 0); // Test creation. nodes = new NodeId[12]; for (int i = 0; i < nodes.Length; ++i) { nodes[i] = graph.CreateNode(); } XAssert.AreEqual(graph.NodeCount, nodes.Length); XAssert.AreEqual(graph.EdgeCount, 0); foreach (NodeId t in nodes) { XAssert.IsTrue(graph.ContainsNode(t)); XAssert.IsTrue(graph.IsSourceNode(t)); XAssert.IsTrue(graph.IsSinkNode(t)); } graph.AddEdge(nodes[5], nodes[0]); graph.AddEdge(nodes[5], nodes[1]); graph.AddEdge(nodes[6], nodes[1]); graph.AddEdge(nodes[6], nodes[2]); graph.AddEdge(nodes[7], nodes[5]); graph.AddEdge(nodes[8], nodes[5]); graph.AddEdge(nodes[9], nodes[6]); graph.AddEdge(nodes[9], nodes[3]); graph.AddEdge(nodes[9], nodes[4]); graph.AddEdge(nodes[10], nodes[8]); graph.AddEdge(nodes[11], nodes[8]); graph.AddEdge(nodes[11], nodes[9]); }