| // Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.android.tools.r8.shaking; |
| |
| import com.android.tools.r8.experimental.graphinfo.GraphConsumer; |
| import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo; |
| import com.android.tools.r8.experimental.graphinfo.GraphNode; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** Base implementation of a graph consumer that collects all of graph nodes and edges. */ |
| public class CollectingGraphConsumer implements GraphConsumer { |
| |
| // Possible sub-consumer that is also inspecting the kept-graph. |
| private final GraphConsumer subConsumer; |
| |
| // Directional map backwards from targets to direct sources. |
| private final Map<GraphNode, Map<GraphNode, Set<GraphEdgeInfo>>> target2sources = new HashMap<>(); |
| |
| public CollectingGraphConsumer(GraphConsumer subConsumer) { |
| this.subConsumer = subConsumer; |
| } |
| |
| @Override |
| public void acceptEdge(GraphNode source, GraphNode target, GraphEdgeInfo info) { |
| target2sources |
| .computeIfAbsent(target, k -> new HashMap<>()) |
| .computeIfAbsent(source, k -> new HashSet<>()) |
| .add(info); |
| if (subConsumer != null) { |
| subConsumer.acceptEdge(source, target, info); |
| } |
| } |
| |
| public Set<GraphNode> getTargets() { |
| return target2sources.keySet(); |
| } |
| |
| public Map<GraphNode, Set<GraphEdgeInfo>> getSourcesTargeting(GraphNode target) { |
| return target2sources.get(target); |
| } |
| } |