projects/guix·blob python-team · refs

125 lines · 4.9 KiB

1Backport from openjdk 10
2
3--- orig/jdk-3cc80be736f2/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleSorter.java 1970-01-01 01:00:01.000000000 +0100
4+++ jdk-3cc80be736f2/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleSorter.java 2022-04-12 20:48:04.474353305 +0200
5@@ -1,5 +1,5 @@
6 /*
7- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
8+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12@@ -30,13 +30,16 @@
13 import jdk.tools.jlink.plugin.ResourcePoolModuleView;
14
15 import java.lang.module.ModuleDescriptor;
16+import java.lang.module.ModuleDescriptor.Requires;
17 import java.lang.module.ModuleDescriptor.Requires.Modifier;
18
19 import java.nio.ByteBuffer;
20-import java.util.Deque;
21+import java.util.ArrayList;
22+import java.util.Comparator;
23 import java.util.HashMap;
24 import java.util.HashSet;
25-import java.util.LinkedList;
26+import java.util.LinkedHashSet;
27+import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.stream.Stream;
31@@ -45,9 +48,8 @@
32 * Helper class to sort modules in topological order
33 */
34 public final class ModuleSorter {
35- private final Deque<ResourcePoolModule> nodes = new LinkedList<>();
36- private final Map<String, Set<ResourcePoolModule>> edges = new HashMap<>();
37- private final Deque<ResourcePoolModule> result = new LinkedList<>();
38+ private final Map<ResourcePoolModule, Set<ResourcePoolModule>> graph = new HashMap<>();
39+ private final List<ResourcePoolModule> result = new ArrayList<>();
40
41 private final ResourcePoolModuleView moduleView;
42
43@@ -69,11 +71,17 @@
44
45 private ModuleSorter addModule(ResourcePoolModule module) {
46 addNode(module);
47- readModuleDescriptor(module).requires().forEach(req -> {
48+ // the module graph will be traversed in a stable order for
49+ // the topological sort. So add the dependences in the module name order
50+ readModuleDescriptor(module).requires()
51+ .stream()
52+ .sorted(Comparator.comparing(Requires::name))
53+ .forEach(req ->
54+ {
55 ResourcePoolModule dep = moduleView.findModule(req.name()).orElse(null);
56 if (dep != null) {
57 addNode(dep);
58- edges.get(module.name()).add(dep);
59+ graph.get(module).add(dep);
60 } else if (!req.modifiers().contains(Modifier.STATIC)) {
61 throw new PluginException(req.name() + " not found");
62 }
63@@ -82,22 +90,23 @@
64 }
65
66 private void addNode(ResourcePoolModule module) {
67- nodes.add(module);
68- edges.computeIfAbsent(module.name(), _n -> new HashSet<>());
69+ graph.computeIfAbsent(module, _n -> new LinkedHashSet<>());
70 }
71
72+ /*
73+ * The module graph will be traversed in a stable order
74+ * (traversing the modules and their dependences in alphabetical order)
75+ * so that it will produce the same result of a given module graph.
76+ */
77 private synchronized void build() {
78- if (!result.isEmpty() || nodes.isEmpty())
79+ if (!result.isEmpty() || graph.isEmpty())
80 return;
81
82- Deque<ResourcePoolModule> visited = new LinkedList<>();
83- Deque<ResourcePoolModule> done = new LinkedList<>();
84- ResourcePoolModule node;
85- while ((node = nodes.poll()) != null) {
86- if (!visited.contains(node)) {
87- visit(node, visited, done);
88- }
89- }
90+ Set<ResourcePoolModule> visited = new HashSet<>();
91+ Set<ResourcePoolModule> done = new HashSet<>();
92+ graph.keySet().stream()
93+ .sorted(Comparator.comparing(ResourcePoolModule::name))
94+ .forEach(node -> visit(node, visited, done));
95 }
96
97 public Stream<ResourcePoolModule> sorted() {
98@@ -106,19 +115,21 @@
99 }
100
101 private void visit(ResourcePoolModule node,
102- Deque<ResourcePoolModule> visited,
103- Deque<ResourcePoolModule> done) {
104+ Set<ResourcePoolModule> visited,
105+ Set<ResourcePoolModule> done) {
106 if (visited.contains(node)) {
107 if (!done.contains(node)) {
108 throw new IllegalArgumentException("Cyclic detected: " +
109- node + " " + edges.get(node.name()));
110+ node + " " + graph.get(node));
111 }
112 return;
113 }
114+
115+ // traverse the dependences of the given module which are
116+ // also sorted in alphabetical order
117 visited.add(node);
118- edges.get(node.name())
119- .forEach(x -> visit(x, visited, done));
120+ graph.get(node).forEach(x -> visit(x, visited, done));
121 done.add(node);
122- result.addLast(node);
123+ result.add(node);
124 }
125 }