All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gradle.internal.graph.GraphAggregator Maven / Gradle / Ivy

There is a newer version: 8.11.1
Show newest version
/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gradle.internal.graph;

import java.util.*;

/**
 * Groups the nodes of a graph based on their reachability from a set of starting nodes.
 */
public class GraphAggregator {
    private final CachingDirectedGraphWalker graphWalker;

    public GraphAggregator(DirectedGraph graph) {
        graphWalker = new CachingDirectedGraphWalker(new ConnectedNodesAsValuesDirectedGraph(graph));
    }

    public Result group(Collection startNodes, Collection allNodes) {
        Map> reachableByNode = new HashMap>();
        Set topLevelNodes = new LinkedHashSet(allNodes);
        for (N node : allNodes) {
            Set reachableNodes = graphWalker.add(node).findValues();
            reachableByNode.put(node, reachableNodes);
            topLevelNodes.removeAll(reachableNodes);
        }
        topLevelNodes.addAll(startNodes);
        Map> nodes = new HashMap>();
        for (N node : topLevelNodes) {
            nodes.put(node, calculateReachableNodes(reachableByNode, node, topLevelNodes));
        }
        return new Result(nodes, topLevelNodes);
    }

    private Set calculateReachableNodes(Map> nodes, N node, Set topLevelNodes) {
        Set reachableNodes = nodes.get(node);
        reachableNodes.add(node);
        Set reachableStartNodes = new LinkedHashSet(topLevelNodes);
        reachableStartNodes.retainAll(reachableNodes);
        reachableStartNodes.remove(node);
        for (N startNode : reachableStartNodes) {
            reachableNodes.removeAll(calculateReachableNodes(nodes, startNode, topLevelNodes));
        }
        return reachableNodes;
    }

    public static class Result {
        private final Map> nodes;
        private final Set topLevelNodes;

        public Result(Map> nodes, Set topLevelNodes) {
            this.nodes = nodes;
            this.topLevelNodes = topLevelNodes;
        }

        public Set getNodes(N startNode) {
            return nodes.get(startNode);
        }

        public Set getTopLevelNodes() {
            return topLevelNodes;
        }
    }

    private static class ConnectedNodesAsValuesDirectedGraph implements DirectedGraph {
        private final DirectedGraph graph;

        private ConnectedNodesAsValuesDirectedGraph(DirectedGraph graph) {
            this.graph = graph;
        }

        public void getNodeValues(N node, Collection values, Collection connectedNodes) {
            Set edges = new LinkedHashSet();
            graph.getNodeValues(node, new ArrayList(), edges);
            values.addAll(edges);
            connectedNodes.addAll(edges);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy