mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8200134: Improve ModuleHashesBuilder
Reviewed-by: mchung, alanb
This commit is contained in:
parent
2137690f0a
commit
5c5918d073
1 changed files with 33 additions and 45 deletions
|
@ -35,7 +35,6 @@ import java.util.Collections;
|
|||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -76,16 +75,15 @@ public class ModuleHashesBuilder {
|
|||
// build a graph containing the packaged modules and
|
||||
// its transitive dependences matching --hash-modules
|
||||
Graph.Builder<String> builder = new Graph.Builder<>();
|
||||
Deque<ResolvedModule> deque = new ArrayDeque<>(configuration.modules());
|
||||
Deque<ResolvedModule> todo = new ArrayDeque<>(configuration.modules());
|
||||
Set<ResolvedModule> visited = new HashSet<>();
|
||||
while (!deque.isEmpty()) {
|
||||
ResolvedModule rm = deque.pop();
|
||||
if (!visited.contains(rm)) {
|
||||
visited.add(rm);
|
||||
ResolvedModule rm;
|
||||
while ((rm = todo.poll()) != null) {
|
||||
if (visited.add(rm)) {
|
||||
builder.addNode(rm.name());
|
||||
for (ResolvedModule dm : rm.reads()) {
|
||||
if (!visited.contains(dm)) {
|
||||
deque.push(dm);
|
||||
todo.push(dm);
|
||||
}
|
||||
builder.addEdge(rm.name(), dm.name());
|
||||
}
|
||||
|
@ -212,17 +210,14 @@ public class ModuleHashesBuilder {
|
|||
* Returns all nodes reachable from the given set of roots.
|
||||
*/
|
||||
public Set<T> dfs(Set<T> roots) {
|
||||
Deque<T> deque = new LinkedList<>(roots);
|
||||
ArrayDeque<T> todo = new ArrayDeque<>(roots);
|
||||
Set<T> visited = new HashSet<>();
|
||||
while (!deque.isEmpty()) {
|
||||
T u = deque.pop();
|
||||
if (!visited.contains(u)) {
|
||||
visited.add(u);
|
||||
if (contains(u)) {
|
||||
T u;
|
||||
while ((u = todo.poll()) != null) {
|
||||
if (visited.add(u) && contains(u)) {
|
||||
adjacentNodes(u).stream()
|
||||
.filter(v -> !visited.contains(v))
|
||||
.forEach(deque::push);
|
||||
}
|
||||
.forEach(todo::push);
|
||||
}
|
||||
}
|
||||
return visited;
|
||||
|
@ -240,12 +235,10 @@ public class ModuleHashesBuilder {
|
|||
final Map<T, Set<T>> edges = new HashMap<>();
|
||||
|
||||
public void addNode(T node) {
|
||||
if (nodes.contains(node)) {
|
||||
return;
|
||||
}
|
||||
nodes.add(node);
|
||||
if (nodes.add(node)) {
|
||||
edges.computeIfAbsent(node, _e -> new HashSet<>());
|
||||
}
|
||||
}
|
||||
|
||||
public void addEdge(T u, T v) {
|
||||
addNode(u);
|
||||
|
@ -263,18 +256,16 @@ public class ModuleHashesBuilder {
|
|||
* Topological sort
|
||||
*/
|
||||
private static class TopoSorter<T> {
|
||||
final Deque<T> result = new LinkedList<>();
|
||||
final Deque<T> nodes;
|
||||
final Deque<T> result = new ArrayDeque<>();
|
||||
final Graph<T> graph;
|
||||
|
||||
TopoSorter(Graph<T> graph) {
|
||||
this.graph = graph;
|
||||
this.nodes = new LinkedList<>(graph.nodes);
|
||||
sort();
|
||||
}
|
||||
|
||||
public void ordered(Consumer<T> action) {
|
||||
result.iterator().forEachRemaining(action);
|
||||
result.forEach(action);
|
||||
}
|
||||
|
||||
public void reverse(Consumer<T> action) {
|
||||
|
@ -282,29 +273,26 @@ public class ModuleHashesBuilder {
|
|||
}
|
||||
|
||||
private void sort() {
|
||||
Deque<T> visited = new LinkedList<>();
|
||||
Deque<T> done = new LinkedList<>();
|
||||
T node;
|
||||
while ((node = nodes.poll()) != null) {
|
||||
if (!visited.contains(node)) {
|
||||
visit(node, visited, done);
|
||||
}
|
||||
}
|
||||
Set<T> visited = new HashSet<>();
|
||||
Deque<T> stack = new ArrayDeque<>();
|
||||
graph.nodes.forEach(node -> visit(node, visited, stack));
|
||||
}
|
||||
|
||||
private void visit(T node, Deque<T> visited, Deque<T> done) {
|
||||
if (visited.contains(node)) {
|
||||
if (!done.contains(node)) {
|
||||
throw new IllegalArgumentException("Cyclic detected: " +
|
||||
node + " " + graph.edges().get(node));
|
||||
private Set<T> children(T node) {
|
||||
return graph.edges().get(node);
|
||||
}
|
||||
return;
|
||||
}
|
||||
visited.add(node);
|
||||
graph.edges().get(node)
|
||||
.forEach(x -> visit(x, visited, done));
|
||||
done.add(node);
|
||||
|
||||
private void visit(T node, Set<T> visited, Deque<T> stack) {
|
||||
if (visited.add(node)) {
|
||||
stack.push(node);
|
||||
children(node).forEach(child -> visit(child, visited, stack));
|
||||
stack.pop();
|
||||
result.addLast(node);
|
||||
}
|
||||
else if (stack.contains(node)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cycle detected: " + node + " -> " + children(node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue