Exemplo n.º 1
0
        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);
                    }
                }
            }
        }
Exemplo n.º 2
0
        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);
        }