mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 12:09:16 +00:00
Use a map to look up layer index child nodes
LayersIndex.Node kept its children in a list and scanned that list linearly to find the child for each path segment. Building the index is therefore O(entries x siblings), a cost that is dominated by the largest flat directory in the jar: BOOT-INF/lib/ for the dependencies, and any bundled resource directory such as a front-end build output. Keep the children in a LinkedHashMap keyed by the segment name so that lookups are constant time. Insertion order is preserved, so the order in which buildIndex() walks the tree is unchanged. For a jar with 32,529 entries, 426 dependencies and a 12,000 file static resource directory, this reduces the number of string comparisons from 73.7M to 222K and the time spent building the index from 197ms to 12ms. For a jar with no large flat directory (20,529 entries, 426 dependencies) the gain is much smaller: 1.58M comparisons to 162K, and 12.5ms to 9.6ms. The generated layers.idx is byte for byte identical in both cases. See gh-51654 Signed-off-by: Junggi Kim <kimjg2477@gmail.com>
This commit is contained in:
committed by
Stéphane Nicoll
parent
c966eca3e7
commit
823744c0b2
+10
-15
@@ -21,11 +21,12 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
@@ -47,6 +48,7 @@ import org.springframework.util.MultiValueMap;
|
||||
* @author Madhura Bhave
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @author Junggi Kim
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class LayersIndex {
|
||||
@@ -116,28 +118,21 @@ public class LayersIndex {
|
||||
|
||||
private final Set<Layer> layers;
|
||||
|
||||
private final List<Node> children = new ArrayList<>();
|
||||
private final Map<String, Node> children = new LinkedHashMap<>();
|
||||
|
||||
Node() {
|
||||
this.name = "";
|
||||
this.layers = new HashSet<>();
|
||||
this("");
|
||||
}
|
||||
|
||||
Node(String name, Layer layer) {
|
||||
Node(String name) {
|
||||
this.name = name;
|
||||
this.layers = new HashSet<>(Collections.singleton(layer));
|
||||
this.layers = new HashSet<>();
|
||||
}
|
||||
|
||||
Node updateOrAddNode(String segment, boolean isDirectory, Layer layer) {
|
||||
String name = segment + (isDirectory ? "/" : "");
|
||||
for (Node child : this.children) {
|
||||
if (name.equals(child.name)) {
|
||||
child.layers.add(layer);
|
||||
return child;
|
||||
}
|
||||
}
|
||||
Node child = new Node(name, layer);
|
||||
this.children.add(child);
|
||||
Node child = this.children.computeIfAbsent(name, Node::new);
|
||||
child.layers.add(layer);
|
||||
return child;
|
||||
}
|
||||
|
||||
@@ -147,7 +142,7 @@ public class LayersIndex {
|
||||
index.add(this.layers.iterator().next(), name);
|
||||
}
|
||||
else {
|
||||
for (Node child : this.children) {
|
||||
for (Node child : this.children.values()) {
|
||||
child.buildIndex(name, index);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user