private static void AddIncidentNodes( IReadonlyDirectedGraph graph, RangedNodeSet walkFromNodes, Func <IReadonlyDirectedGraph, NodeId, IEnumerable <Edge> > getEdges, Func <NodeId, NodeId, bool> validateEdgeTopoProperty, NodeRange incidentNodeFilter, bool skipOutOfOrderNodes, RangedNodeSet addTo) { Contract.Requires(!incidentNodeFilter.IsEmpty); foreach (NodeId existingNode in walkFromNodes) { IEnumerable <Edge> edges = getEdges(graph, existingNode); foreach (Edge edge in edges) { NodeId other = edge.OtherNode; if (skipOutOfOrderNodes && !validateEdgeTopoProperty(existingNode, other)) { continue; } if (incidentNodeFilter.Contains(other)) { addTo.Add(edge.OtherNode); } } } }
private static bool RangeIncidentNodesAndIntersect( IReadonlyDirectedGraph graph, RangedNodeSet walkFromNodes, Func <IReadonlyDirectedGraph, NodeId, IEnumerable <Edge> > getEdges, Func <NodeId, NodeId, bool> validateEdgeTopoProperty, NodeRange incidentNodeFilter, RangedNodeSet intersectWith, bool skipOutOfOrderNodes, out NodeRange range, out NodeId intersection) { // Note that initially, currentMin > currentMax so NodeRange.CreatePossiblyEmpty // would return an empty range. We return an empty range iff no nodes pass incidentNodeFilter below. uint currentMin = NodeId.MaxValue; uint currentMax = NodeId.MinValue; foreach (NodeId existingNode in walkFromNodes) { IEnumerable <Edge> edges = getEdges(graph, existingNode); foreach (Edge edge in edges) { NodeId other = edge.OtherNode; if (!validateEdgeTopoProperty(existingNode, other)) { if (skipOutOfOrderNodes) { continue; } throw new BuildXLException(I($"Topological order violated due to an edge between nodes {existingNode} and {other}")); } if (!incidentNodeFilter.Contains(other)) { continue; } if (other.Value > currentMax) { currentMax = edge.OtherNode.Value; Contract.AssertDebug(currentMax <= NodeId.MaxValue && currentMax >= NodeId.MinValue); } if (other.Value < currentMin) { currentMin = edge.OtherNode.Value; Contract.AssertDebug(currentMin <= NodeId.MaxValue && currentMin >= NodeId.MinValue); } if (intersectWith.Contains(other)) { intersection = other; Contract.AssertDebug(currentMin <= NodeId.MaxValue && currentMin >= NodeId.MinValue); Contract.AssertDebug(currentMax <= NodeId.MaxValue && currentMax >= NodeId.MinValue); range = NodeRange.CreatePossiblyEmpty(new NodeId(currentMin), new NodeId(currentMax)); return(true); } } } intersection = NodeId.Invalid; Contract.AssertDebug(currentMin <= NodeId.MaxValue && currentMin >= NodeId.MinValue); Contract.AssertDebug(currentMax <= NodeId.MaxValue && currentMax >= NodeId.MinValue); range = NodeRange.CreatePossiblyEmpty(new NodeId(currentMin), new NodeId(currentMax)); return(false); }